use memmap() to save one memcpy call in bootm
This commit is contained in:
parent
665291e693
commit
8881fb7984
|
@ -67,10 +67,10 @@ static struct tag *params;
|
|||
#endif
|
||||
|
||||
|
||||
int do_bootm_linux(image_header_t *os_header, image_header_t *initrd)
|
||||
int do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd)
|
||||
{
|
||||
ulong initrd_start, initrd_end;
|
||||
void (*theKernel)(int zero, int arch, uint params);
|
||||
image_header_t *os_header = &os_handle->header;
|
||||
#ifdef CONFIG_CMDLINE_TAG
|
||||
const char *commandline = getenv ("bootargs");
|
||||
#endif
|
||||
|
@ -78,7 +78,9 @@ int do_bootm_linux(image_header_t *os_header, image_header_t *initrd)
|
|||
printf("Multifile images not handled at the moment\n");
|
||||
return -1;
|
||||
}
|
||||
printf("os header: 0x%p ep: %\n", os_header, os_header + 1);
|
||||
|
||||
printf("commandline: %s\n", commandline);
|
||||
|
||||
theKernel = (void (*)(int, int, uint))ntohl((unsigned long)(os_header->ih_ep));
|
||||
|
||||
debug ("## Transferring control to Linux (at address %08lx) ...\n",
|
||||
|
@ -113,7 +115,7 @@ printf("os header: 0x%p ep: %\n", os_header, os_header + 1);
|
|||
#endif
|
||||
setup_end_tag ();
|
||||
#endif
|
||||
if (relocate_image(os_header, (void *)ntohl(os_header->ih_load)))
|
||||
if (relocate_image(os_handle, (void *)ntohl(os_header->ih_load)))
|
||||
return -1;
|
||||
|
||||
/* we assume that the kernel is in place */
|
||||
|
|
|
@ -17,7 +17,7 @@ extern bd_t *bd;
|
|||
#define SHOW_BOOT_PROGRESS(x)
|
||||
|
||||
int
|
||||
do_bootm_linux(image_header_t *os_header, image_header_t *initrd_header, const char *oftree)
|
||||
do_bootm_linux(struct image_handle *os_handle, struct image_handle *initrd_handle, const char *oftree)
|
||||
{
|
||||
ulong sp;
|
||||
ulong initrd_end = 0;
|
||||
|
@ -30,18 +30,23 @@ do_bootm_linux(image_header_t *os_header, image_header_t *initrd_header, const c
|
|||
void (*kernel)(bd_t *, ulong, ulong, ulong, ulong);
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
char *of_flat_tree = NULL;
|
||||
// ulong of_data = 0;
|
||||
#endif
|
||||
image_header_t *os_header = &os_handle->header;
|
||||
image_header_t *initrd_header = NULL;
|
||||
void *os_data = NULL;
|
||||
void *initrd_data = NULL;
|
||||
void *of_data = NULL;
|
||||
struct image_handle *oftree_handle;
|
||||
unsigned long os_len, initrd_len;
|
||||
|
||||
if (initrd_handle)
|
||||
initrd_header = &initrd_handle->header;
|
||||
|
||||
printf("entering %s: os_header: %p initrd_header: %p oftree: %p\n",
|
||||
__FUNCTION__, os_header, initrd_header, oftree);
|
||||
|
||||
if (os_header->ih_type == IH_TYPE_MULTI) {
|
||||
unsigned long *data = (unsigned long *)(os_header + 1);
|
||||
unsigned long *data = (unsigned long *)(os_handle->data);
|
||||
unsigned long len1 = 0, len2 = 0;
|
||||
|
||||
if (!*data) {
|
||||
|
@ -83,22 +88,21 @@ do_bootm_linux(image_header_t *os_header, image_header_t *initrd_header, const c
|
|||
initrd_len = len1;
|
||||
}
|
||||
} else {
|
||||
os_data = (void *)(os_header + 1);
|
||||
os_data = os_handle->data;
|
||||
printf("set os_data to %p\n", os_data);
|
||||
}
|
||||
|
||||
if (initrd_header)
|
||||
initrd_data = (void *)(initrd_header + 1);
|
||||
if (initrd_handle)
|
||||
initrd_data = initrd_handle->data;
|
||||
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
if (oftree) {
|
||||
image_header_t *oftree_header;
|
||||
/* The oftree can be given either as an uboot image or as a
|
||||
* binary blob. First try to read it as an image.
|
||||
*/
|
||||
oftree_header = map_image(oftree, 1);
|
||||
if (oftree_header) {
|
||||
of_data = (void *)(oftree_header + 1);
|
||||
oftree_handle = map_image(oftree, 1);
|
||||
if (oftree_handle) {
|
||||
of_data = oftree_handle->data;
|
||||
} else {
|
||||
of_data = read_file(oftree);
|
||||
if (!of_data) {
|
||||
|
@ -197,7 +201,7 @@ do_bootm_linux(image_header_t *os_header, image_header_t *initrd_header, const c
|
|||
|
||||
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))ntohl(os_header->ih_ep); /* FIXME */
|
||||
|
||||
if (relocate_image(os_header, (void *)ntohl(os_header->ih_load)))
|
||||
if (relocate_image(os_handle, (void *)ntohl(os_header->ih_load)))
|
||||
return -1;
|
||||
|
||||
#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
|
||||
|
|
|
@ -167,10 +167,11 @@ print_type (image_header_t *hdr)
|
|||
}
|
||||
#endif
|
||||
|
||||
int relocate_image(image_header_t *hdr, void *load_address)
|
||||
int relocate_image(struct image_handle *handle, void *load_address)
|
||||
{
|
||||
unsigned long data = (unsigned long)(hdr + 1);
|
||||
image_header_t *hdr = &handle->header;
|
||||
unsigned long len = ntohl(hdr->ih_size);
|
||||
unsigned long data = (unsigned long)(handle->data);
|
||||
|
||||
#if defined CONFIG_CMD_BOOTM_ZLIB || defined CONFIG_CMD_BOOTM_BZLIB
|
||||
uint unc_len = CFG_BOOTM_LEN;
|
||||
|
@ -215,12 +216,12 @@ int relocate_image(image_header_t *hdr, void *load_address)
|
|||
return 0;
|
||||
}
|
||||
|
||||
image_header_t *map_image(const char *filename, int verify)
|
||||
struct image_handle *map_image(const char *filename, int verify)
|
||||
{
|
||||
int fd;
|
||||
uint32_t checksum, len;
|
||||
void *data;
|
||||
image_header_t *header, *tmp_header;
|
||||
struct image_handle *handle;
|
||||
image_header_t *header;
|
||||
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
|
@ -228,7 +229,8 @@ image_header_t *map_image(const char *filename, int verify)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
header = xmalloc(sizeof(image_header_t));
|
||||
handle = xzalloc(sizeof(struct image_handle));
|
||||
header = &handle->header;
|
||||
|
||||
if (read(fd, header, sizeof(image_header_t)) < 0) {
|
||||
printf("could not read: %s\n", errno_str());
|
||||
|
@ -249,38 +251,47 @@ image_header_t *map_image(const char *filename, int verify)
|
|||
}
|
||||
len = ntohl(header->ih_size);
|
||||
|
||||
tmp_header = realloc(header, sizeof(image_header_t) + len);
|
||||
if (!tmp_header)
|
||||
goto err_out;
|
||||
header = tmp_header;
|
||||
|
||||
data = (void *)(header + 1);
|
||||
|
||||
if (read(fd, data, len) < 0) {
|
||||
printf("could not read: %s\n", errno_str());
|
||||
goto err_out;
|
||||
handle->data = memmap(fd, PROT_READ);
|
||||
if (!handle) {
|
||||
handle->data = xmalloc(len);
|
||||
handle->flags = IH_MALLOC;
|
||||
if (read(fd, &handle->data, len) < 0) {
|
||||
printf("could not read: %s\n", errno_str());
|
||||
goto err_out;
|
||||
}
|
||||
} else {
|
||||
handle->data = (void *)((unsigned long)handle->data + sizeof(image_header_t));
|
||||
}
|
||||
|
||||
if (verify) {
|
||||
puts (" Verifying Checksum ... ");
|
||||
if (crc32 (0, data, len) != ntohl(header->ih_dcrc)) {
|
||||
if (crc32 (0, handle->data, len) != ntohl(header->ih_dcrc)) {
|
||||
printf ("Bad Data CRC\n");
|
||||
goto err_out;
|
||||
}
|
||||
puts ("OK\n");
|
||||
}
|
||||
|
||||
print_image_hdr (header);
|
||||
print_image_hdr(header);
|
||||
|
||||
close(fd);
|
||||
|
||||
return header;
|
||||
return handle;
|
||||
err_out:
|
||||
close(fd);
|
||||
free(header);
|
||||
if (handle->flags & IH_MALLOC)
|
||||
free(handle->data);
|
||||
free(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void unmap_image(struct image_handle *handle)
|
||||
{
|
||||
if (handle->flags & IH_MALLOC)
|
||||
free(handle->data);
|
||||
free(handle);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
#define OPT_OFTREE "o:"
|
||||
#else
|
||||
|
@ -295,10 +306,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
char *initrd = NULL;
|
||||
image_header_t *os_header;
|
||||
image_header_t *initrd_header = NULL;
|
||||
struct image_handle *os_handle, *initrd_handle = NULL;
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
char *oftree = NULL;
|
||||
#endif
|
||||
int ignore_load_address = 0;
|
||||
|
||||
getopt_reset();
|
||||
|
||||
|
@ -310,9 +321,6 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
case 'n':
|
||||
verify = 0;
|
||||
break;
|
||||
case 'i':
|
||||
ignore_load_address = 1;
|
||||
break;
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
case 'o':
|
||||
oftree = optarg;
|
||||
|
@ -328,19 +336,22 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
return 1;
|
||||
}
|
||||
|
||||
os_header = map_image(argv[optind], verify);
|
||||
if (!os_header)
|
||||
os_handle = map_image(argv[optind], verify);
|
||||
if (!os_handle)
|
||||
return 1;
|
||||
|
||||
os_header = &os_handle->header;
|
||||
|
||||
if (os_header->ih_arch != IH_CPU) {
|
||||
printf ("Unsupported Architecture 0x%x\n", os_header->ih_arch);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (initrd) {
|
||||
initrd_header = map_image(initrd, verify);
|
||||
if (!initrd_header)
|
||||
initrd_handle = map_image(initrd, verify);
|
||||
if (!initrd_handle)
|
||||
goto err_out;
|
||||
initrd_header = &initrd_handle->header;
|
||||
}
|
||||
#if 0
|
||||
switch (os_header->ih_type) {
|
||||
|
@ -383,9 +394,9 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
fixup_silent_linux();
|
||||
#endif
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
do_bootm_linux(os_header, initrd_header, oftree);
|
||||
do_bootm_linux(os_handle, initrd_handle, oftree);
|
||||
#else
|
||||
do_bootm_linux(os_header, initrd_header);
|
||||
do_bootm_linux(os_handle, initrd_handle);
|
||||
#endif
|
||||
break;
|
||||
#ifdef CONFIG_NETBSD
|
||||
|
@ -434,10 +445,10 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
|
|||
#endif
|
||||
|
||||
err_out:
|
||||
if (os_header)
|
||||
free(os_header);
|
||||
if (initrd_header)
|
||||
free(initrd_header);
|
||||
if (os_handle)
|
||||
unmap_image(os_handle);
|
||||
if (initrd_handle)
|
||||
unmap_image(initrd_handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,21 +2,11 @@
|
|||
#define __BOOT_H
|
||||
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
int do_bootm_linux(image_header_t *os, image_header_t *initrd,
|
||||
int do_bootm_linux(struct image_handle *os, struct image_handle *initrd,
|
||||
const char *oftree);
|
||||
#else
|
||||
int do_bootm_linux(image_header_t *os, image_header_t *initrd);
|
||||
int do_bootm_linux(struct image_handle *os, struct image_handle *initrd);
|
||||
#endif
|
||||
|
||||
#endif /* __BOOT_H */
|
||||
#ifndef __BOOT_H
|
||||
#define __BOOT_H
|
||||
|
||||
#ifdef CONFIG_OF_FLAT_TREE
|
||||
int do_bootm_linux(image_header_t *os, image_header_t *initrd,
|
||||
const char *oftree);
|
||||
#else
|
||||
int do_bootm_linux(image_header_t *os, image_header_t *initrd);
|
||||
#endif
|
||||
|
||||
#endif /* __BOOT_H */
|
||||
|
|
|
@ -180,6 +180,13 @@ typedef struct image_header {
|
|||
uint8_t ih_name[IH_NMLEN]; /* Image Name */
|
||||
} image_header_t;
|
||||
|
||||
struct image_handle {
|
||||
image_header_t header;
|
||||
void *data;
|
||||
#define IH_MALLOC 1
|
||||
int flags;
|
||||
};
|
||||
|
||||
/* commamds/bootm.c */
|
||||
void print_image_hdr (image_header_t *hdr);
|
||||
|
||||
|
@ -187,12 +194,12 @@ void print_image_hdr (image_header_t *hdr);
|
|||
* Load an image into memory. Returns a pointer to the loaded
|
||||
* image.
|
||||
*/
|
||||
image_header_t *map_image(const char *filename, int verify);
|
||||
struct image_handle *map_image(const char *filename, int verify);
|
||||
|
||||
/*
|
||||
* Relocate an image to load_address by uncompressing
|
||||
* or just copying.
|
||||
*/
|
||||
int relocate_image(image_header_t *hdr, void *load_address);
|
||||
int relocate_image(struct image_handle *handle, void *load_address);
|
||||
|
||||
#endif /* __IMAGE_H__ */
|
||||
|
|
Loading…
Reference in New Issue