[U-Boot-Users] Lowering memory footprint

Ladislav Michl ladis at linux-mips.org
Wed Jan 12 14:31:56 CET 2005


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




More information about the U-Boot mailing list