
Hi Wolfgang et all,
I ported U-Boot to OMAP5910 based board and before submiting patch I'd like to discuss few issues.
Board has 64M RAM and 32M bit mirror flash, which is quite sufficient to run U-Boot under normal circumstancies. During production of prototypes I met few boards with bad printed circuit board or bad soldering. Therefore I decided to run U-Boot from OMAP's 192kB internal RAM located at 2000'0000-2002'ffff with TEXT_BASE set to 2001'2000. That way I have 64kB heap and 8kB stack, which I found is sufficient for my needs. Such setup helps a lot while debugging hardware problems, despite I know it could be done different way, but it would be pity not to use U-Boot's power :)
Because CFG_MALLOC_LEN is 64k-128 something like this is needed to startup code:
Index: cpu/arm925t/start.S =================================================================== RCS file: /cvsroot/u-boot/u-boot/cpu/arm925t/start.S,v retrieving revision 1.8 diff -u -r1.8 start.S --- cpu/arm925t/start.S 9 Jan 2005 17:12:29 -0000 1.8 +++ cpu/arm925t/start.S 12 Jan 2005 12:45:27 -0000 @@ -83,6 +83,10 @@
_TEXT_BASE: .word TEXT_BASE +_STACK_OFS: + .word CFG_MALLOC_LEN + CFG_GBL_DATA_SIZE +_BAD_STACK_OFS: + .word CFG_MALLOC_LEN + CFG_GBL_DATA_SIZE + CONFIG_STACKSIZE + 8
.globl _armboot_start _armboot_start: @@ -188,8 +192,8 @@ /* Set up the stack */ stack_setup: ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ - sub r0, r0, #CFG_MALLOC_LEN /* malloc area */ - sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */ + ldr r1, _STACK_OFS + sub r0, r0, r1 /* malloc area and bdinfo */ #ifdef CONFIG_USE_IRQ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) #endif @@ -293,8 +297,8 @@ stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
ldr r2, _armboot_start - sub r2, r2, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) - sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack + ldr r13, _BAD_STACK_OFS + sub r2, r2, r13 ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs) add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
@@ -326,8 +330,8 @@
.macro get_bad_stack ldr r13, _armboot_start @ setup our mode stack - sub r13, r13, #(CONFIG_STACKSIZE+CFG_MALLOC_LEN) - sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack + ldr r2, _BAD_STACK_OFS + sub r13, r13, r2
str lr, [r13] @ save caller lr in position 0 of saved stack mrs lr, spsr @ get the spsr
Flash is partitioned this way: 128k - U-Boot 128k - env 16256k - data1 16256k - data2
Kernel is loaded directly from jffs2 partition to ease firmware upgrating. New firmware is unpacked into other partion (after user data are backed out) and if it boots sucessfuly U-Boot env is changed permanetly. Otherwise watchdog resets board and old firmware is used again.
Although only following commands are enabled: CFG_CMD_BDI, CFG_CMD_LOADB, CFG_CMD_IMI, CFG_CMD_FLASH, CFG_CMD_MEMORY, CFG_CMD_NET, CFG_CMD_ENV, CFG_CMD_BOOTD, CFG_CMD_DHCP, CFG_CMD_PING, CFG_CMD_JFFS2, there is not enough space to fit U-Boot into 120kB without ripping out CramFS support. My question is whenever I should make only CramFS selectable or allow choice between JFFS2 and/or CramFS and how should be such configuration handled (you know it's quite hard for me to come with some nice short descriptive names :))
And finally ~64k heap is not sufficient for zlib to decompress kernel after it is loaded from jffs2 partition, because node structures are still allocated. I hope it is reasonable to expect, that once file is loaded it is intended to execute it and free memory used by jffs2 private structures.
Index: fs/jffs2/jffs2_1pass.c =================================================================== RCS file: /cvsroot/u-boot/u-boot/fs/jffs2/jffs2_1pass.c,v retrieving revision 1.15 diff -u -p -r1.15 jffs2_1pass.c --- fs/jffs2/jffs2_1pass.c 12 May 2004 22:54:39 -0000 1.15 +++ fs/jffs2/jffs2_1pass.c 12 Jan 2005 13:17:58 -0000 @@ -467,8 +467,8 @@ jffs2_scan_empty(u32 start_offset, struc return offset - part->offset; }
-static u32 -jffs_init_1pass_list(struct part_info *part) +static void +jffs_1pass_free_nodes(struct part_info *part) { struct b_lists *pL;
@@ -478,6 +478,16 @@ jffs_init_1pass_list(struct part_info *p free_nodes(&pL->dir); free(pL); } + part->jffs2_priv = NULL; +} + +static u32 +jffs_init_1pass_list(struct part_info *part) +{ + struct b_lists *pL; + + jffs_1pass_free_nodes(part); + if (NULL != (part->jffs2_priv = malloc(sizeof(struct b_lists)))) { pL = (struct b_lists *)part->jffs2_priv;
@@ -1267,6 +1277,9 @@ jffs2_1pass_load(char *dest, struct part
DEBUGF ("load: loaded '%s' to 0x%lx (%ld bytes)\n", fname, (unsigned long) dest, ret); + + jffs_1pass_free_nodes(part); + return ret; }
Comments and suggestions are welcome (even those which suggest to use completely different solution ;)). I'll eventually send final patches based on eventual discussion.
Best regards, ladis