This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
linux exec on arm
- From: Jani Monoses <jani at iv dot ro>
- To: ecos-patches at sources dot redhat dot com
- Date: Mon, 23 Sep 2002 17:04:15 +0000
- Subject: linux exec on arm
In order to boot linux from redboot on edb7211 the following changes needed to be made
1)do not pass ATAG_CORE to the kernel because the board has discontiguos SDRAM and
the fixup function in the kernel will handle that.
2)the tags hw address (where linux expects them) is not mapped in ecos virtual mem
(The address is 0xC0020100)
Unless there are objections I propose that CYGHWR_REDBOOT_ARM_LINUX_TAGS_ADDRESS be a
hardware address.redboot builds the tag list and after disabling mmu it copies the list to
the right address.
This patch is just a draft; if you think it's OK then the existing ARMs booting linux should
have the TAGS address changed as well and the PASS_MEM_ATAG define renamed and put in the CDLs
somewhere.
Comments?
--- hal/arm/arch/current/src/redboot_linux_exec.c 31 May 2002 01:05:54 -0000 1.3
+++ hal/arm/arch/current/src/redboot_linux_exec.c 23 Sep 2002 13:44:51 -0000
@@ -242,7 +242,7 @@
// Round up a quantity to a longword (32 bit) length
#define ROUNDUP(n) (((n)+3)&~3)
-
+char tags[1024];
static void
do_exec(int argc, char *argv[])
{
@@ -257,9 +257,9 @@
struct option_info opts[6];
char line[8];
char *cmd_line;
- struct tag *params = (struct tag *)CYGHWR_REDBOOT_ARM_LINUX_TAGS_ADDRESS;
+ struct tag *params = (struct tag *)tags;
extern char __tramp_start__[], __tramp_end__[];
-
+ unsigned long tags_length;
// Default physical entry point for Linux is kernel base.
entry = (unsigned long)CYGHWR_REDBOOT_ARM_LINUX_EXEC_ADDRESS;
@@ -292,7 +292,7 @@
params->u.core.pagesize = 0;
params->u.core.rootdev = 0;
params = (struct tag *)((long *)params + params->hdr.size);
-
+#if PASS_ATAG_MEM
/* Next ATAG_MEM. */
params->hdr.size = (sizeof(struct tag_mem32) + sizeof(struct tag_header))/sizeof(long);
params->hdr.tag = ATAG_MEM;
@@ -304,7 +304,7 @@
if (params->u.mem.size < CYGMEM_REGION_ram_SIZE << 1)
params->u.mem.size <<= 1;
params = (struct tag *)((long *)params + params->hdr.size);
-
+#endif
if (ramdisk_addr_set) {
params->hdr.size = (sizeof(struct tag_initrd) + sizeof(struct tag_header))/sizeof(long);
params->hdr.tag = ATAG_INITRD;
@@ -321,7 +321,7 @@
// Mark end of parameter list
params->hdr.size = 0;
params->hdr.tag = ATAG_NONE;
-
+ tags_length = (unsigned long)params + sizeof(struct tag_header) - (unsigned long)tags;
if (wait_time_set) {
int script_timeout_ms = wait_time * 1000;
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
@@ -372,6 +372,11 @@
asm volatile (
CYGARC_HAL_MMU_OFF(%5)
"__tramp_start__:\n"
+ "0:\n"
+ " ldr r0,[%7],#4;\n" // Copy boot params to where the kernel
+ " str r0,[%6],#4;\n" // expects them to be
+ " subs %8,%8,#4;\n"
+ " bne 0b;\n"
" cmp %1,%4;\n" // Default kernel load address. Relocate
" beq 2f;\n" // kernel image there if necessary, and
" cmp %2,#0;\n" // if size is non-zero
@@ -394,7 +399,9 @@
"r"(CYGHWR_REDBOOT_ARM_MACHINE_TYPE),
"r"(CYGHWR_REDBOOT_ARM_LINUX_EXEC_ADDRESS),
"r"(CYGARC_PHYSICAL_ADDRESS(CYGHWR_REDBOOT_ARM_TRAMPOLINE_ADDRESS)),
- "r"(CYGARC_PHYSICAL_ADDRESS(CYGHWR_REDBOOT_ARM_LINUX_TAGS_ADDRESS))
+ "r"(CYGHWR_REDBOOT_ARM_LINUX_TAGS_ADDRESS),
+ "r"(CYGARC_PHYSICAL_ADDRESS(tags)),
+ "r"(tags_length)
: "r0", "r1"
);
}