// Contributors: gthomas, jskov,
// Russell King <rmk@arm.linux.org.uk>
// Date: 2001-02-20
-// Purpose:
-// Description:
-//
+// Purpose:
+// Description:
+//
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
// Exported CLI function(s)
static void do_exec(int argc, char *argv[]);
-RedBoot_cmd("exec",
- "Execute an image - with MMU off",
+RedBoot_cmd("exec",
+ "Execute an image - with MMU off",
"[-w timeout] [-b <load addr> [-l <length>]]\n"
" [-r <ramdisk addr> [-s <ramdisk length>]]\n"
" [-c \"kernel command line\"] [-t <target> ] [<entry_point>]",
// Default memory layout - can be overridden by platform, typically in
// <cyg/hal/plf_io.h>
#ifndef CYGHWR_REDBOOT_LINUX_ATAG_MEM
-#define CYGHWR_REDBOOT_LINUX_ATAG_MEM(_p_) \
- CYG_MACRO_START \
- /* Next ATAG_MEM. */ \
- _p_->hdr.size = (sizeof(struct tag_mem32) + sizeof(struct tag_header))/sizeof(long); \
- _p_->hdr.tag = ATAG_MEM; \
- /* Round up so there's only one bit set in the memory size. \
- * Don't double it if it's already a power of two, though. \
- */ \
- _p_->u.mem.size = 1<<hal_msbindex(CYGMEM_REGION_ram_SIZE); \
- if (_p_->u.mem.size < CYGMEM_REGION_ram_SIZE) \
- _p_->u.mem.size <<= 1; \
- _p_->u.mem.start = CYGARC_PHYSICAL_ADDRESS(CYGMEM_REGION_ram); \
+#define CYGHWR_REDBOOT_LINUX_ATAG_MEM(_p_) \
+ CYG_MACRO_START \
+ /* Next ATAG_MEM. */ \
+ _p_->hdr.size = (sizeof(struct tag_mem32) + sizeof(struct tag_header))/sizeof(long); \
+ _p_->hdr.tag = ATAG_MEM; \
+ /* Round up so there's only one bit set in the memory size. \
+ * Don't double it if it's already a power of two, though. \
+ */ \
+ _p_->u.mem.size = 1<<hal_msbindex(CYGMEM_REGION_ram_SIZE); \
+ if (_p_->u.mem.size < CYGMEM_REGION_ram_SIZE) \
+ _p_->u.mem.size <<= 1; \
+ _p_->u.mem.start = CYGARC_PHYSICAL_ADDRESS(CYGMEM_REGION_ram); \
CYG_MACRO_END
#endif
// Round up a quantity to a longword (32 bit) length
#define ROUNDUP(n) (((n) + 3) & ~3)
-static void
+static void
do_exec(int argc, char *argv[])
{
unsigned long entry;
#endif
extern char __tramp_start__[], __tramp_end__[];
-#if 1
target = load_address;
entry = entry_address;
-#else
- // Default physical entry point for Linux is kernel base.
- entry = (unsigned long)CYGHWR_REDBOOT_ARM_LINUX_EXEC_ADDRESS;
- target = (unsigned long)CYGHWR_REDBOOT_ARM_LINUX_EXEC_ADDRESS;
-#endif
+
base_addr = load_address;
length = load_address_end - load_address;
// Round length up to the next quad word
length = (length + 3) & ~0x3;
ramdisk_size = 4096*1024;
- init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
- &wait_time, &wait_time_set, "wait timeout");
- init_opts(&opts[1], 'b', true, OPTION_ARG_TYPE_NUM,
- &base_addr, &base_addr_set, "base address");
- init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM,
- &length, &length_set, "length");
- init_opts(&opts[3], 'c', true, OPTION_ARG_TYPE_STR,
- &cmd_line, &cmd_line_set, "kernel command line");
- init_opts(&opts[4], 'r', true, OPTION_ARG_TYPE_NUM,
- &ramdisk_addr, &ramdisk_addr_set, "ramdisk_addr");
- init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM,
- &ramdisk_size, &ramdisk_size_set, "ramdisk_size");
+ init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
+ &wait_time, &wait_time_set, "wait timeout");
+ init_opts(&opts[1], 'b', true, OPTION_ARG_TYPE_NUM,
+ &base_addr, &base_addr_set, "base address");
+ init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM,
+ &length, &length_set, "length");
+ init_opts(&opts[3], 'c', true, OPTION_ARG_TYPE_STR,
+ &cmd_line, &cmd_line_set, "kernel command line");
+ init_opts(&opts[4], 'r', true, OPTION_ARG_TYPE_NUM,
+ &ramdisk_addr, &ramdisk_addr_set, "ramdisk_addr");
+ init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM,
+ &ramdisk_size, &ramdisk_size_set, "ramdisk_size");
init_opts(&opts[6], 't', true, OPTION_ARG_TYPE_NUM,
- &target, 0, "[physical] target address");
+ &target, 0, "[physical] target address");
num_opts = 7;
#ifdef CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH
- init_opts(&opts[num_opts], 'x', false, OPTION_ARG_TYPE_FLG,
- &swap_endian, 0, "swap endianness");
+ init_opts(&opts[num_opts], 'x', false, OPTION_ARG_TYPE_FLG,
+ &swap_endian, 0, "swap endianness");
++num_opts;
#endif
if (!scan_opts(argc, argv, 1, opts, num_opts, &entry,
// Set up parameters to pass to kernel
// CORE tag must be present & first
- params->hdr.size = (sizeof(struct tag_core) + sizeof(struct tag_header))/sizeof(long);
+ params->hdr.size = (sizeof(struct tag_core) + sizeof(struct tag_header)) / sizeof(long);
params->hdr.tag = ATAG_CORE;
params->u.core.flags = 0;
params->u.core.pagesize = 0;
params = (struct tag *)((long *)params + params->hdr.size);
if (ramdisk_addr_set) {
- params->hdr.size = (sizeof(struct tag_initrd) + sizeof(struct tag_header))/sizeof(long);
+ params->hdr.size = (sizeof(struct tag_initrd) + sizeof(struct tag_header)) / sizeof(long);
params->hdr.tag = ATAG_INITRD2;
params->u.initrd.start = CYGARC_PHYSICAL_ADDRESS(ramdisk_addr);
params->u.initrd.size = ramdisk_size;
// memory map possibly convoluted from 1-1. The trampoline code
// between labels __tramp_start__ and __tramp_end__ must be copied
// to RAM and then executed at the non-mapped address.
- //
+ //
// This magic was created in order to be able to execute standard
// Linux kernels with as little change/perturberance as possible.
" mov r2,%6;\n" // Kernel parameters
" mov pc,%0;\n" // Jump to kernel
"__xtramp_end__:\n"
- : :
+ : :
"r"(entry),
"r"(CYGARC_PHYSICAL_ADDRESS(base_addr)),
"r"(length),
" mov r2,%6;\n" // Kernel parameters
" mov pc,%0;\n" // Jump to kernel
"__tramp_end__:\n"
- : :
+ : :
"r"(entry),
"r"(CYGARC_PHYSICAL_ADDRESS(base_addr)),
"r"(length),
: "r0", "r1"
);
}
-
+
#endif // HAL_PLATFORM_MACHINE_TYPE - otherwise we do not support this stuff...
// EOF redboot_linux_exec.c