Index: head/sys/arm/arm/elf_trampoline.c =================================================================== --- head/sys/arm/arm/elf_trampoline.c (revision 159556) +++ head/sys/arm/arm/elf_trampoline.c (revision 159557) @@ -1,442 +1,563 @@ /*- * Copyright (c) 2005 Olivier Houchard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include +#include #include #include "opt_global.h" #include "opt_kernname.h" extern char kernel_start[]; extern char kernel_end[]; +extern void *_end; + void __start(void); #define GZ_HEAD 0xa #ifdef CPU_ARM7TDMI #define cpu_idcache_wbinv_all arm7tdmi_cache_flushID #elif defined(CPU_ARM8) #define cpu_idcache_wbinv_all arm8_cache_purgeID #elif defined(CPU_ARM9) -#define cpu_idcache_wbinv_all arm9_dcache_wbinv_all +#define cpu_idcache_wbinv_all arm9_idcache_wbinv_all #elif defined(CPU_ARM10) #define cpu_idcache_wbinv_all arm10_idcache_wbinv_all #elif defined(CPU_SA110) || defined(CPU_SA1110) || defined(CPU_SA1100) || \ defined(CPU_IXP12X0) #define cpu_idcache_wbinv_all sa1_cache_purgeID #elif defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \ defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) #define cpu_idcache_wbinv_all xscale_cache_purgeID #endif -int arm_pdcache_line_size = 32; + +#ifdef KZIP +int arm_picache_size; +int arm_picache_line_size; +int arm_picache_ways; + +int arm_pdcache_size; /* and unified */ +int arm_pdcache_line_size = 32; +int arm_pdcache_ways; + +int arm_pcache_type; +int arm_pcache_unified; + +int arm_dcache_align; +int arm_dcache_align_mask; + +/* Additional cache information local to this file. Log2 of some of the + above numbers. */ +static int arm_dcache_l2_nsets; +static int arm_dcache_l2_assoc; +static int arm_dcache_l2_linesize; + + int block_userspace_access = 0; +extern int arm9_dcache_sets_inc; +extern int arm9_dcache_sets_max; +extern int arm9_dcache_index_max; +extern int arm9_dcache_index_inc; +#endif static __inline void * memcpy(void *dst, const void *src, int len) { const char *s = src; char *d = dst; while (len) { if (0 && len >= 4 && !((vm_offset_t)d & 3) && !((vm_offset_t)s & 3)) { *(uint32_t *)d = *(uint32_t *)s; s += 4; d += 4; len -= 4; } else { *d++ = *s++; len--; } } return (dst); } static __inline void bzero(void *addr, int count) { char *tmp = (char *)addr; while (count > 0) { if (count >= 4 && !((vm_offset_t)tmp & 3)) { *(uint32_t *)tmp = 0; tmp += 4; count -= 4; } else { *tmp = 0; tmp++; count--; } } } void _start(void) { int physaddr = KERNPHYSADDR; int tmp1; + unsigned int sp = (unsigned int)&_end; +#ifdef KZIP + sp += KERNSIZE + 0x100; + sp &= ~(L1_TABLE_SIZE - 1); + sp += 2 * L1_TABLE_SIZE; +#endif + sp += 1024 * 1024; /* Should be enough for a stack */ __asm __volatile("adr %0, 2f\n" "bic %0, %0, #0xff000000\n" - "bic sp, sp, #0xff000000\n" "and %1, %1, #0xff000000\n" "orr %0, %0, %1\n" - "orr sp, sp, %1\n" "mrc p15, 0, %1, c1, c0, 0\n" "bic %1, %1, #1\n" /* Disable MMU */ "orr %1, %1, #(4 | 8)\n" /* Add DC enable, WBUF enable */ "orr %1, %1, #0x1000\n" /* Add IC enable */ "orr %1, %1, #(0x800)\n" /* BPRD enable */ "mcr p15, 0, %1, c1, c0, 0\n" "nop\n" "nop\n" "nop\n" "mov pc, %0\n" "2: nop\n" - : "=r" (tmp1), "+r" (physaddr)); + "mov sp, %2\n" + : "=r" (tmp1), "+r" (physaddr), "+r" (sp)); __start(); } #ifdef KZIP +static void +get_cachetype_cp15() +{ + u_int ctype, isize, dsize; + u_int multiplier; + + __asm __volatile("mrc p15, 0, %0, c0, c0, 1" + : "=r" (ctype)); + + /* + * ...and thus spake the ARM ARM: + * + * If an value corresponding to an unimplemented or + * reserved ID register is encountered, the System Control + * processor returns the value of the main ID register. + */ + if (ctype == cpufunc_id()) + goto out; + + if ((ctype & CPU_CT_S) == 0) + arm_pcache_unified = 1; + + /* + * If you want to know how this code works, go read the ARM ARM. + */ + + arm_pcache_type = CPU_CT_CTYPE(ctype); + if (arm_pcache_unified == 0) { + isize = CPU_CT_ISIZE(ctype); + multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2; + arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3); + if (CPU_CT_xSIZE_ASSOC(isize) == 0) { + if (isize & CPU_CT_xSIZE_M) + arm_picache_line_size = 0; /* not present */ + else + arm_picache_ways = 1; + } else { + arm_picache_ways = multiplier << + (CPU_CT_xSIZE_ASSOC(isize) - 1); + } + arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8); + } + + dsize = CPU_CT_DSIZE(ctype); + multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2; + arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3); + if (CPU_CT_xSIZE_ASSOC(dsize) == 0) { + if (dsize & CPU_CT_xSIZE_M) + arm_pdcache_line_size = 0; /* not present */ + else + arm_pdcache_ways = 1; + } else { + arm_pdcache_ways = multiplier << + (CPU_CT_xSIZE_ASSOC(dsize) - 1); + } + arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8); + + arm_dcache_align = arm_pdcache_line_size; + + arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2; + arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3; + arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) - + CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize); + out: + arm_dcache_align_mask = arm_dcache_align - 1; +} + +static void +arm9_setup(void) +{ + + get_cachetype_cp15(); + arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize; + arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize + + arm_dcache_l2_nsets)) - arm9_dcache_sets_inc; + arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc); + arm9_dcache_index_max = 0U - arm9_dcache_index_inc; +} + + static unsigned char *orig_input, *i_input, *i_output; static u_int memcnt; /* Memory allocated: blocks */ static size_t memtot; /* Memory allocated: bytes */ /* * Library functions required by inflate(). */ #define MEMSIZ 0x8000 /* * Allocate memory block. */ unsigned char * kzipmalloc(int size) { void *ptr; static u_char mem[MEMSIZ]; if (memtot + size > MEMSIZ) return NULL; ptr = mem + memtot; memtot += size; memcnt++; return ptr; } /* * Free allocated memory block. */ void kzipfree(void *ptr) { memcnt--; if (!memcnt) memtot = 0; } void putstr(char *dummy) { } static int input(void *dummy) { if ((size_t)(i_input - orig_input) >= KERNCOMPSIZE) { return (GZ_EOF); } return *i_input++; } static int output(void *dummy, unsigned char *ptr, unsigned long len) { memcpy(i_output, ptr, len); i_output += len; return (0); } static void * inflate_kernel(void *kernel, void *startaddr) { struct inflate infl; char slide[GZ_WSIZE]; orig_input = kernel; memcnt = memtot = 0; i_input = (char *)kernel + GZ_HEAD; if (((char *)kernel)[3] & 0x18) { while (*i_input) i_input++; i_input++; } i_output = startaddr; bzero(&infl, sizeof(infl)); infl.gz_input = input; infl.gz_output = output; infl.gz_slide = slide; inflate(&infl); return ((char *)(((vm_offset_t)i_output & ~3) + 4)); } #endif void * load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end, int d) { Elf32_Ehdr *eh; Elf32_Phdr phdr[512] /* XXX */, *php; Elf32_Shdr shdr[512] /* XXX */; int i,j; void *entry_point; int symtabindex = -1; int symstrindex = -1; vm_offset_t lastaddr = 0; Elf_Addr ssym = 0, esym = 0; Elf_Dyn *dp; eh = (Elf32_Ehdr *)kstart; ssym = esym = 0; entry_point = (void*)eh->e_entry; memcpy(phdr, (void *)(kstart + eh->e_phoff ), eh->e_phnum * sizeof(phdr[0])); /* Determine lastaddr. */ for (i = 0; i < eh->e_phnum; i++) { if (lastaddr < (phdr[i].p_vaddr - KERNVIRTADDR + curaddr + phdr[i].p_memsz)) lastaddr = phdr[i].p_vaddr - KERNVIRTADDR + curaddr + phdr[i].p_memsz; } /* Save the symbol tables, as there're about to be scratched. */ memcpy(shdr, (void *)(kstart + eh->e_shoff), sizeof(*shdr) * eh->e_shnum); if (eh->e_shnum * eh->e_shentsize != 0 && eh->e_shoff != 0) { for (i = 0; i < eh->e_shnum; i++) { if (shdr[i].sh_type == SHT_SYMTAB) { for (j = 0; j < eh->e_phnum; j++) { if (phdr[j].p_type == PT_LOAD && shdr[i].sh_offset >= phdr[j].p_offset && (shdr[i].sh_offset + shdr[i].sh_size <= phdr[j].p_offset + phdr[j].p_filesz)) { shdr[i].sh_offset = 0; shdr[i].sh_size = 0; j = eh->e_phnum; } } if (shdr[i].sh_offset != 0 && shdr[i].sh_size != 0) { symtabindex = i; symstrindex = shdr[i].sh_link; } } } func_end = roundup(func_end, sizeof(long)); if (symtabindex >= 0 && symstrindex >= 0) { ssym = lastaddr; if (d) { memcpy((void *)func_end, (void *)( shdr[symtabindex].sh_offset + kstart), shdr[symtabindex].sh_size); memcpy((void *)(func_end + shdr[symtabindex].sh_size), (void *)(shdr[symstrindex].sh_offset + kstart), shdr[symstrindex].sh_size); } else { lastaddr += shdr[symtabindex].sh_size; lastaddr = roundup(lastaddr, sizeof(shdr[symtabindex].sh_size)); lastaddr += sizeof(shdr[symstrindex].sh_size); lastaddr += shdr[symstrindex].sh_size; lastaddr = roundup(lastaddr, sizeof(shdr[symstrindex].sh_size)); } } } if (!d) return ((void *)lastaddr); j = eh->e_phnum; for (i = 0; i < j; i++) { volatile char c; if (phdr[i].p_type != PT_LOAD) continue; memcpy((void *)(phdr[i].p_vaddr - KERNVIRTADDR + curaddr), (void*)(kstart + phdr[i].p_offset), phdr[i].p_filesz); /* Clean space from oversized segments, eg: bss. */ if (phdr[i].p_filesz < phdr[i].p_memsz) bzero((void *)(phdr[i].p_vaddr - KERNVIRTADDR + curaddr + phdr[i].p_filesz), phdr[i].p_memsz - phdr[i].p_filesz); } /* Now grab the symbol tables. */ if (symtabindex >= 0 && symstrindex >= 0) { *(Elf_Size *)lastaddr = shdr[symtabindex].sh_size; lastaddr += sizeof(shdr[symtabindex].sh_size); memcpy((void*)lastaddr, (void *)func_end, shdr[symtabindex].sh_size); lastaddr += shdr[symtabindex].sh_size; lastaddr = roundup(lastaddr, sizeof(shdr[symtabindex].sh_size)); *(Elf_Size *)lastaddr = shdr[symstrindex].sh_size; lastaddr += sizeof(shdr[symstrindex].sh_size); memcpy((void*)lastaddr, (void*)(func_end + shdr[symtabindex].sh_size), shdr[symstrindex].sh_size); lastaddr += shdr[symstrindex].sh_size; lastaddr = roundup(lastaddr, sizeof(shdr[symstrindex].sh_size)); *(Elf_Addr *)curaddr = MAGIC_TRAMP_NUMBER; *((Elf_Addr *)curaddr + 1) = ssym - curaddr + KERNVIRTADDR; *((Elf_Addr *)curaddr + 2) = lastaddr - curaddr + KERNVIRTADDR; } else *(Elf_Addr *)curaddr = 0; /* Invalidate the instruction cache. */ __asm __volatile("mcr p15, 0, %0, c7, c5, 0\n" "mcr p15, 0, %0, c7, c10, 4\n" : : "r" (curaddr)); /* Jump to the entry point. */ ((void(*)(void))(entry_point - KERNVIRTADDR + curaddr))(); __asm __volatile(".globl func_end\n" "func_end:"); } extern char func_end[]; -extern void *_end; #define PMAP_DOMAIN_KERNEL 15 /* * Just define it instead of including the * whole VM headers set. */ int __hack; static __inline void setup_pagetables(unsigned int pt_addr, vm_paddr_t physstart, vm_paddr_t physend) { unsigned int *pd = (unsigned int *)pt_addr; vm_paddr_t addr; int domain = (DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT; int tmp; bzero(pd, L1_TABLE_SIZE); for (addr = physstart; addr < physend; addr += L1_S_SIZE) pd[addr >> L1_S_SHIFT] = L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)| L1_S_DOM(PMAP_DOMAIN_KERNEL) | addr; /* XXX: See below */ if (0xfff00000 < physstart || 0xfff00000 > physend) pd[0xfff00000 >> L1_S_SHIFT] = L1_TYPE_S|L1_S_AP(AP_KRW)| L1_S_DOM(PMAP_DOMAIN_KERNEL)|physstart; __asm __volatile("mcr p15, 0, %1, c2, c0, 0\n" /* set TTB */ "mcr p15, 0, %1, c8, c7, 0\n" /* Flush TTB */ "mcr p15, 0, %2, c3, c0, 0\n" /* Set DAR */ "mrc p15, 0, %0, c1, c0, 0\n" "orr %0, %0, #1\n" /* MMU_ENABLE */ "mcr p15, 0, %0, c1, c0, 0\n" "mrc p15, 0, %0, c2, c0, 0\n" /* CPWAIT */ "mov r0, r0\n" "sub pc, pc, #4\n" : "=r" (tmp) : "r" (pd), "r" (domain)); /* * XXX: This is the most stupid workaround I've ever wrote. * For some reason, the KB9202 won't boot the kernel unless * we access an address which is not in the * 0x20000000 - 0x20ffffff range. I hope I'll understand * what's going on later. */ __hack = *(volatile int *)0xfffff21c; } void __start(void) { void *curaddr; void *dst, *altdst; char *kernel = (char *)&kernel_start; + int sp; __asm __volatile("mov %0, pc" : "=r" (curaddr)); curaddr = (void*)((unsigned int)curaddr & 0xfff00000); #ifdef KZIP if (*kernel == 0x1f && kernel[1] == 0x8b) { int pt_addr = (((int)&_end + KERNSIZE + 0x100) & ~(L1_TABLE_SIZE - 1)) + L1_TABLE_SIZE; +#ifdef CPU_ARM9 + /* So that idcache_wbinv works; */ + if ((cpufunc_id() & 0x0000f000) == 0x00009000) + arm9_setup(); +#endif setup_pagetables(pt_addr, (vm_paddr_t)curaddr, (vm_paddr_t)curaddr + 0x10000000); /* Gzipped kernel */ dst = inflate_kernel(kernel, &_end); kernel = (char *)&_end; altdst = 4 + load_kernel((unsigned int)kernel, (unsigned int)curaddr, (unsigned int)&func_end , 0); if (altdst > dst) dst = altdst; cpu_idcache_wbinv_all(); __asm __volatile("mrc p15, 0, %0, c1, c0, 0\n" "bic %0, %0, #1\n" /* MMU_ENABLE */ "mcr p15, 0, %0, c1, c0, 0\n" : "=r" (pt_addr)); } else #endif dst = 4 + load_kernel((unsigned int)&kernel_start, (unsigned int)curaddr, (unsigned int)&func_end, 0); + sp = (vm_offset_t)dst + 4096; + dst = (void *)sp; memcpy((void *)dst, (void *)&load_kernel, (unsigned int)&func_end - (unsigned int)&load_kernel); - ((void (*)())dst)((unsigned int)kernel, - (unsigned int)curaddr, - dst + (unsigned int)(&func_end) - - (unsigned int)(&load_kernel), 1); + do_call(dst, kernel, dst + (unsigned int)(&func_end) - + (unsigned int)(&load_kernel), sp); } Index: head/sys/arm/arm/inckern.S =================================================================== --- head/sys/arm/arm/inckern.S (revision 159556) +++ head/sys/arm/arm/inckern.S (revision 159557) @@ -1,34 +1,42 @@ /*- * Copyright (c) 2005 Olivier Houchard. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "opt_kernname.h" #include __FBSDID("$FreeBSD$") +ENTRY(do_call) + mov r6, r0 + mov r0, r1 + ldr r1, =0xfff00000 + and r1, pc, r1 + mov sp, r3 + mov r3, #1 + mov pc, r6 .section ".real_kernel","aw" .globl kernel_start; kernel_start: .incbin KERNNAME .globl kernel_end; kernel_end: Index: head/sys/conf/Makefile.arm =================================================================== --- head/sys/conf/Makefile.arm (revision 159556) +++ head/sys/conf/Makefile.arm (revision 159557) @@ -1,126 +1,128 @@ # Makefile.arm -- with config changes. # Copyright 1990 W. Jolitz # from: @(#)Makefile.i386 7.1 5/10/91 # $FreeBSD$ # # Makefile for FreeBSD # # This makefile is constructed from a machine description: # config machineid # Most changes should be made in the machine description # /sys/arm/conf/``machineid'' # after which you should do # config machineid # Generic makefile changes should be made in # /sys/conf/Makefile.arm # after which config should be rerun for all machines. # # Which version of config(8) is required. %VERSREQ= 600004 # Temporary stuff while we're still embryonic NO_MODULES= STD8X16FONT?= iso .if !defined(S) .if exists(./@/.) S= ./@ .else S= ../../.. .endif .endif .include "$S/conf/kern.pre.mk" SYSTEM_LD:= ${SYSTEM_LD:$S/conf/ldscript.$M=ldscript.$M} SYSTEM_DEP:= ${SYSTEM_DEP:$S/conf/ldscript.$M=ldscript.$M} .if defined(ARM_BIG_ENDIAN) CC += -mbig-endian SYSTEM_LD += -EB .endif .if !defined(DEBUG) && !defined(PROFLEVEL) CFLAGS += -mno-apcs-frame STRIP_FLAGS = -S .endif DDB_ENABLED!= grep DDB opt_ddb.h || true SYSTEM_LD_ = ${LD} -Bdynamic -T ldscript.$M.noheader \ -warn-common -export-dynamic -dynamic-linker /red/herring -o \ ${FULLKERNEL}.noheader -X ${SYSTEM_OBJS} vers.o SYSTEM_LD_TAIL +=;sed s/" + SIZEOF_HEADERS"// ldscript.$M\ >ldscript.$M.noheader; \ ${SYSTEM_LD_}; \ ${OBJCOPY} -S -O binary ${FULLKERNEL}.noheader \ ${KERNEL_KO}.bin; \ rm ${FULLKERNEL}.noheader FILES_CPU_FUNC = $S/$M/$M/cpufunc_asm_arm7tdmi.S \ $S/$M/$M/cpufunc_asm_arm8.S $S/$M/$M/cpufunc_asm_arm9.S \ $S/$M/$M/cpufunc_asm_sa1.S $S/$M/$M/cpufunc_asm_arm10.S \ - $S/$M/$M/cpufunc_asm_xscale.S + $S/$M/$M/cpufunc_asm_xscale.S $S/$M/$M/cpufunc_asm.S trampoline: ${KERNEL_KO}.tramp ${KERNEL_KO}.tramp: ${KERNEL_KO} echo "#define KERNNAME \"${KERNEL_KO}.tmp\"" >opt_kernname.h sed s/${KERNVIRTADDR}/${KERNPHYSADDR}/ ldscript.$M > ldscript.$M.tramp sed s/" + SIZEOF_HEADERS"// ldscript.$M.tramp > \ ldscript.$M.tramp.noheader ${OBJCOPY} --strip-symbol '$$d' --strip-symbol '$$a' \ -g --strip-symbol '$$t' ${FULLKERNEL} ${KERNEL_KO}.tmp + eval $$(stat -s ${KERNEL_KO}.tmp) && \ + echo "#define KERNSIZE $$st_size" >>opt_kernname.h ${CC} -O -nostdlib -I. -Xlinker -T -Xlinker ldscript.$M.tramp \ $S/$M/$M/elf_trampoline.c $S/$M/$M/inckern.S -o ${KERNEL_KO}.tramp ${CC} -O -nostdlib -I. -Xlinker -T -Xlinker ldscript.$M.tramp.noheader \ $S/$M/$M/elf_trampoline.c $S/$M/$M/inckern.S -o \ ${KERNEL_KO}.tramp.noheader ${OBJCOPY} -S -O binary ${KERNEL_KO}.tramp.noheader \ ${KERNEL_KO}.tramp.bin ${OBJCOPY} ${STRIP_FLAGS} ${KERNEL_KO}.tmp echo "#define KERNNAME \"${KERNEL_KO}.tmp.gz\"" \ >opt_kernname.h eval $$(stat -s ${KERNEL_KO}.tmp) && \ echo "#define KERNSIZE $$st_size" >>opt_kernname.h gzip -9 ${KERNEL_KO}.tmp eval $$(stat -s ${KERNEL_KO}.tmp.gz) && \ echo "#define KERNCOMPSIZE $$st_size" >>opt_kernname.h ${CC} -O2 -DKZIP -I. -c $S/kern/inflate.c -o inflate-tramp.o ${CC} -O -nostdlib -I. -Xlinker -T -Xlinker ldscript.$M.tramp \ -DKZIP $S/$M/$M/elf_trampoline.c inflate-tramp.o $S/$M/$M/inckern.S \ ${FILES_CPU_FUNC} -o ${KERNEL_KO}.gz.tramp ${CC} -O -nostdlib -I. -Xlinker -T -Xlinker ldscript.$M.tramp.noheader \ -DKZIP $S/$M/$M/elf_trampoline.c inflate-tramp.o $S/$M/$M/inckern.S \ ${FILES_CPU_FUNC} -o ${KERNEL_KO}.tramp.noheader ${OBJCOPY} -S -O binary ${KERNEL_KO}.tramp.noheader \ ${KERNEL_KO}.gz.tramp.bin rm ${KERNEL_KO}.tmp.gz ${KERNEL_KO}.tramp.noheader opt_kernname.h \ inflate-tramp.o %BEFORE_DEPEND %OBJS %FILES.c %FILES.s %FILES.m %CLEAN CLEAN+= ldscript.$M ${KERNEL_KO}.bin ldscript.$M.noheader .if ${DDB_ENABLED} != "" CLEAN+= ${KERNEL_KO}.tramp ${KERNEL_KO}.tramp.bin ldscript.$M.tramp \ ldscript.$M.tramp.noheader ${KERNEL_KO}.gz.tramp \ ${KERNEL_KO}.gz.tramp.bin .endif ldscript.$M: $S/conf/ldscript.$M cat $S/conf/ldscript.$M|sed s/KERNPHYSADDR/${KERNPHYSADDR}/g| \ sed s/KERNVIRTADDR/${KERNVIRTADDR}/g > ldscript.$M %RULES .include "$S/conf/kern.post.mk"