[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