This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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"
         );
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]