[linux-sh:03271] Booting the Linux-2.4.x kernel for SH4 for uClinux from ROM - Patch submission (Whoops!)

Rahul Chaturvedi <[email protected]> Wed, 23 Jun 2004 23:42:09 -0700 (PDT)
Newsgroups gmane.linux.ports.sh.general,gmane.linux.uclinux.devel,gmane.linux.ports.sh.devel
Message-ID <[email protected]>
Sorry guys, I did the diff the other way around!

Here is the patch with the diff done correctly, so it
should apply without needing the -R switch.


Btw, this patch has been tested on a BigSurIV board
only till now (since its the only board I have :)).

If anyone wants to volunteer to test it on other SH4
boards, it should *theoretically* work ;), and I would
appreciate it :)


		
__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail
linux-sh-ROMBoot.patch (text/plain, 9.7 KB)
diff -Naur linux-2.4.x/arch/sh/config.in ../uClinux-dist/linux-2.4.x/arch/sh/config.in
--- linux-2.4.x/arch/sh/config.in	2004-04-08 05:46:04.000000000 +0530
+++ ../uClinux-dist/linux-2.4.x/arch/sh/config.in	2004-06-24 09:26:46.000000000 +0530
@@ -184,6 +184,14 @@
 
 hex 'Link address offset for booting' CONFIG_BOOT_LINK_OFFSET 00210000
 
+if [ "$CONFIG_SH_BIGSUR" = "y" ]; then
+   bool 'Boot kernel from ROM' CONFIG_SH_ROMBOOT
+fi
+
+if [ "$CONFIG_SH_ROMBOOT" = "y" ]; then
+	hex 'Offset into ROM to store image at' CONFIG_ROM_STORE_OFFSET 100000
+fi
+
 dep_bool 'Enable OC RAM zone (experimental)' CONFIG_SCRATCH_SPACE $CONFIG_EXPERIMENTAL
 bool 'DSP mode support' CONFIG_SH_DSP
 
diff -Naur linux-2.4.x/arch/sh/kernel/head.S ../uClinux-dist/linux-2.4.x/arch/sh/kernel/head.S
--- linux-2.4.x/arch/sh/kernel/head.S	2004-04-08 05:46:04.000000000 +0530
+++ ../uClinux-dist/linux-2.4.x/arch/sh/kernel/head.S	2004-06-24 09:31:36.000000000 +0530
@@ -9,11 +9,16 @@
  * for more details.
  *
  * Head.S contains the SH exception handlers and startup code.
+ *
+ * Modified by Rahul Chaturvedi on 22/06/2004 ([email protected])
+ * to add support for booting the kernel from ROM
+ *
  */
 #include <linux/linkage.h>
 
 	.section	.empty_zero_page, "aw"
 ENTRY(empty_zero_page)
+
 #ifdef CONFIG_BLK_DEV_INITRD
 	.long	1		/* MOUNT_ROOT_RDONLY */
 	.long	0x4000		/* RAMDISK_FLAGS */
@@ -64,6 +69,51 @@
  *
  */
 ENTRY(_stext)
+
+#if defined(CONFIG_SH_ROMBOOT)
+!			Copy zero page to RAM
+
+	mov.l	11f, r1		! r1 = src (zero page in ROM - _rom_store)
+	mov.l	12f, r2		! r2 = dest (zero page dest in RAM - _mem_start)
+
+	mov.l	13f, r0		! r0 = sizeof zero page (4k)
+	add	r2, r0		! r0 = end of dest 
+
+10:
+	mov.b	@r1, r3
+	mov.b	r3, @r2
+
+	add #1, r1
+	add #1, r2
+	
+	cmp/eq r2, r0
+	bf 10b
+
+
+
+!			Copy everything from _etext to __bss_start to RAM
+
+	mov.l	7f, r2		! r2 = dest (_etext)
+	mov	r2, r1
+	mov.l	12f, r3	
+	sub	r3, r1 		! r1 = _etext - _mem_start
+	mov.l	11f, r3	
+	add	r3, r1		! r1 = _etext - (_mem_start - _rom_store) = src
+	
+	mov.l	3f, r0		! r0 = end of dest (__bss_start)
+
+14:
+	mov.b	@r1, r3
+	mov.b	r3, @r2
+
+	add #1, r1
+	add #1, r2
+	
+	cmp/eq r2, r0
+	bf 14b
+
+#endif
+
 	!			Initialize Status Register
 	mov.l	1f, r0		! MD=1, RB=0, BL=0, IMASK=0xF
 	ldc	r0, sr
@@ -82,12 +132,15 @@
 	mov.l	6f, r0
 	jsr	@r0
 	nop
+
 #if defined(CONFIG_SH_SNAPGEAR)
 	! move the romfs to after the bss
 	mov.l	fix_romfs, r0
 	jsr @r0
 #endif
 	nop
+
+
 	!			Clear BSS area
 	mov.l	3f, r1
 	add	#4, r1
@@ -96,6 +149,7 @@
 9:	cmp/hs	r2, r1
 	bf/s	9b		! while (r1 < r2)
 	mov.l	r0,@-r2
+
 	!			Start kernel
 	mov.l	5f, r0
 	jmp	@r0
@@ -108,6 +162,15 @@
 4:	.long	SYMBOL_NAME(_end)
 5:	.long	SYMBOL_NAME(start_kernel)
 6:	.long	SYMBOL_NAME(cache_init)
+
+
+#if defined(CONFIG_SH_ROMBOOT)
+7:	.long	SYMBOL_NAME(_etext);
+11:	.long	SYMBOL_NAME(_rom_store)	
+12:	.long	SYMBOL_NAME(_mem_start)
+13:	.long	0x1000
+#endif
+
 #if defined(CONFIG_SH_SNAPGEAR)
 fix_romfs: .long copy_romfs
 #endif
diff -Naur linux-2.4.x/arch/sh/kernel/setup.c ../uClinux-dist/linux-2.4.x/arch/sh/kernel/setup.c
--- linux-2.4.x/arch/sh/kernel/setup.c	2004-04-08 05:46:04.000000000 +0530
+++ ../uClinux-dist/linux-2.4.x/arch/sh/kernel/setup.c	2004-06-24 09:31:00.000000000 +0530
@@ -4,6 +4,9 @@
  *
  *  Copyright (C) 1999  Niibe Yutaka
  *
+ * Modified by Rahul Chaturvedi on 22/06/2004 ([email protected])
+ * Lines 158-164 (For copying the ROMFS from the .bss image in ROM instead of RAM)
+ * 
  */
 
 /*
@@ -153,8 +156,13 @@
 {
 	unsigned long	*sp, *dp, len;
 	extern int __bss_start;
+#ifdef CONFIG_SH_ROMBOOT
+	extern int _mem_start, _rom_store;
 
+	sp = (unsigned long *) &__bss_start - ((_mem_start - _rom_store) / 4);
+#else
 	sp = (unsigned long *) &__bss_start;
+#endif
 	dp = (unsigned long *) &_end;
 
 	if (memcmp(&sp[0], "-rom1fs-", 8) == 0) { /* romfs */
diff -Naur linux-2.4.x/arch/sh/Makefile ../uClinux-dist/linux-2.4.x/arch/sh/Makefile
--- linux-2.4.x/arch/sh/Makefile	2004-04-08 05:46:04.000000000 +0530
+++ ../uClinux-dist/linux-2.4.x/arch/sh/Makefile	2004-06-24 09:29:16.000000000 +0530
@@ -11,6 +11,9 @@
 # for "archclean" and "archdep" for cleaning up and making dependencies for
 # this architecture
 #
+# Modified by Rahul Chaturvedi on 22/06/2004 ([email protected])
+# to add support to use the vmlinux.lds.rom.S file when specified by the user
+#
 
 ifdef CONFIG_CPU_LITTLE_ENDIAN
 CFLAGS		+= -ml
@@ -104,8 +107,13 @@
 	@rm -f include/asm-sh/cpu
 	@ln -sf $(cpuincdir-y) include/asm-sh/cpu
 
+ifdef CONFIG_SH_ROMBOOT
+arch/sh/vmlinux.lds: arch/sh/vmlinux.lds.rom.S FORCE
+	$(CPP) -traditional -C -P -I$(HPATH) -Ush arch/sh/vmlinux.lds.rom.S >arch/sh/vmlinux.lds
+else
 arch/sh/vmlinux.lds: arch/sh/vmlinux.lds.S FORCE
 	$(CPP) -traditional -C -P -I$(HPATH) -Ush arch/sh/vmlinux.lds.S >arch/sh/vmlinux.lds
+endif
 
 FORCE: ;
 
diff -Naur linux-2.4.x/arch/sh/vmlinux.lds.rom.S ../uClinux-dist/linux-2.4.x/arch/sh/vmlinux.lds.rom.S
--- linux-2.4.x/arch/sh/vmlinux.lds.rom.S	1970-01-01 05:30:00.000000000 +0530
+++ ../uClinux-dist/linux-2.4.x/arch/sh/vmlinux.lds.rom.S	2004-06-24 09:27:52.000000000 +0530
@@ -0,0 +1,163 @@
+/* $Id: vmlinux.lds.in,v 1.5 2001/07/27 11:45:55 gniibe Exp $
+ * ld script to make SuperH Linux kernel (for booting from ROM)
+ * Written by Niibe Yutaka
+ *
+ * Modified by Rahul Chaturvedi on 22/06/2004 ([email protected])
+ * to add support to boot from a ROM image
+ */
+#include <linux/config.h>
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
+#else
+OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux")
+#endif
+OUTPUT_ARCH(sh)
+ENTRY(_start)
+SECTIONS
+{
+  _mem_start  = 0x80000000 + CONFIG_MEMORY_START + 0x1000;
+  _rom_store = 0x80000000 + CONFIG_ROM_STORE_OFFSET;
+
+  . = _mem_start;
+  .empty_zero_page : {
+	*(.empty_zero_page)
+	} = 0
+
+  . = _rom_store;
+  _text = .;			/* Text and read-only data */
+  text = .;			/* Text and read-only data */
+
+  .text _rom_store + SIZEOF(.empty_zero_page) : 
+		AT (_mem_start + SIZEOF(.empty_zero_page)) {
+	*(.text)
+	*(.fixup)
+	*(.gnu.warning)
+	} = 0x0009
+
+
+
+  .rodata : 
+	      AT( ADDR(.text) + SIZEOF(.text) + (_mem_start - _rom_store)) 	{ *(.rodata) *(.rodata.*) }
+
+  .kstrtab : AT ( ADDR(.rodata) + SIZEOF(.rodata) + (_mem_start - _rom_store)) { *(.kstrtab) }
+
+
+
+  _ctr = .;
+  . = ALIGN(16);		/* Exception table */
+  _ctr = _ctr - .;
+  __start___ex_table = .;
+  __ex_table : AT( ADDR(.kstrtab) + SIZEOF(.kstrtab) + 
+				(_mem_start - _rom_store)) { *(__ex_table) }
+  __stop___ex_table = .;
+
+  __start___ksymtab = .;	/* Kernel symbol table */
+  __ksymtab : AT( ADDR(__ex_table) + SIZEOF(__ex_table) + 
+				(_mem_start - _rom_store)) { *(__ksymtab) }
+  __stop___ksymtab = .;
+
+  __start___kallsyms = .;	/* All kernel symbols */
+  __kallsyms : AT( ADDR(__ksymtab) + SIZEOF(__ksymtab) + 
+				(_mem_start - _rom_store)) { *(__kallsyms) }
+  __stop___kallsyms = .;
+
+  . = ADDR(__kallsyms) + SIZEOF(__kallsyms)
+				+ (_mem_start - _rom_store) + _ctr;
+
+  _etext = .;			/* End of text section */
+
+  .data : {			/* Data */
+	*(.data)
+	CONSTRUCTORS
+	}
+
+  _edata = .;			/* End of data section */
+
+  . = ALIGN(8192);		/* init_task */
+  .data.init_task : { *(.data.init_task) }
+  /* stack */
+  .stack : { stack = .;  _stack = .; }
+
+  . = ALIGN(4096);		/* Init code and data */
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(16);
+  __setup_start = .;
+  .setup.init : { *(.setup.init) }
+  __setup_end = .;
+  __initcall_start = .;
+  .initcall.init : { *(.initcall.init) }
+  __initcall_end = .;
+  __machvec_start = .;
+  .machvec.init : { *(.machvec.init) }
+  __machvec_end = .;
+  . = ALIGN(4096);
+  __init_end = .;
+
+  . = ALIGN(4096);
+  .data.page_aligned : { *(.data.idt) }
+
+#ifdef CONFIG_CPU_SH3	
+  . = ALIGN(16);
+#else
+  . = ALIGN(32);
+#endif	
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+  . = ALIGN(4);
+  __bss_start = .;		/* BSS */
+  _initrd_rom = . - (_mem_start - _rom_store);
+
+  .bss : {
+	*(.bss)
+	}
+  . = ALIGN(4096);
+  _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.exit)
+	}
+
+  /* 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  .  */
+}
HITACHI-BigSurIV_ROMBoot-HOWTO (text/plain, 987 B)
-------------------------------
HITACHI BigSurIV ROM Boot patch
-------------------------------


This patch will add an additional option in the kernel configuration to have
the kernel boot from ROM instead of needing to be copied to RAM first.

To apply this patch, go into the following directory,

cd uClinux-dist
and run
patch -p0 < $PATCH_LOCATION/linux-sh-ROMBoot.patch


This will give you a new option in the kernel configuration called
"Boot kernel from ROM". Select this option if you want to have the
kernel code segment running from ROM.

Then you will need to give the offset into the ROM where you wish
to store/run the image from.

You will then need to modify your boot loader to jump into the specified
offset + 0x1000. So if the offset is specified as 0x100000 (the default),
then your boot loader needs to jump to 0x101000 to boot the kernel.

Also, remove any code for copying the image into RAM. Any copying that
needs to be done will be done by the kernel itself.