From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ladislav Michl Date: Wed, 12 Jan 2005 14:31:56 +0100 Subject: [U-Boot-Users] Lowering memory footprint Message-ID: <20050112133156.GA7451@orphique> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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