This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
Viper - add Linux boot command
- From: Gary Thomas <gary at chez-thomas dot org>
- To: eCos patches <ecos-patches at sources dot redhat dot com>
- Date: 25 Jun 2002 17:21:33 -0600
- Subject: Viper - add Linux boot command
Index: hal/powerpc/viper/current/ChangeLog
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/hal/powerpc/viper/current/ChangeLog,v
retrieving revision 1.7
diff -u -5 -p -r1.7 ChangeLog
--- hal/powerpc/viper/current/ChangeLog 24 Jun 2002 13:10:11 -0000 1.7
+++ hal/powerpc/viper/current/ChangeLog 25 Jun 2002 23:19:54 -0000
@@ -1,5 +1,10 @@
+2002-06-25 Gary Thomas <gary@chez-thomas.org>
+
+ * src/redboot_linux_exec.c:
+ * cdl/hal_powerpc_viper.cdl: Add Linux boot (exec) command.
+
2002-06-24 Gary Thomas <gary@chez-thomas.org>
* misc/redboot_ROMRAM.ecm: Update for new FLASH chips.
2002-06-20 Gary Thomas <gary@chez-thomas.org>
Index: hal/powerpc/viper/current/cdl/hal_powerpc_viper.cdl
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/hal/powerpc/viper/current/cdl/hal_powerpc_viper.cdl,v
retrieving revision 1.3
diff -u -5 -p -r1.3 hal_powerpc_viper.cdl
--- hal/powerpc/viper/current/cdl/hal_powerpc_viper.cdl 23 May 2002 23:04:34 -0000 1.3
+++ hal/powerpc/viper/current/cdl/hal_powerpc_viper.cdl 24 Jun 2002 13:56:56 -0000
@@ -40,11 +40,11 @@
# ====================================================================
######DESCRIPTIONBEGIN####
#
# Author(s): jskov
# Original data: hmt
-# Contributors:
+# Contributors: gthomas
# Date: 1999-11-02
#
#####DESCRIPTIONEND####
#
# ====================================================================
@@ -330,20 +330,30 @@ cdl_package CYGPKG_HAL_POWERPC_VIPER {
active_if CYGPKG_REDBOOT
description "
This option lists the target's requirements for a valid Redboot
configuration."
+ cdl_option CYGSEM_REDBOOT_HAL_LINUX_BOOT {
+ display "Support booting Linux via RedBoot"
+ flavor bool
+ default_value 1
+ description "
+ This option enables RedBoot to support booting of a Linux kernel."
+
+ compile -library=libextras.a redboot_linux_exec.c
+ }
+
cdl_option CYGBLD_BUILD_REDBOOT_BIN {
display "Build Redboot ROM binary image"
active_if CYGBLD_BUILD_REDBOOT
default_value 1
no_define
description "This option enables the conversion of the Redboot ELF
image to a binary image suitable for ROM programming."
# compile -library=libextras.a redboot_cmds.c
-
+
make -priority 325 {
<PREFIX>/bin/redboot.bin : <PREFIX>/bin/redboot.elf
$(OBJCOPY) --strip-debug $< $(@:.bin=.img)
$(OBJCOPY) -O srec $< $(@:.bin=.srec)
$(OBJCOPY) -O binary $< $@
Index: hal/powerpc/viper/current/src/redboot_linux_exec.c
===================================================================
RCS file: hal/powerpc/viper/current/src/redboot_linux_exec.c
diff -N hal/powerpc/viper/current/src/redboot_linux_exec.c
--- hal/powerpc/viper/current/src/redboot_linux_exec.c 1 Jan 1970 00:00:00 -0000
+++ hal/powerpc/viper/current/src/redboot_linux_exec.c 25 Jun 2002 23:19:25 -0000
@@ -0,0 +1,272 @@
+//==========================================================================
+//
+// redboot_linux_boot.c
+//
+// RedBoot command to boot Linux
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+//
+// 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.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+//
+// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
+// at http://sources.redhat.com/ecos/ecos-license/
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//####OTHERCOPYRIGHTBEGIN####
+//
+// The structure definitions below are taken from include/ppc/platforms/am860.h in
+// the Linux kernel, Copyright (c) 2002 Gary Thomas, Copyright (c) 1997 Dan Malek.
+// Their presence here is for the express purpose of communication with the Linux
+// kernel being booted and is considered 'fair use' by the original author and
+// are included with their permission.
+//
+//####OTHERCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): msalter
+// Contributors: gthomas,msalter
+// Date: 2002-01-14
+// Purpose:
+// Description:
+//
+// This code is part of RedBoot (tm).
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+#include <redboot.h>
+#include <pkgconf/hal_powerpc_quicc.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+
+#ifdef CYGPKG_REDBOOT_NETWORKING
+#include <net/net.h>
+#endif
+
+#ifdef CYGSEM_REDBOOT_HAL_LINUX_BOOT
+
+#include CYGHWR_MEMORY_LAYOUT_H
+
+//=========================================================================
+
+// Exported CLI function(s)
+static void do_exec(int argc, char *argv[]);
+RedBoot_cmd("exec",
+ "Execute a Linux image - with MMU off",
+ "[-w timeout]\n"
+ " [-c \"kernel command line\"] [<entry_point>]",
+ do_exec
+ );
+
+//=========================================================================
+// Imported from Linux kernel include/asm-ppc/am860.h
+// Copyright (c) 2002 Gary Thomas (gary@chez-thomas.org)
+// Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
+// Used with permission of author(s).
+
+
+/* A Board Information structure that is given to a program when
+ * RedBoot starts it up.
+ */
+typedef struct bd_info {
+ unsigned int bi_tag; /* Should be 0x42444944 "BDID" */
+ unsigned int bi_size; /* Size of this structure */
+ unsigned int bi_revision; /* revision of this structure */
+ unsigned int bi_bdate; /* EPPCbug date, i.e. 0x11061997 */
+ unsigned int bi_memstart; /* Memory start address */
+ unsigned int bi_memsize; /* Memory (end) size in bytes */
+ unsigned int bi_intfreq; /* Internal Freq, in Hz */
+ unsigned int bi_busfreq; /* Bus Freq, in Hz */
+ unsigned int bi_clun; /* Boot device controller */
+ unsigned int bi_dlun; /* Boot device logical dev */
+ unsigned char bi_enetaddr[6];
+ unsigned int bi_baudrate;
+ unsigned char *bi_cmdline;
+} bd_t;
+
+//
+// Execute a Linux kernel - this is a RedBoot CLI command
+//
+static void
+do_exec(int argc, char *argv[])
+{
+ unsigned long entry;
+ bool wait_time_set, cmd_line_set;
+ int wait_time;
+ char *cmd_line;
+ char *cline;
+ struct option_info opts[2];
+ hal_virtual_comm_table_t *__chan;
+ int baud_rate;
+
+ bd_t *board_info;
+ CYG_INTERRUPT_STATE oldints;
+ unsigned long sp = CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE;
+
+ init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
+ (void **)&wait_time, (bool *)&wait_time_set, "wait timeout");
+ init_opts(&opts[1], 'c', true, OPTION_ARG_TYPE_STR,
+ (void **)&cmd_line, (bool *)&cmd_line_set, "kernel command line");
+ entry = entry_address; // Default from last 'load' operation
+ if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM,
+ "[physical] starting address")) {
+ return;
+ }
+
+ // Determine baud rate on current console
+ __chan = CYGACC_CALL_IF_CONSOLE_PROCS();
+ baud_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
+ if (baud_rate <= 0) {
+ baud_rate = CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD;
+ }
+
+ // Make a little space at the top of the stack, and align to
+ // 64-bit boundary.
+ sp = (sp-128) & ~7; // The Linux boot code uses this space for FIFOs
+
+ // Copy the commandline onto the stack, and set the SP to just below it.
+ if (cmd_line_set) {
+ int len,i;
+
+ // get length of string
+ for( len = 0; cmd_line[len] != '\0'; len++ );
+
+ // decrement sp by length of string and align to
+ // word boundary.
+ sp = (sp-(len+1)) & ~3;
+
+ // assign this SP value to command line start
+ cline = (char *)sp;
+
+ // copy command line over.
+ for( i = 0; i < len; i++ )
+ cline[i] = cmd_line[i];
+ cline[len] = '\0';
+
+ } else {
+ cline = (char *)NULL;
+ }
+
+ // Set up parameter struct at top of stack
+ sp = sp-sizeof(bd_t);
+ board_info = (bd_t *)sp;
+ memset(board_info, sizeof(*board_info), 0);
+
+ board_info->bi_tag = 0x42444944;
+ board_info->bi_size = sizeof(board_info);
+ board_info->bi_revision = 1;
+ board_info->bi_bdate = 0x06012002;
+ board_info->bi_memstart = CYGMEM_REGION_ram;
+ board_info->bi_memsize = CYGMEM_REGION_ram_SIZE;
+ board_info->bi_intfreq = CYGHWR_HAL_POWERPC_BOARD_SPEED*1000000;
+ board_info->bi_busfreq = 66*1000000;
+ board_info->bi_clun = 0; // ????
+ board_info->bi_dlun = 0; // ????
+ board_info->bi_baudrate = baud_rate;
+ board_info->bi_cmdline = cline;
+#ifdef CYGPKG_REDBOOT_NETWORKING
+ memcpy(board_info->bi_enetaddr, __local_enet_addr, sizeof(enet_addr_t));
+#endif
+
+ // adjust SP to 64 bit boundary, and leave a little space
+ // between it and the commandline for PowerPC calling
+ // conventions.
+
+ sp = (sp-32)&~7;
+
+ if (wait_time_set) {
+ int script_timeout_ms = wait_time * 1000;
+#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
+ unsigned char *hold_script = script;
+ script = (unsigned char *)0;
+#endif
+ diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
+ (void *)entry, wait_time);
+ while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
+ int res;
+ char line[80];
+ res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
+ if (res == _GETS_CTRLC) {
+#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
+ script = hold_script; // Re-enable script
+#endif
+ return;
+ }
+ script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
+ }
+ }
+
+ // Disable interrupts
+ HAL_DISABLE_INTERRUPTS(oldints);
+
+ // Put the caches to sleep.
+ HAL_DCACHE_SYNC();
+ HAL_ICACHE_DISABLE();
+ HAL_DCACHE_DISABLE();
+ HAL_DCACHE_SYNC();
+ HAL_ICACHE_INVALIDATE_ALL();
+ HAL_DCACHE_INVALIDATE_ALL();
+
+// diag_printf("entry %08x, sp %08x, info %08x, cmd line %08x, baud %d\n",
+// entry, sp, board_info, cline, baud_rate);
+// breakpoint();
+
+ // Call into Linux
+ __asm__ volatile (
+ // Start by disabling MMU - the mappings are
+ // 1-1 so this should not cause any problems
+ "mfmsr 3\n"
+ "li 4,0xFFFFFFCF\n"
+ "and 3,3,4\n"
+ "sync\n"
+ "mtmsr 3\n"
+ "sync\n"
+
+ // Now set up parameters to jump into linux
+
+ "mtlr %0\n" // set entry address in LR
+ "mr 1,%1\n" // set stack pointer
+ "mr 3,%2\n" // set board info in R3
+ "mr 4,%3\n" // set command line in R4
+ "blr \n" // jump into linux
+ :
+ : "r"(entry),"r"(sp),"r"(board_info),"r"(cline)
+ : "r3", "r4"
+
+ );
+}
+
+#endif // CYGSEM_REDBOOT_HAL_LINUX_BOOT
+
+//=========================================================================
+// EOF redboot_linux_exec.c