From: Jesper S. <js...@re...> - 2000-08-25 09:03:31
|
>>>>> "Jesper" == Jesper Skov <js...@re...> writes: >>>>> "Manoj" == Manoj Kumar <man...@so...> writes: Manoj> Hello all, I want to build a ROMable kernel image.I am using Manoj> NIIBE's sh-linux 2.4.0. I am not using a CE device. Does Manoj> anyone know about a patch for doing the same? Manoj> I found a patch in Ludovic's site,but it is for linux2.3.23. Jesper> I have some XIP patches. I need to clean them up and submit Jesper> them. Hopefully today, but I need to check that they are OK to Jesper> publicize - so no guarantees. I have now uploaded the simple patch below to the patch manager at sourceforge. The only real problem with the patch as far as I'm concerned is that it uses a hack to separate arguments from the empty_zero_page. I had to do this because (a) I'm using some scripts to write boot parameters into the start of the boot image and (b) empty_zero_page has to be in the data section so it will end up in RAM. I don't know if the patch is worth integrating the public tree before that issue has been fixed. But even so, there are a few generic fixes in there as well: Documentation fix + lose module exit functions. For debugging with the XIP configuration, I configure something like this (I have 8MB RAM @ 0x0c000000): CONFIG_SH_XIP=y CONFIG_XIP_ROM_START=0C100000 CONFIG_MEMORY_START=0C300000 CONFIG_MEMORY_SIZE=00500000 Thus leaving 2MB @ 0x0c100000 for the boot image (kernel text + initrd). On startup the data section is copied to MEMORY_START and the 5MB @ 0x0c300000 is mapped as if it was the only RAM in the system. Then I'm free to still use breakpoints/single-step the kernel text. For production I put CONFIG_XIP_ROM_START=00100000, and have the full 8MB of RAM for the system. (the 1MB missing are for the boot monitor). Cheers, Jesper 2000-08-25 Jesper Skov <js...@re...> * arch/sh/Makefile: Select linker script based on XIP config. * arch/sh/config.in: Added XIP related and memory default size options. * arch/sh/vmlinux.lds.S: Added _sdata label. Discard .exitcalls from modules. * arch/sh/vmlinux.lds.xip.S: [Added] Linker script for XIP configuration. * arch/sh/kernel/head.S: Copy data to RAM in XIP config. Crufty hack to keep arguments at front of image while empty_zero_page ends up in RAM. * arch/sh/kernel/setup.c (parse_cmdline): Use configurable default memory size. empty_zero_page/argument_page XIP hack. * arch/sh/mm/init.c (mem_init): Use _sdata instead of _etext for size calculation. * Documentation/Configure.help: Added descriptions for new options. Fixed CPU selection description. Index: Documentation/Configure.help =================================================================== RCS file: /cvsroot/linuxsh/kernel/Documentation/Configure.help,v retrieving revision 1.21 diff -u -5 -r1.21 Configure.help --- Documentation/Configure.help 2000/08/10 01:19:39 1.21 +++ Documentation/Configure.help 2000/08/25 08:48:00 @@ -14818,14 +14818,15 @@ # The following options are for Linux when running on the Hitachi # SuperH family of RISC microprocessors. CPU Selection -CONFIG_CPU_SUBTYPE_SH7708 +CONFIG_CPU_SUBTYPE_SH7707 This is the type of your Hitachi SuperH processor. This information is used for optimizing and configuration purposes. + - "SH7707" for SH7707 - "SH7708" for SH7708, SH7708S, SH7708R - "SH7709" for SH7707, SH7709, SH7709A, and SH7729. - "SH7750" for SH7750, and possibly SH7751 Physical memory start address @@ -14837,10 +14838,40 @@ You should set this value to the address of the lowest RAM location. A value of 0c000000 will work for most boards. + +Execute-in-place kernel +CONFIG_SH_XIP + Selecting this option (eXecute-In-Place) will allow the kernel text + and rodata segments to remain in flash/ROM memory, saving on RAM usage. + + There might be a small performance degradation due to the flash/ROM + being slower than DRAM, but since the kernel only uses a fraction of + the total CPU time, this should not be a problem. The RAM freed up + by running the kernel out of flash/ROM will probably more than + counter this slowdown. + +XIP text segment start address +CONFIG_XIP_ROM_START + When the XIP option is selected, this option controls where the + kernel text segment starts. SuperH processors always have flash/ROM + at address zero, but there may be reasons to put the kernel + elsewhere: + + Higher up in the flash/ROM, leaving the start of the flash/ROM to a + boot monitor which can start Linux. + + In RAM, allowing for debugging. In this case you should adjust the + CONFIG_MEMORY_START option as well, leaving a gap for the kernel in + RAM. + +Memory size +CONFIG_MEMORY_SIZE + The amount of RAM used by Linux can be controlled with a kernel + parameter, but this option allows for a configurable default. Directly Connected Compact Flash support CONFIG_CF_ENABLER If your board has "Directly Connected" Compact Flash at area 6, you may want to enable this option. Then, you can use CF as Index: arch/sh/Makefile =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/Makefile,v retrieving revision 1.9 diff -u -5 -r1.9 Makefile --- arch/sh/Makefile 2000/07/31 12:35:55 1.9 +++ arch/sh/Makefile 2000/08/25 08:48:01 @@ -80,14 +80,20 @@ SUBDIRS += arch/sh/overdrive CORE_FILES += arch/sh/overdrive/overdrive.o endif endif +ifdef CONFIG_SH_XIP +LINKSCRIPT_SRC = arch/sh/vmlinux.lds.xip.S +else +LINKSCRIPT_SRC = arch/sh/vmlinux.lds.S +endif + vmlinux: arch/sh/vmlinux.lds -arch/sh/vmlinux.lds: arch/sh/vmlinux.lds.S FORCE - $(CPP) -C -P -I$(HPATH) -Ush arch/sh/vmlinux.lds.S >arch/sh/vmlinux.lds +arch/sh/vmlinux.lds: $(LINKSCRIPT_SRC) FORCE + $(CPP) -C -P -I$(HPATH) -Ush $(LINKSCRIPT_SRC) >arch/sh/vmlinux.lds FORCE: ; zImage: vmlinux @$(MAKEBOOT) zImage Index: arch/sh/config.in =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/config.in,v retrieving revision 1.19 diff -u -5 -r1.19 config.in --- arch/sh/config.in 2000/08/05 07:04:45 1.19 +++ arch/sh/config.in 2000/08/25 08:48:02 @@ -52,16 +52,21 @@ if [ "$CONFIG_CPU_SUBTYPE_SH7750" = "y" ]; then define_bool CONFIG_CPU_SH3 n define_bool CONFIG_CPU_SH4 y fi bool 'Little Endian' CONFIG_CPU_LITTLE_ENDIAN +bool 'Kernel XIP' CONFIG_SH_XIP +if [ "$CONFIG_SH_XIP" = "y" ]; then + hex 'ROM physical start address' CONFIG_XIP_ROM_START 08100000 +fi if [ "$CONFIG_SH_SOLUTION_ENGINE" = "y" -o "$CONFIG_SH_HP600" = "y" -o \ "$CONFIG_SH_OVERDRIVE" = "y" ]; then define_hex CONFIG_MEMORY_START 0c000000 else hex 'Physical memory start address' CONFIG_MEMORY_START 08000000 fi +hex 'Memory size' CONFIG_MEMORY_SIZE 00400000 endmenu mainmenu_option next_comment comment 'General setup' Index: arch/sh/vmlinux.lds.S =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/vmlinux.lds.S,v retrieving revision 1.6 diff -u -5 -r1.6 vmlinux.lds.S --- arch/sh/vmlinux.lds.S 2000/08/05 06:25:22 1.6 +++ arch/sh/vmlinux.lds.S 2000/08/25 08:48:02 @@ -35,10 +35,11 @@ __start___ksymtab = .; /* Kernel symbol table */ __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; _etext = .; /* End of text section */ + _sdata = .; /* Start of data section */ .data : { /* Data */ *(.data) CONSTRUCTORS } @@ -87,10 +88,11 @@ * it's a module. */ /DISCARD/ : { *(.text.exit) *(.data.exit) + *(.exitcall.*) } /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } Index: arch/sh/vmlinux.lds.xip.S =================================================================== RCS file: vmlinux.lds.xip.S diff -N vmlinux.lds.xip.S --- arch/sh/vmlinux.lds.xip.S Tue May 5 13:32:27 1998 +++ arch/sh/vmlinux.lds.xip.S Fri Aug 25 01:48:03 2000 @@ -0,0 +1,155 @@ +/* $Id: vmlinux.lds.xip.S,v 1.3 2000/08/21 14:12:02 jskov Exp $ + * ld script to make SuperH Linux kernel + * Written by Niibe Yutaka + */ + +#include <linux/config.h> +#ifdef CONFIG_CPU_LITTLE_ENDIAN +OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl") +#else +OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh") +#endif +OUTPUT_ARCH(sh) +ENTRY(_start) + +#define ALIGN_LMA 4 +#define ALIGNED_GAP(_section_, _align_) (((ADDR(_section_)+SIZEOF(_section_)+(_align_)-1) & ~((_align_)-1))-ADDR(_section_)) +#define FOLLOWING(_section_, _align_) AT (LOADADDR (_section_) + ALIGNED_GAP(_section_, _align_)) + +SECTIONS +{ + . = 0x80000000 + CONFIG_XIP_ROM_START + 0x1000; + _text = .; /* Text and read-only data */ + text = .; /* Text and read-only data */ + .argument_page : { + *(.argument_page) + } = 0 + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + *(.text.init) + } = 0x0009 + .text.lock : { *(.text.lock) } /* out-of-line lock text */ + .rodata : { *(.rodata) } + .kstrtab : { *(.kstrtab) } + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + + _etext = .; /* End of text section */ + + _xip_load = .; /* Load address of data for RAM */ + . = 0x80000000 + CONFIG_MEMORY_START; + _xip_sdata = .; /* Start of data section */ + _sdata = .; /* Start of data section */ + .empty_zero_page : FOLLOWING(__ksymtab, 1) { + *(.empty_zero_page) + } = 0 + . = ALIGN(4096); + .data : FOLLOWING(.empty_zero_page, 4096) {/* Data */ + *(.data) +#if 0 + CONSTRUCTORS +#endif + } + + _edata = .; /* End of data section */ + + . = ALIGN(8192); /* init_task */ + .data.init_task : FOLLOWING(.data, 8192) { *(.data.init_task) } + /* stack */ + .stack : { stack = .; _stack = .; } + + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + .data.init : FOLLOWING(.data.init_task, 4096) { *(.data.init) } + . = ALIGN(16); + __setup_start = .; + .setup.init : FOLLOWING(.data.init, 16) { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : FOLLOWING(.setup.init, 1) { *(.initcall.init) } + __initcall_end = .; + __machvec_start = .; + .machvec.init : FOLLOWING(.initcall.init, 1) { *(.machvec.init) } + __machvec_end = .; + . = ALIGN(4096); + __init_end = .; + +#if 0 + . = ALIGN(4096); + .data.page_aligned : FOLLOWING(.setup.init, 4096) { *(.data.idt) } +#endif + +#if 0 + . = ALIGN(32); + .data.cacheline_aligned : FOLLOWING(.data.page_aligned, 32) { *(.data.cacheline_aligned) } +#else + . = ALIGN(4096); + .data.cacheline_aligned : FOLLOWING(.initcall.init, 4096) { *(.data.cacheline_aligned) } +#endif + + . = ALIGN(4); + + _xip_edata = .; /* End of data that needs to be copied */ + + __bss_start = .; /* BSS */ + .bss : { + *(.bss) + } + . = ALIGN(4); + _end = . ; + + /* When something in the kernel is NOT compiled as a module, the + * module cleanup code and data are put into these segments. Both + * can then be thrown away, as cleanup code is never called unless + * it's a module. + */ + /DISCARD/ : { + *(.text.exit) + *(.data.exit) + *(.exitcall.*) + } + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging section are relative to the beginning + of the section so we begin .debug at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ +} Index: arch/sh/kernel/head.S =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/head.S,v retrieving revision 1.7 diff -u -5 -r1.7 head.S --- arch/sh/kernel/head.S 2000/07/04 06:24:39 1.7 +++ arch/sh/kernel/head.S 2000/08/25 08:48:03 @@ -10,12 +10,21 @@ * * Head.S contains the SH exception handlers and startup code. */ #include <linux/linkage.h> +#ifdef CONFIG_SH_XIP .section .empty_zero_page, "aw" ENTRY(empty_zero_page) + .long 0 + + .section .argument_page, "aw" +ENTRY(argument_page) +#else + .section .empty_zero_page, "aw" +ENTRY(empty_zero_page) +#endif .long 1 /* MOUNT_ROOT_RDONLY */ .long 0 /* RAMDISK_FLAGS */ .long 0x0200 /* ORIG_ROOT_DEV */ .long 1 /* LOADER_TYPE */ .long 0x00360000 /* INITRD_START */ @@ -58,10 +67,21 @@ #endif ! Enable cache mov.l 6f, $r0 jsr @$r0 nop +#ifdef CONFIG_SH_XIP + ! Copy data to RAM + mov.l 10f,$r0 + mov.l 11f,$r1 + mov.l 12f,$r2 +9: mov.l @$r0+,$r3 ! get word from ROM + mov.l $r3,@$r1 ! store in RAM + add #4,$r1 + cmp/eq $r1,$r2 ! compare + bf 9b ! loop if not yet done +#endif ! Clear BSS area mov.l 3f, $r1 add #4, $r1 mov.l 4f, $r2 mov #0, $r0 @@ -80,6 +100,11 @@ 4: .long SYMBOL_NAME(_end) 5: .long SYMBOL_NAME(start_kernel) 6: .long SYMBOL_NAME(cache_init) #if defined(__SH4__) 7: .long SYMBOL_NAME(fpu_init) +#endif +#ifdef CONFIG_SH_XIP +10: .long SYMBOL_NAME(_xip_load) +11: .long SYMBOL_NAME(_xip_sdata) +12: .long SYMBOL_NAME(_xip_edata) #endif Index: arch/sh/kernel/setup.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/kernel/setup.c,v retrieving revision 1.11 diff -u -5 -r1.11 setup.c --- arch/sh/kernel/setup.c 2000/08/05 06:25:23 1.11 +++ arch/sh/kernel/setup.c 2000/08/25 08:48:04 @@ -69,11 +69,16 @@ static struct sh_machine_vector* __init get_mv_byname(const char* name); /* * This is set up by the setup-routine at boot-time */ +#ifndef CONFIG_SH_XIP #define PARAM ((unsigned char *)empty_zero_page) +#else +extern unsigned char argument_page; +#define PARAM ((unsigned char *)&argument_page) +#endif #define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000)) #define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004)) #define ORIG_ROOT_DEV (*(unsigned long *) (PARAM+0x008)) #define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c)) @@ -202,12 +207,12 @@ /* Save unparsed command line copy for /proc/cmdline */ memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START; - /* Default is 4Mbyte. */ - memory_end = (unsigned long)PAGE_OFFSET+0x00400000+__MEMORY_START; + /* Default is specified by the configuration */ + memory_end = (unsigned long)PAGE_OFFSET+CONFIG_MEMORY_SIZE+__MEMORY_START; for (;;) { /* * "mem=XXX[kKmM]" defines a size of memory. */ Index: arch/sh/mm/init.c =================================================================== RCS file: /cvsroot/linuxsh/kernel/arch/sh/mm/init.c,v retrieving revision 1.6 diff -u -5 -r1.6 init.c --- arch/sh/mm/init.c 2000/08/16 08:34:04 1.6 +++ arch/sh/mm/init.c 2000/08/25 08:48:04 @@ -176,11 +176,11 @@ show_buffers(); } /* References to section boundaries */ -extern char _text, _etext, _edata, __bss_start, _end; +extern char _text, _etext, _sdata, _edata, __bss_start, _end; extern char __init_begin, __init_end; pgd_t swapper_pg_dir[1024]; /* It'd be good if these lines were in the standard header file. */ @@ -251,11 +251,11 @@ * Only count reserved RAM pages */ if (PageReserved(mem_map+tmp)) reservedpages++; codesize = (unsigned long) &_etext - (unsigned long) &_text; - datasize = (unsigned long) &_edata - (unsigned long) &_etext; + datasize = (unsigned long) &_edata - (unsigned long) &_sdata; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), max_mapnr << (PAGE_SHIFT-10), |