mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 23:51:33 +00:00
[new uImage] Use lmb for bootm allocations
Convert generic ramdisk_high(), get_boot_cmdline(), get_boot_kbd() functions over to using lmb for allocation of the ramdisk, command line and kernel bd info. Convert PPC specific fdt_relocate() to use lmb for allocation of the device tree. Provided a weak function that board code can call to do additional lmb reserves if needed. Also introduce the concept of bootmap_base to specify the offset in physical memory that the bootmap is located at. This is used for allocations of the cmdline, kernel bd, and device tree as they should be contained within bootmap_base and bootmap_base + CFG_BOOTMAPSZ. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
This commit is contained in:
parent
f5614e7926
commit
e822d7fc4d
5 changed files with 118 additions and 125 deletions
|
@ -103,6 +103,12 @@ static boot_os_fn do_bootm_artos;
|
||||||
ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */
|
ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */
|
||||||
static bootm_headers_t images; /* pointers to os/initrd/fdt images */
|
static bootm_headers_t images; /* pointers to os/initrd/fdt images */
|
||||||
|
|
||||||
|
void __board_lmb_reserve(struct lmb *lmb)
|
||||||
|
{
|
||||||
|
/* please define platform specific board_lmb_reserve() */
|
||||||
|
}
|
||||||
|
void board_lmb_reserve(struct lmb *lmb) __attribute__((weak, alias("__board_lmb_reserve")));
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/* bootm - boot application image from image in memory */
|
/* bootm - boot application image from image in memory */
|
||||||
|
@ -134,6 +140,8 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
||||||
lmb_add(&lmb, 0, gd->bd->bi_memsize);
|
lmb_add(&lmb, 0, gd->bd->bi_memsize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
board_lmb_reserve(&lmb);
|
||||||
|
|
||||||
/* get kernel image header, start address and length */
|
/* get kernel image header, start address and length */
|
||||||
os_hdr = get_kernel (cmdtp, flag, argc, argv,
|
os_hdr = get_kernel (cmdtp, flag, argc, argv,
|
||||||
&images, &os_data, &os_len);
|
&images, &os_data, &os_len);
|
||||||
|
|
132
common/image.c
132
common/image.c
|
@ -704,10 +704,9 @@ int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
|
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
|
||||||
/**
|
/**
|
||||||
* ramdisk_high - relocate init ramdisk
|
* ramdisk_high - relocate init ramdisk
|
||||||
|
* @lmb: pointer to lmb handle, will be used for memory mgmt
|
||||||
* @rd_data: ramdisk data start address
|
* @rd_data: ramdisk data start address
|
||||||
* @rd_len: ramdisk data length
|
* @rd_len: ramdisk data length
|
||||||
* @sp_limit: stack pointer limit (including BOOTMAPSZ)
|
|
||||||
* @sp: current stack pointer
|
|
||||||
* @initrd_start: pointer to a ulong variable, will hold final init ramdisk
|
* @initrd_start: pointer to a ulong variable, will hold final init ramdisk
|
||||||
* start address (after possible relocation)
|
* start address (after possible relocation)
|
||||||
* @initrd_end: pointer to a ulong variable, will hold final init ramdisk
|
* @initrd_end: pointer to a ulong variable, will hold final init ramdisk
|
||||||
|
@ -720,16 +719,16 @@ int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
* - initrd_start and initrd_end are set to final (after relocation) ramdisk
|
* - initrd_start and initrd_end are set to final (after relocation) ramdisk
|
||||||
* start/end addresses if ramdisk image start and len were provided
|
* start/end addresses if ramdisk image start and len were provided
|
||||||
* otherwise set initrd_start and initrd_end set to zeros
|
* otherwise set initrd_start and initrd_end set to zeros
|
||||||
* - returns new allc_current, next free address below BOOTMAPSZ
|
* - returns:
|
||||||
|
* 0 - success
|
||||||
|
* -1 - failure
|
||||||
*/
|
*/
|
||||||
ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len,
|
int ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
|
||||||
ulong sp_limit, ulong sp,
|
ulong *initrd_start, ulong *initrd_end)
|
||||||
ulong *initrd_start, ulong *initrd_end)
|
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
ulong initrd_high;
|
ulong initrd_high;
|
||||||
int initrd_copy_to_ram = 1;
|
int initrd_copy_to_ram = 1;
|
||||||
ulong new_alloc_current = alloc_current;
|
|
||||||
|
|
||||||
if ((s = getenv ("initrd_high")) != NULL) {
|
if ((s = getenv ("initrd_high")) != NULL) {
|
||||||
/* a value of "no" or a similar string will act like 0,
|
/* a value of "no" or a similar string will act like 0,
|
||||||
|
@ -743,12 +742,6 @@ ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len,
|
||||||
initrd_high = ~0;
|
initrd_high = ~0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_LOGBUFFER
|
|
||||||
/* Prevent initrd from overwriting logbuffer */
|
|
||||||
if (initrd_high < (gd->bd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD))
|
|
||||||
initrd_high = gd->bd->bi_memsize - LOGBUFF_LEN - LOGBUFF_OVERHEAD;
|
|
||||||
debug ("## Logbuffer at 0x%08lx ", gd->bd->bi_memsize - LOGBUFF_LEN);
|
|
||||||
#endif
|
|
||||||
debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
|
debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
|
||||||
initrd_high, initrd_copy_to_ram);
|
initrd_high, initrd_copy_to_ram);
|
||||||
|
|
||||||
|
@ -757,40 +750,17 @@ ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len,
|
||||||
debug (" in-place initrd\n");
|
debug (" in-place initrd\n");
|
||||||
*initrd_start = rd_data;
|
*initrd_start = rd_data;
|
||||||
*initrd_end = rd_data + rd_len;
|
*initrd_end = rd_data + rd_len;
|
||||||
|
lmb_reserve(lmb, rd_data, rd_len);
|
||||||
} else {
|
} else {
|
||||||
new_alloc_current = alloc_current - rd_len;
|
if (initrd_high)
|
||||||
*initrd_start = new_alloc_current;
|
*initrd_start = lmb_alloc_base(lmb, rd_len, 0x1000, initrd_high);
|
||||||
*initrd_start &= ~(4096 - 1); /* align on page */
|
else
|
||||||
|
*initrd_start = lmb_alloc(lmb, rd_len, 0x1000);
|
||||||
|
|
||||||
if (initrd_high) {
|
if (*initrd_start == 0) {
|
||||||
ulong nsp;
|
puts("ramdisk - allocation error\n");
|
||||||
|
goto error;
|
||||||
/*
|
|
||||||
* the inital ramdisk does not need to be within
|
|
||||||
* CFG_BOOTMAPSZ as it is not accessed until after
|
|
||||||
* the mm system is initialised.
|
|
||||||
*
|
|
||||||
* do the stack bottom calculation again and see if
|
|
||||||
* the initrd will fit just below the monitor stack
|
|
||||||
* bottom without overwriting the area allocated
|
|
||||||
* for command line args and board info.
|
|
||||||
*/
|
|
||||||
nsp = sp;
|
|
||||||
nsp -= 2048; /* just to be sure */
|
|
||||||
nsp &= ~0xF;
|
|
||||||
|
|
||||||
if (nsp > initrd_high) /* limit as specified */
|
|
||||||
nsp = initrd_high;
|
|
||||||
|
|
||||||
nsp -= rd_len;
|
|
||||||
nsp &= ~(4096 - 1); /* align on page */
|
|
||||||
|
|
||||||
if (nsp >= sp_limit) {
|
|
||||||
*initrd_start = nsp;
|
|
||||||
new_alloc_current = alloc_current;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
show_boot_progress (12);
|
show_boot_progress (12);
|
||||||
|
|
||||||
*initrd_end = *initrd_start + rd_len;
|
*initrd_end = *initrd_start + rd_len;
|
||||||
|
@ -808,56 +778,40 @@ ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len,
|
||||||
}
|
}
|
||||||
debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
|
debug (" ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
|
||||||
*initrd_start, *initrd_end);
|
*initrd_start, *initrd_end);
|
||||||
|
return 0;
|
||||||
|
|
||||||
return new_alloc_current;
|
error:
|
||||||
}
|
return -1;
|
||||||
|
|
||||||
/**
|
|
||||||
* get_boot_sp_limit - calculate stack pointer limit
|
|
||||||
* @sp: current stack pointer
|
|
||||||
*
|
|
||||||
* get_boot_sp_limit() takes current stack pointer adrress and calculates
|
|
||||||
* stack pointer limit, below which kernel boot data (cmdline, board info,
|
|
||||||
* etc.) will be allocated.
|
|
||||||
*
|
|
||||||
* returns:
|
|
||||||
* stack pointer limit
|
|
||||||
*/
|
|
||||||
ulong get_boot_sp_limit(ulong sp)
|
|
||||||
{
|
|
||||||
ulong sp_limit = sp;
|
|
||||||
|
|
||||||
sp_limit -= 2048; /* just to be sure */
|
|
||||||
|
|
||||||
/* make sure sp_limit is within kernel mapped space */
|
|
||||||
if (sp_limit > CFG_BOOTMAPSZ)
|
|
||||||
sp_limit = CFG_BOOTMAPSZ;
|
|
||||||
sp_limit &= ~0xF;
|
|
||||||
|
|
||||||
return sp_limit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_boot_cmdline - allocate and initialize kernel cmdline
|
* get_boot_cmdline - allocate and initialize kernel cmdline
|
||||||
* @alloc_current: current boot allocation address (counting down
|
* @lmb: pointer to lmb handle, will be used for memory mgmt
|
||||||
* from sp_limit)
|
|
||||||
* @cmd_start: pointer to a ulong variable, will hold cmdline start
|
* @cmd_start: pointer to a ulong variable, will hold cmdline start
|
||||||
* @cmd_end: pointer to a ulong variable, will hold cmdline end
|
* @cmd_end: pointer to a ulong variable, will hold cmdline end
|
||||||
|
* @bootmap_base: ulong variable, holds offset in physical memory to
|
||||||
|
* base of bootmap
|
||||||
*
|
*
|
||||||
* get_boot_cmdline() allocates space for kernel command line below
|
* get_boot_cmdline() allocates space for kernel command line below
|
||||||
* provided alloc_current address. If "bootargs" U-boot environemnt
|
* BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt
|
||||||
* variable is present its contents is copied to allocated kernel
|
* variable is present its contents is copied to allocated kernel
|
||||||
* command line.
|
* command line.
|
||||||
*
|
*
|
||||||
* returns:
|
* returns:
|
||||||
* alloc_current after cmdline allocation
|
* 0 - success
|
||||||
|
* -1 - failure
|
||||||
*/
|
*/
|
||||||
ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end)
|
int get_boot_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
|
||||||
|
ulong bootmap_base)
|
||||||
{
|
{
|
||||||
char *cmdline;
|
char *cmdline;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
cmdline = (char *)((alloc_current - CFG_BARGSIZE) & ~0xF);
|
cmdline = (char *)lmb_alloc_base(lmb, CFG_BARGSIZE, 0xf,
|
||||||
|
CFG_BOOTMAPSZ + bootmap_base);
|
||||||
|
|
||||||
|
if (cmdline == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if ((s = getenv("bootargs")) == NULL)
|
if ((s = getenv("bootargs")) == NULL)
|
||||||
s = "";
|
s = "";
|
||||||
|
@ -869,25 +823,31 @@ ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end)
|
||||||
|
|
||||||
debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
|
debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
|
||||||
|
|
||||||
return (ulong)cmdline;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_boot_kbd - allocate and initialize kernel copy of board info
|
* get_boot_kbd - allocate and initialize kernel copy of board info
|
||||||
* @alloc_current: current boot allocation address (counting down
|
* @lmb: pointer to lmb handle, will be used for memory mgmt
|
||||||
* from sp_limit)
|
|
||||||
* @kbd: double pointer to board info data
|
* @kbd: double pointer to board info data
|
||||||
|
* @bootmap_base: ulong variable, holds offset in physical memory to
|
||||||
|
* base of bootmap
|
||||||
*
|
*
|
||||||
* get_boot_kbd() - allocates space for kernel copy of board info data.
|
* get_boot_kbd() allocates space for kernel copy of board info data below
|
||||||
* Space is allocated below provided alloc_current address and kernel
|
* BOOTMAPSZ + bootmap_base address and kernel board info is initialized with
|
||||||
* board info is initialized with the current u-boot board info data.
|
* the current u-boot board info data.
|
||||||
*
|
*
|
||||||
* returns:
|
* returns:
|
||||||
* alloc_current after kbd allocation
|
* 0 - success
|
||||||
|
* -1 - failure
|
||||||
*/
|
*/
|
||||||
ulong get_boot_kbd (ulong alloc_current, bd_t **kbd)
|
int get_boot_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
|
||||||
{
|
{
|
||||||
*kbd = (bd_t *) (((ulong)alloc_current - sizeof(bd_t)) & ~0xF);
|
*kbd = (bd_t *)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
|
||||||
|
CFG_BOOTMAPSZ + bootmap_base);
|
||||||
|
if (*kbd == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
**kbd = *(gd->bd);
|
**kbd = *(gd->bd);
|
||||||
|
|
||||||
debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);
|
debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);
|
||||||
|
@ -896,7 +856,7 @@ ulong get_boot_kbd (ulong alloc_current, bd_t **kbd)
|
||||||
do_bdinfo(NULL, 0, 0, NULL);
|
do_bdinfo(NULL, 0, 0, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (ulong)*kbd;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PPC || CONFIG_M68K */
|
#endif /* CONFIG_PPC || CONFIG_M68K */
|
||||||
|
|
||||||
|
|
|
@ -391,13 +391,11 @@ int get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
ulong *rd_start, ulong *rd_end);
|
ulong *rd_start, ulong *rd_end);
|
||||||
|
|
||||||
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
|
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
|
||||||
ulong ramdisk_high (ulong alloc_current, ulong rd_data, ulong rd_len,
|
int ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
|
||||||
ulong sp_limit, ulong sp,
|
ulong *initrd_start, ulong *initrd_end);
|
||||||
ulong *initrd_start, ulong *initrd_end);
|
int get_boot_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
|
||||||
|
ulong bootmap_base);
|
||||||
ulong get_boot_sp_limit (ulong sp);
|
int get_boot_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base);
|
||||||
ulong get_boot_cmdline (ulong alloc_current, ulong *cmd_start, ulong *cmd_end);
|
|
||||||
ulong get_boot_kbd (ulong alloc_current, bd_t **kbd);
|
|
||||||
#endif /* CONFIG_PPC || CONFIG_M68K */
|
#endif /* CONFIG_PPC || CONFIG_M68K */
|
||||||
|
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
|
|
|
@ -50,16 +50,18 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag,
|
||||||
int argc, char *argv[],
|
int argc, char *argv[],
|
||||||
bootm_headers_t *images)
|
bootm_headers_t *images)
|
||||||
{
|
{
|
||||||
ulong sp, sp_limit, alloc_current;
|
ulong sp;
|
||||||
|
|
||||||
ulong rd_data_start, rd_data_end, rd_len;
|
ulong rd_data_start, rd_data_end, rd_len;
|
||||||
ulong initrd_start, initrd_end;
|
ulong initrd_start, initrd_end;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ulong cmd_start, cmd_end;
|
ulong cmd_start, cmd_end;
|
||||||
|
ulong bootmap_base = 0;
|
||||||
bd_t *kbd;
|
bd_t *kbd;
|
||||||
ulong ep = 0;
|
ulong ep = 0;
|
||||||
void (*kernel) (bd_t *, ulong, ulong, ulong, ulong);
|
void (*kernel) (bd_t *, ulong, ulong, ulong, ulong);
|
||||||
|
struct lmb *lmb = images->lmb;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Booting a (Linux) kernel image
|
* Booting a (Linux) kernel image
|
||||||
|
@ -73,14 +75,23 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag,
|
||||||
sp = get_sp();
|
sp = get_sp();
|
||||||
debug ("## Current stack ends at 0x%08lx ", sp);
|
debug ("## Current stack ends at 0x%08lx ", sp);
|
||||||
|
|
||||||
alloc_current = sp_limit = get_boot_sp_limit(sp);
|
/* adjust sp by 1K to be safe */
|
||||||
debug ("=> set upper limit to 0x%08lx\n", sp_limit);
|
sp -= 1024;
|
||||||
|
lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + gd->ram_size - sp));
|
||||||
|
|
||||||
/* allocate space and init command line */
|
/* allocate space and init command line */
|
||||||
alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end);
|
ret = get_boot_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base);
|
||||||
|
if (ret) {
|
||||||
|
puts("ERROR with allocation of cmdline\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* allocate space for kernel copy of board info */
|
/* allocate space for kernel copy of board info */
|
||||||
alloc_current = get_boot_kbd (alloc_current, &kbd);
|
ret = get_boot_kbd (lmb, &kbd, bootmap_base);
|
||||||
|
if (ret) {
|
||||||
|
puts("ERROR with allocation of kernel bd\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
set_clocks_in_mhz(kbd);
|
set_clocks_in_mhz(kbd);
|
||||||
|
|
||||||
/* find kernel entry point */
|
/* find kernel entry point */
|
||||||
|
@ -105,8 +116,9 @@ void do_bootm_linux(cmd_tbl_t * cmdtp, int flag,
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
rd_len = rd_data_end - rd_data_start;
|
rd_len = rd_data_end - rd_data_start;
|
||||||
alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len,
|
ret = ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end);
|
||||||
sp_limit, get_sp (), &initrd_start, &initrd_end);
|
if (ret)
|
||||||
|
goto error;
|
||||||
|
|
||||||
debug("## Transferring control to Linux (at address %08lx) ...\n",
|
debug("## Transferring control to Linux (at address %08lx) ...\n",
|
||||||
(ulong) kernel);
|
(ulong) kernel);
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
static void fdt_error (const char *msg);
|
static void fdt_error (const char *msg);
|
||||||
static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
static int get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
|
bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
|
||||||
static ulong fdt_relocate (ulong alloc_current,
|
static int fdt_relocate (struct lmb *lmb, ulong bootmap_base,
|
||||||
cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
char **of_flat_tree, ulong *of_size);
|
char **of_flat_tree, ulong *of_size);
|
||||||
#endif
|
#endif
|
||||||
|
@ -55,6 +55,7 @@ static ulong fdt_relocate (ulong alloc_current,
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
|
||||||
|
extern ulong get_effective_memsize(void);
|
||||||
static ulong get_sp (void);
|
static ulong get_sp (void);
|
||||||
static void set_clocks_in_mhz (bd_t *kbd);
|
static void set_clocks_in_mhz (bd_t *kbd);
|
||||||
|
|
||||||
|
@ -62,22 +63,25 @@ void __attribute__((noinline))
|
||||||
do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
bootm_headers_t *images)
|
bootm_headers_t *images)
|
||||||
{
|
{
|
||||||
ulong sp, sp_limit, alloc_current;
|
ulong sp;
|
||||||
|
|
||||||
ulong initrd_start, initrd_end;
|
ulong initrd_start, initrd_end;
|
||||||
ulong rd_data_start, rd_data_end, rd_len;
|
ulong rd_data_start, rd_data_end, rd_len;
|
||||||
|
|
||||||
ulong cmd_start, cmd_end;
|
ulong cmd_start, cmd_end, bootmap_base;
|
||||||
bd_t *kbd;
|
bd_t *kbd;
|
||||||
ulong ep = 0;
|
ulong ep = 0;
|
||||||
void (*kernel)(bd_t *, ulong, ulong, ulong, ulong);
|
void (*kernel)(bd_t *, ulong, ulong, ulong, ulong);
|
||||||
int ret;
|
int ret;
|
||||||
ulong of_size = 0;
|
ulong of_size = 0;
|
||||||
|
struct lmb *lmb = images->lmb;
|
||||||
|
|
||||||
#if defined(CONFIG_OF_LIBFDT)
|
#if defined(CONFIG_OF_LIBFDT)
|
||||||
char *of_flat_tree = NULL;
|
char *of_flat_tree = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bootmap_base = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Booting a (Linux) kernel image
|
* Booting a (Linux) kernel image
|
||||||
*
|
*
|
||||||
|
@ -90,8 +94,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
sp = get_sp();
|
sp = get_sp();
|
||||||
debug ("## Current stack ends at 0x%08lx ", sp);
|
debug ("## Current stack ends at 0x%08lx ", sp);
|
||||||
|
|
||||||
alloc_current = sp_limit = get_boot_sp_limit(sp);
|
/* adjust sp by 1K to be safe */
|
||||||
debug ("=> set upper limit to 0x%08lx\n", sp_limit);
|
sp -= 1024;
|
||||||
|
lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + get_effective_memsize() - sp));
|
||||||
|
|
||||||
#if defined(CONFIG_OF_LIBFDT)
|
#if defined(CONFIG_OF_LIBFDT)
|
||||||
/* find flattened device tree */
|
/* find flattened device tree */
|
||||||
|
@ -103,10 +108,18 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
|
|
||||||
if (!of_size) {
|
if (!of_size) {
|
||||||
/* allocate space and init command line */
|
/* allocate space and init command line */
|
||||||
alloc_current = get_boot_cmdline (alloc_current, &cmd_start, &cmd_end);
|
ret = get_boot_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base);
|
||||||
|
if (ret) {
|
||||||
|
puts("ERROR with allocation of cmdline\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
/* allocate space for kernel copy of board info */
|
/* allocate space for kernel copy of board info */
|
||||||
alloc_current = get_boot_kbd (alloc_current, &kbd);
|
ret = get_boot_kbd (lmb, &kbd, bootmap_base);
|
||||||
|
if (ret) {
|
||||||
|
puts("ERROR with allocation of kernel bd\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
set_clocks_in_mhz(kbd);
|
set_clocks_in_mhz(kbd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,8 +147,8 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
rd_len = rd_data_end - rd_data_start;
|
rd_len = rd_data_end - rd_data_start;
|
||||||
|
|
||||||
#if defined(CONFIG_OF_LIBFDT)
|
#if defined(CONFIG_OF_LIBFDT)
|
||||||
alloc_current = fdt_relocate (alloc_current,
|
ret = fdt_relocate (lmb, bootmap_base,
|
||||||
cmdtp, flag, argc, argv, &of_flat_tree, &of_size);
|
cmdtp, flag, argc, argv, &of_flat_tree, &of_size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add the chosen node if it doesn't exist, add the env and bd_t
|
* Add the chosen node if it doesn't exist, add the env and bd_t
|
||||||
|
@ -166,8 +179,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_OF_LIBFDT */
|
#endif /* CONFIG_OF_LIBFDT */
|
||||||
|
|
||||||
alloc_current = ramdisk_high (alloc_current, rd_data_start, rd_len,
|
ret = ramdisk_high (lmb, rd_data_start, rd_len, &initrd_start, &initrd_end);
|
||||||
sp_limit, get_sp (), &initrd_start, &initrd_end);
|
if (ret)
|
||||||
|
goto error;
|
||||||
|
|
||||||
#if defined(CONFIG_OF_LIBFDT)
|
#if defined(CONFIG_OF_LIBFDT)
|
||||||
/* fixup the initrd now that we know where it should be */
|
/* fixup the initrd now that we know where it should be */
|
||||||
|
@ -488,17 +502,17 @@ error:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ulong fdt_relocate (ulong alloc_current,
|
static int fdt_relocate (struct lmb *lmb, ulong bootmap_base,
|
||||||
cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
|
||||||
char **of_flat_tree, ulong *of_size)
|
char **of_flat_tree, ulong *of_size)
|
||||||
{
|
{
|
||||||
char *fdt_blob = *of_flat_tree;
|
char *fdt_blob = *of_flat_tree;
|
||||||
ulong relocate = 0;
|
ulong relocate = 0;
|
||||||
ulong new_alloc_current;
|
ulong of_len = 0;
|
||||||
|
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
if (*of_size == 0)
|
if (*of_size == 0)
|
||||||
return alloc_current;
|
return 0;
|
||||||
|
|
||||||
if (fdt_check_header (fdt_blob) != 0) {
|
if (fdt_check_header (fdt_blob) != 0) {
|
||||||
fdt_error ("image is not a fdt");
|
fdt_error ("image is not a fdt");
|
||||||
|
@ -511,25 +525,28 @@ static ulong fdt_relocate (ulong alloc_current,
|
||||||
relocate = 1;
|
relocate = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CFG_BOOTMAPSZ
|
|
||||||
/*
|
/*
|
||||||
* The blob must be within CFG_BOOTMAPSZ,
|
* The blob must be within CFG_BOOTMAPSZ,
|
||||||
* so we flag it to be copied if it is not.
|
* so we flag it to be copied if it is not.
|
||||||
*/
|
*/
|
||||||
if (fdt_blob >= (char *)CFG_BOOTMAPSZ)
|
if (fdt_blob >= (char *)CFG_BOOTMAPSZ)
|
||||||
relocate = 1;
|
relocate = 1;
|
||||||
#endif
|
|
||||||
|
of_len = be32_to_cpu (fdt_totalsize (fdt));
|
||||||
|
|
||||||
/* move flattend device tree if needed */
|
/* move flattend device tree if needed */
|
||||||
if (relocate) {
|
if (relocate) {
|
||||||
int err;
|
int err;
|
||||||
ulong of_start, of_len;
|
ulong of_start;
|
||||||
|
|
||||||
of_len = *of_size;
|
|
||||||
|
|
||||||
/* position on a 4K boundary before the alloc_current */
|
/* position on a 4K boundary before the alloc_current */
|
||||||
of_start = alloc_current - of_len;
|
of_start = lmb_alloc_base(lmb, of_len, 0x1000,
|
||||||
of_start &= ~(4096 - 1); /* align on page */
|
(CFG_BOOTMAPSZ + bootmap_base));
|
||||||
|
|
||||||
|
if (of_start == 0) {
|
||||||
|
puts("device tree - allocation error\n");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
|
debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
|
||||||
(ulong)fdt_blob, (ulong)fdt_blob + of_len - 1,
|
(ulong)fdt_blob, (ulong)fdt_blob + of_len - 1,
|
||||||
|
@ -546,16 +563,14 @@ static ulong fdt_relocate (ulong alloc_current,
|
||||||
puts ("OK\n");
|
puts ("OK\n");
|
||||||
|
|
||||||
*of_flat_tree = (char *)of_start;
|
*of_flat_tree = (char *)of_start;
|
||||||
new_alloc_current = of_start;
|
|
||||||
} else {
|
} else {
|
||||||
*of_flat_tree = fdt_blob;
|
*of_flat_tree = fdt_blob;
|
||||||
new_alloc_current = alloc_current;
|
lmb_reserve(lmb, (ulong)fdt, of_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_alloc_current;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
do_reset (cmdtp, flag, argc, argv);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue