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]

-x option for RedBoot exec command


This adds support for bi-endian ARM platforms to boot a linux
kernel which is not the same endianess as RedBoot.

--Mark

Index: hal/arm/arch/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/arch/current/ChangeLog,v
retrieving revision 1.99
diff -u -p -5 -r1.99 ChangeLog
--- hal/arm/arch/current/ChangeLog	7 Jul 2004 15:44:47 -0000	1.99
+++ hal/arm/arch/current/ChangeLog	2 Sep 2004 16:21:42 -0000
@@ -1,5 +1,13 @@
+2004-09-02  Mark Salter  <msalter@redhat.com>
+
+	* cdl/hal_arm.cdl (CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH): New
+	option used to enable "-x" option to exec command.
+	
+	* src/redboot_linux_exec.c (do_exec): Add support for booting
+	kernels built for endianess oppposite of RedBoot.
+
 2004-07-07  Gary Thomas  <gary@mlbassoc.com>
 
 	* src/redboot_linux_exec.c (do_exec): Fix test for valid entry
 	(was being overwritten by command line parameter)
 
Index: hal/arm/arch/current/cdl/hal_arm.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/arch/current/cdl/hal_arm.cdl,v
retrieving revision 1.14
diff -u -p -5 -r1.14 hal_arm.cdl
--- hal/arm/arch/current/cdl/hal_arm.cdl	22 Apr 2004 15:26:25 -0000	1.14
+++ hal/arm/arch/current/cdl/hal_arm.cdl	2 Sep 2004 16:21:42 -0000
@@ -247,10 +247,19 @@ cdl_package CYGPKG_HAL_ARM {
                 This option contains requirements for booting linux
                 from RedBoot. The component is enabled/disabled from
                 RedBoots CDL."
             compile -library=libextras.a redboot_linux_exec.c
 
+            cdl_option CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH {
+                display "Enable -x switch for exec command."
+                flavor bool
+                default_value 0
+                description "
+                    This option allows bi-endian platforms to launch kernels
+                    built for an endianess different than the RedBoot endianess"
+            }
+ 
             cdl_option CYGHWR_REDBOOT_ARM_LINUX_EXEC_ADDRESS {
                 display       "Physical base address of linux kernel"
                 flavor        data
                 default_value CYGHWR_REDBOOT_ARM_LINUX_EXEC_ADDRESS_DEFAULT
                 description   "
Index: hal/arm/arch/current/src/redboot_linux_exec.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/arm/arch/current/src/redboot_linux_exec.c,v
retrieving revision 1.12
diff -u -p -5 -r1.12 redboot_linux_exec.c
--- hal/arm/arch/current/src/redboot_linux_exec.c	7 Jul 2004 15:44:47 -0000	1.12
+++ hal/arm/arch/current/src/redboot_linux_exec.c	2 Sep 2004 16:21:42 -0000
@@ -6,11 +6,11 @@
 //
 //==========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
 // Copyright (C) 2003, 2004 Gary Thomas
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
 // Software Foundation; either version 2 or (at your option) any later version.
@@ -98,20 +98,49 @@ RedBoot_cmd("exec", 
 
 // CYGARC_HAL_MMU_OFF inserts code to turn off MMU and jump to a physical
 // address. Some ARM implementations may need special handling and define
 // their own version.
 #ifndef CYGARC_HAL_MMU_OFF
-#define CYGARC_HAL_MMU_OFF(__paddr__) \
-  "   mcr p15,0,r0,c7,c10,4\n"        \
-  "   mcr p15,0,r0,c7,c7,0\n"         \
-  "   mrc p15,0,r0,c1,c0,0\n"         \
+
+#define __CYGARC_GET_CTLREG \
+              "   mrc p15,0,r0,c1,c0,0\n"
+
+#define __CYGARC_CLR_MMU_BITS         \
   "   bic r0,r0,#0xd\n"               \
   "   bic r0,r0,#0x1000\n"            \
-  "   mcr p15,0,r0,c1,c0,0\n"         \
-  "   mov pc," #__paddr__ "\n"
+
+#ifdef CYGHWR_HAL_ARM_BIGENDIAN
+#define __CYGARC_CLR_MMU_BITS_X       \
+  "   bic r0,r0,#0x8d\n"              \
+  "   bic r0,r0,#0x1000\n"
+#else
+#define __CYGARC_CLR_MMU_BITS_X       \
+  "   bic r0,r0,#0xd\n"               \
+  "   bic r0,r0,#0x1000\n"            \
+  "   orr r0,r0,#0x80\n"
 #endif
 
+#define __CYGARC_SET_CTLREG(__paddr__) \
+  "   mcr p15,0,r0,c1,c0,0\n"          \
+  "   mov pc," #__paddr__ "\n"
+
+#define CYGARC_HAL_MMU_OFF(__paddr__)  \
+  "   mcr p15,0,r0,c7,c10,4\n"         \
+  "   mcr p15,0,r0,c7,c7,0\n"          \
+  __CYGARC_GET_CTLREG                  \  
+  __CYGARC_CLR_MMU_BITS                \
+  __CYGARC_SET_CTLREG(__paddr__)
+
+#define CYGARC_HAL_MMU_OFF_X(__paddr__)  \
+  "   mcr p15,0,r0,c7,c10,4\n"           \
+  "   mcr p15,0,r0,c7,c7,0\n"            \
+  __CYGARC_GET_CTLREG                    \  
+  __CYGARC_CLR_MMU_BITS_X                \
+  __CYGARC_SET_CTLREG(__paddr__)
+
+#endif  // CYGARC_HAL_MMU_OFF
+
 //
 // Parameter info for Linux kernel
 //   ** C A U T I O N **  This setup must match "asm-arm/setup.h"
 //
 // Info is passed at a fixed location, using a sequence of tagged
@@ -278,19 +307,23 @@ static void 
 do_exec(int argc, char *argv[])
 {
     unsigned long entry;
     unsigned long oldints;
     bool wait_time_set;
-    int  wait_time, res;
+    int  wait_time, res, num_opts;
     bool base_addr_set, length_set, cmd_line_set;
     bool ramdisk_addr_set, ramdisk_size_set;
     unsigned long base_addr, length;
     unsigned long ramdisk_addr, ramdisk_size;
-    struct option_info opts[6];
+    struct option_info opts[7];
     char line[8];
     char *cmd_line;
     struct tag *params = (struct tag *)CYGHWR_REDBOOT_ARM_LINUX_TAGS_ADDRESS;
+#ifdef CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH
+    bool swap_endian;
+    extern char __xtramp_start__[], __xtramp_end__[];
+#endif
     extern char __tramp_start__[], __tramp_end__[];
 
     // Check to see if a valid image has been loaded
     if (entry_address == (unsigned long)NO_MEMORY) {
         diag_printf("Can't execute Linux - invalid entry address\n");
@@ -315,11 +348,17 @@ do_exec(int argc, char *argv[])
               (void **)&cmd_line, (bool *)&cmd_line_set, "kernel command line");
     init_opts(&opts[4], 'r', true, OPTION_ARG_TYPE_NUM, 
               (void **)&ramdisk_addr, (bool *)&ramdisk_addr_set, "ramdisk_addr");
     init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, 
               (void **)&ramdisk_size, (bool *)&ramdisk_size_set, "ramdisk_size");
-    if (!scan_opts(argc, argv, 1, opts, 6, (void *)&entry, OPTION_ARG_TYPE_NUM, "[physical] starting address"))
+    num_opts = 6;
+#ifdef CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH
+    init_opts(&opts[6], 'x', false, OPTION_ARG_TYPE_FLG, 
+              (void **)&swap_endian, 0, "swap endianess");
+    ++num_opts;
+#endif
+    if (!scan_opts(argc, argv, 1, opts, num_opts, (void *)&entry, OPTION_ARG_TYPE_NUM, "[physical] starting address"))
     {
         return;
     }
 
     // Set up parameters to pass to kernel
@@ -403,10 +442,52 @@ do_exec(int argc, char *argv[])
     // 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.
 
+#ifdef CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH
+    if (swap_endian) {
+	// copy the trampline code
+	memcpy((char *)CYGHWR_REDBOOT_ARM_TRAMPOLINE_ADDRESS,
+	       __xtramp_start__,
+	       __xtramp_end__ - __xtramp_start__);
+
+	asm volatile (
+	    CYGARC_HAL_MMU_OFF_X(%5)
+	    "__xtramp_start__:\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
+	    " beq 2f;\n"
+	    "1:\n"
+	    " ldr r0,[%1],#4;\n"
+	    " eor %5, r0, r0, ror #16;\n"
+	    " bic %5, %5, #0x00ff0000;\n"
+	    " mov r0, r0, ror #8;\n"
+	    " eor r0, r0, %5, lsr #8;\n"
+	    " str r0,[%4],#4;\n"
+	    " subs %2,%2,#4;\n"
+	    " bne 1b;\n"
+	    "2:\n"
+	    " mov r0,#0;\n"       // Set board type
+	    " mov r1,%3;\n"       // Machine type
+	    " 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),
+	    "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))
+	    : "r0", "r1"
+	    );
+    }
+#endif // CYGHWR_REDBOOT_LINUX_EXEC_X_SWITCH
+
     // copy the trampline code
     memcpy((char *)CYGHWR_REDBOOT_ARM_TRAMPOLINE_ADDRESS,
 	   __tramp_start__,
 	   __tramp_end__ - __tramp_start__);
 
Index: redboot/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/ChangeLog,v
retrieving revision 1.204
diff -u -p -5 -r1.204 ChangeLog
--- redboot/current/ChangeLog	1 Sep 2004 21:21:30 -0000	1.204
+++ redboot/current/ChangeLog	2 Sep 2004 16:21:51 -0000
@@ -1,5 +1,9 @@
+2004-09-02  Mark Salter  <msalter@redhat.com>
+
+	* doc/redboot_cmds.sgml: Add -x option to exec command.
+
 2004-09-01  Mark Salter  <msalter@redhat.com>
 
 	* cdl/redboot.cdl (CYGOPT_REDBOOT_FLASH_BYTEORDER): New option.
 	* include/redboot.h: Define FLASH_{READ,PROGRAM} macros.
 	Define REDBOOT_FLASH_REVERSE_BYTEORDER if appropriate.
Index: redboot/current/doc/redboot_cmds.sgml
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/doc/redboot_cmds.sgml,v
retrieving revision 1.9
diff -u -p -5 -r1.9 redboot_cmds.sgml
--- redboot/current/doc/redboot_cmds.sgml	27 Aug 2004 13:27:40 -0000	1.9
+++ redboot/current/doc/redboot_cmds.sgml	2 Sep 2004 16:21:51 -0000
@@ -8,11 +8,11 @@
 <!--                                                                 -->
 <!-- =============================================================== -->
 <!-- ####COPYRIGHTBEGIN####                                          -->
 <!--                                                                 -->
 <!-- =============================================================== -->
-<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.  -->
+<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.  -->
 <!-- This material may be distributed only subject to the terms      -->
 <!-- and conditions set forth in the Open Publication License, v1.0  -->
 <!-- or later (the latest version is presently available at          -->
 <!-- http://www.opencontent.org/openpub/)                            -->
 <!-- Distribution of the work or derivative of the work in any       -->
@@ -2973,10 +2973,16 @@ command, either from a script or the con
 	      <entry>String</entry>
 	      <entry>Command line to pass to the Linux kernel.</entry>	     
 	      <entry><emphasis>None</emphasis></entry>	     
 	    </row>
 	    <row>
+	      <entry>-x</entry>	     
+	      <entry></entry>
+	      <entry>Boot kernel with endianess opposite of RedBoot endianess.</entry>	     
+	      <entry>Boot kernel with same endianess as RedBoot</entry>	     
+	    </row>
+	    <row>
 	      <entry><replaceable>entry_address</replaceable></entry>	     
 	      <entry>Number</entry>
 	      <entry>Starting address for Linux kernel execution</entry>	     
 	      <entry>Implied by architecture</entry>	     
 	    </row>
@@ -3004,10 +3010,12 @@ loaded ramdisk (initrd) is located.</par
 <para>The "-c" option can be used to pass textual "command line" information
 to the kernel.  If the command line data contains any punctuation (spaces,
 etc), then it must be quoted using the double-quote character '"'. If the
 quote character is required, it should be written as '\"'.
       </para>
+<para>The "-x" option is optionally available on some bi-endian platforms. It is used to boot
+a kernel built with an endianess opposite of RedBoot.</para>
     </refsect1>
     <refsect1>
       <title>Examples</title>
       <para>
 Execute a Linux kernel, passing a command line, which needs relocation.


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