[POWERPC] More bootwrapper reorganization
More reorganization of the bootwrapper: - Add dtb section to zImage - ft_init now called by platform_init - Pack a flat dt before calling kernel - Remove size parameter from free - printf only calls console_ops.write it its not NULL - Some cleanup Signed-off-by: Mark A. Greer <mgreer@mvista.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
b0a779debd
commit
c888554bf9
7 changed files with 34 additions and 42 deletions
|
@ -27,6 +27,8 @@ extern char _vmlinux_start[];
|
||||||
extern char _vmlinux_end[];
|
extern char _vmlinux_end[];
|
||||||
extern char _initrd_start[];
|
extern char _initrd_start[];
|
||||||
extern char _initrd_end[];
|
extern char _initrd_end[];
|
||||||
|
extern char _dtb_start[];
|
||||||
|
extern char _dtb_end[];
|
||||||
|
|
||||||
struct addr_range {
|
struct addr_range {
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
@ -250,10 +252,6 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2)
|
||||||
flush_cache((void *)vmlinux.addr, vmlinux.size);
|
flush_cache((void *)vmlinux.addr, vmlinux.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__ ((weak)) ft_init(void *dt_blob)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A buffer that may be edited by tools operating on a zImage binary so as to
|
/* A buffer that may be edited by tools operating on a zImage binary so as to
|
||||||
* edit the command line passed to vmlinux (by setting /chosen/bootargs).
|
* edit the command line passed to vmlinux (by setting /chosen/bootargs).
|
||||||
* The buffer is put in it's own section so that tools may locate it easier.
|
* The buffer is put in it's own section so that tools may locate it easier.
|
||||||
|
@ -285,19 +283,12 @@ static void set_cmdline(char *buf)
|
||||||
setprop(devp, "bootargs", buf, strlen(buf) + 1);
|
setprop(devp, "bootargs", buf, strlen(buf) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Section where ft can be tacked on after zImage is built */
|
|
||||||
union blobspace {
|
|
||||||
struct boot_param_header hdr;
|
|
||||||
char space[8*1024];
|
|
||||||
} dt_blob __attribute__((__section__("__builtin_ft")));
|
|
||||||
|
|
||||||
struct platform_ops platform_ops;
|
struct platform_ops platform_ops;
|
||||||
struct dt_ops dt_ops;
|
struct dt_ops dt_ops;
|
||||||
struct console_ops console_ops;
|
struct console_ops console_ops;
|
||||||
|
|
||||||
void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
||||||
{
|
{
|
||||||
int have_dt = 0;
|
|
||||||
kernel_entry_t kentry;
|
kernel_entry_t kentry;
|
||||||
char cmdline[COMMAND_LINE_SIZE];
|
char cmdline[COMMAND_LINE_SIZE];
|
||||||
|
|
||||||
|
@ -306,15 +297,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
||||||
memset(&dt_ops, 0, sizeof(dt_ops));
|
memset(&dt_ops, 0, sizeof(dt_ops));
|
||||||
memset(&console_ops, 0, sizeof(console_ops));
|
memset(&console_ops, 0, sizeof(console_ops));
|
||||||
|
|
||||||
/* Override the dt_ops and device tree if there was an flat dev
|
if (platform_init(promptr, _dtb_start, _dtb_end))
|
||||||
* tree attached to the zImage.
|
|
||||||
*/
|
|
||||||
if (dt_blob.hdr.magic == OF_DT_HEADER) {
|
|
||||||
have_dt = 1;
|
|
||||||
ft_init(&dt_blob);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (platform_init(promptr))
|
|
||||||
exit();
|
exit();
|
||||||
if (console_ops.open && (console_ops.open() < 0))
|
if (console_ops.open && (console_ops.open() < 0))
|
||||||
exit();
|
exit();
|
||||||
|
@ -342,8 +325,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
||||||
console_ops.close();
|
console_ops.close();
|
||||||
|
|
||||||
kentry = (kernel_entry_t) vmlinux.addr;
|
kentry = (kernel_entry_t) vmlinux.addr;
|
||||||
if (have_dt)
|
if (_dtb_end > _dtb_start) {
|
||||||
|
dt_ops.ft_pack();
|
||||||
kentry(dt_ops.ft_addr(), 0, NULL);
|
kentry(dt_ops.ft_addr(), 0, NULL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
/* XXX initrd addr/size should be passed in properties */
|
/* XXX initrd addr/size should be passed in properties */
|
||||||
kentry(a1, a2, promptr);
|
kentry(a1, a2, promptr);
|
||||||
|
|
|
@ -256,24 +256,18 @@ static void of_console_write(char *buf, int len)
|
||||||
call_prom("write", 3, 1, of_stdout_handle, buf, len);
|
call_prom("write", 3, 1, of_stdout_handle, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int platform_init(void *promptr)
|
int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end)
|
||||||
{
|
{
|
||||||
platform_ops.fixups = NULL;
|
|
||||||
platform_ops.image_hdr = of_image_hdr;
|
platform_ops.image_hdr = of_image_hdr;
|
||||||
platform_ops.malloc = of_try_claim;
|
platform_ops.malloc = of_try_claim;
|
||||||
platform_ops.free = NULL;
|
|
||||||
platform_ops.exit = of_exit;
|
platform_ops.exit = of_exit;
|
||||||
|
|
||||||
dt_ops.finddevice = of_finddevice;
|
dt_ops.finddevice = of_finddevice;
|
||||||
dt_ops.getprop = of_getprop;
|
dt_ops.getprop = of_getprop;
|
||||||
dt_ops.setprop = of_setprop;
|
dt_ops.setprop = of_setprop;
|
||||||
dt_ops.translate_addr = NULL;
|
|
||||||
|
|
||||||
console_ops.open = of_console_open;
|
console_ops.open = of_console_open;
|
||||||
console_ops.write = of_console_write;
|
console_ops.write = of_console_write;
|
||||||
console_ops.edit_cmdline = NULL;
|
|
||||||
console_ops.close = NULL;
|
|
||||||
console_ops.data = NULL;
|
|
||||||
|
|
||||||
prom = (int (*)(void *))promptr;
|
prom = (int (*)(void *))promptr;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -22,7 +22,8 @@ struct platform_ops {
|
||||||
void (*fixups)(void);
|
void (*fixups)(void);
|
||||||
void (*image_hdr)(const void *);
|
void (*image_hdr)(const void *);
|
||||||
void * (*malloc)(u32 size);
|
void * (*malloc)(u32 size);
|
||||||
void (*free)(void *ptr, u32 size);
|
void (*free)(void *ptr);
|
||||||
|
void * (*realloc)(void *ptr, unsigned long size);
|
||||||
void (*exit)(void);
|
void (*exit)(void);
|
||||||
};
|
};
|
||||||
extern struct platform_ops platform_ops;
|
extern struct platform_ops platform_ops;
|
||||||
|
@ -30,12 +31,11 @@ extern struct platform_ops platform_ops;
|
||||||
/* Device Tree operations */
|
/* Device Tree operations */
|
||||||
struct dt_ops {
|
struct dt_ops {
|
||||||
void * (*finddevice)(const char *name);
|
void * (*finddevice)(const char *name);
|
||||||
int (*getprop)(const void *node, const char *name, void *buf,
|
int (*getprop)(const void *phandle, const char *name, void *buf,
|
||||||
const int buflen);
|
const int buflen);
|
||||||
int (*setprop)(const void *node, const char *name,
|
int (*setprop)(const void *phandle, const char *name,
|
||||||
const void *buf, const int buflen);
|
const void *buf, const int buflen);
|
||||||
u64 (*translate_addr)(const char *path, const u32 *in_addr,
|
void (*ft_pack)(void);
|
||||||
const u32 addr_len);
|
|
||||||
unsigned long (*ft_addr)(void);
|
unsigned long (*ft_addr)(void);
|
||||||
};
|
};
|
||||||
extern struct dt_ops dt_ops;
|
extern struct dt_ops dt_ops;
|
||||||
|
@ -59,10 +59,13 @@ struct serial_console_data {
|
||||||
void (*close)(void);
|
void (*close)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int platform_init(void *promptr);
|
int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end);
|
||||||
extern void simple_alloc_init(void);
|
int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
|
||||||
extern void ft_init(void *dt_blob);
|
int serial_console_init(void);
|
||||||
extern int serial_console_init(void);
|
int ns16550_console_init(void *devp, struct serial_console_data *scdp);
|
||||||
|
void *simple_alloc_init(char *base, u32 heap_size, u32 granularity,
|
||||||
|
u32 max_allocs);
|
||||||
|
|
||||||
|
|
||||||
static inline void *finddevice(const char *name)
|
static inline void *finddevice(const char *name)
|
||||||
{
|
{
|
||||||
|
@ -84,10 +87,10 @@ static inline void *malloc(u32 size)
|
||||||
return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
|
return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void free(void *ptr, u32 size)
|
static inline void free(void *ptr)
|
||||||
{
|
{
|
||||||
if (platform_ops.free)
|
if (platform_ops.free)
|
||||||
platform_ops.free(ptr, size);
|
platform_ops.free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void exit(void)
|
static inline void exit(void)
|
||||||
|
|
|
@ -320,6 +320,7 @@ printf(const char *fmt, ...)
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
n = vsprintf(sprint_buf, fmt, args);
|
n = vsprintf(sprint_buf, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
console_ops.write(sprint_buf, n);
|
if (console_ops.write)
|
||||||
|
console_ops.write(sprint_buf, n);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,11 +179,11 @@ if [ -z "$cacheit" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$initrd" ]; then
|
if [ -n "$initrd" ]; then
|
||||||
addsec $tmp "$initrd" initrd
|
addsec $tmp "$initrd" $isection
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "$dtb" ]; then
|
if [ -n "$dtb" ]; then
|
||||||
addsec $tmp "$dtb" dtb
|
addsec $tmp "$dtb" .kernel:dtb
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$platform" != "miboot" ]; then
|
if [ "$platform" != "miboot" ]; then
|
||||||
|
|
|
@ -21,6 +21,10 @@ SECTIONS
|
||||||
*(.got2)
|
*(.got2)
|
||||||
__got2_end = .;
|
__got2_end = .;
|
||||||
|
|
||||||
|
_dtb_start = .;
|
||||||
|
*(.kernel:dtb)
|
||||||
|
_dtb_end = .;
|
||||||
|
|
||||||
_vmlinux_start = .;
|
_vmlinux_start = .;
|
||||||
*(.kernel:vmlinux.strip)
|
*(.kernel:vmlinux.strip)
|
||||||
_vmlinux_end = .;
|
_vmlinux_end = .;
|
||||||
|
|
|
@ -21,6 +21,11 @@ SECTIONS
|
||||||
__got2_end = .;
|
__got2_end = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
. = ALIGN(8);
|
||||||
|
_dtb_start = .;
|
||||||
|
.kernel:dtb : { *(.kernel:dtb) }
|
||||||
|
_dtb_end = .;
|
||||||
|
|
||||||
. = ALIGN(4096);
|
. = ALIGN(4096);
|
||||||
_vmlinux_start = .;
|
_vmlinux_start = .;
|
||||||
.kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) }
|
.kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) }
|
||||||
|
|
Loading…
Reference in a new issue