9
0
Fork 0

use memmap() to save one memcpy call in bootm

This commit is contained in:
Sascha Hauer 2007-07-15 14:02:53 +02:00
parent 665291e693
commit 8881fb7984
5 changed files with 77 additions and 63 deletions

View File

@ -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 */

View File

@ -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)

View File

@ -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;
}

View File

@ -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 */

View File

@ -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__ */