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]

load and boot support of linux bzImage for i386


Although it has a few limitations such as handling initrd, it allows
redboot-i386 to load and boot linux bzImage.

Index: hal/i386/arch/current/cdl/hal_i386.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/i386/arch/current/cdl/hal_i386.cdl,v
retrieving revision 1.10
diff -u -p -r1.10 hal_i386.cdl
--- hal/i386/arch/current/cdl/hal_i386.cdl	23 May 2002 23:03:02 -0000	1.10
+++ hal/i386/arch/current/cdl/hal_i386.cdl	19 Jul 2002 04:22:48 -0000
@@ -162,5 +162,41 @@ cdl_package CYGPKG_HAL_I386 {
     cdl_interface CYGINT_HAL_I386_MEM_REAL_REGION_TOP {
         display  "Implementations of hal_i386_mem_real_region_top()"
     }
+
+    cdl_component CYGPKG_REDBOOT_I386_OPTIONS {
+        display       "Redboot for i386 options"
+        flavor        none
+        no_define
+        parent        CYGPKG_REDBOOT
+        active_if     CYGPKG_REDBOOT
+        description   "
+            This option lists the target's requirements for a valid Redboot
+            configuration."
+
+        cdl_component CYGSEM_REDBOOT_I386_LINUX_BOOT {
+            display        "Support booting Linux via RedBoot"
+            flavor         bool
+            default_value  1
+            description    "
+               This option allows RedBoot to support booting of a Linux kernel."
+            compile -library=libextras.a redboot_linux_exec.c
+
+            cdl_component CYGOPT_REDBOOT_I386_BZIMAGE {
+                display       "Support loading linux bzImage via RedBoot"
+                flavor        bool
+                default_value 1
+                description   "
+                    This option allow RedBoot to support loading of a
+                    linux bzImage."
+            }
+
+            cdl_option CYGDAT_REDBOOT_I386_LINUX_BOOT_COMMAND_LINE {
+                display        "Default COMMAND_LINE"
+                flavor         data
+                default_value  { "" }
+            }
+        }
+    }
+
     
 }
Index: hal/i386/pc/current/include/platform.inc
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/i386/pc/current/include/platform.inc,v
retrieving revision 1.7
diff -u -p -r1.7 platform.inc
--- hal/i386/pc/current/include/platform.inc	23 May 2002 23:03:12 -0000	1.7
+++ hal/i386/pc/current/include/platform.inc	19 Jul 2002 04:22:48 -0000
@@ -77,6 +77,10 @@ hal_cpu_init_start:
 	# Disable interrupt handling.
 	cli
 
+#ifdef CYGSEM_REDBOOT_I386_LINUX_BOOT
+#include <cyg/hal/linux.inc>
+#endif        
+
 	# Make a GDT pointer in location 0 and load new GDTR
 	movw	$(gdtEnd - gdtStart),%ax
 	movw	%ax,0
@@ -137,6 +141,24 @@ gdtStart:
 	.byte	0x93
 	.byte	0xC7
 	.byte	0x00
+
+#ifdef CYGSEM_REDBOOT_I386_LINUX_BOOT
+        /* Selector 0x28 == code. real-mode boundary D-bit = 0*/
+        .word   0xFFFF
+        .word   0x0000
+        .byte   0x00
+        .byte   0x9B
+        .byte   0x00
+        .byte   0x00
+
+        /* Selector 0x30 == data. real-mode boundary D-bit = 0*/
+        .word   0xFFFF
+        .word   0x0000
+        .byte   0x00
+        .byte   0x93
+        .byte   0x00
+        .byte   0x00
+#endif
 
 	.align	4, 0xFF
 gdtEnd:
Index: hal/i386/pcmb/current/include/pcmb.inc
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/i386/pcmb/current/include/pcmb.inc,v
retrieving revision 1.3
diff -u -p -r1.3 pcmb.inc
--- hal/i386/pcmb/current/include/pcmb.inc	23 May 2002 23:03:15 -0000	1.3
+++ hal/i386/pcmb/current/include/pcmb.inc	19 Jul 2002 04:22:49 -0000
@@ -228,6 +228,10 @@ _endload:
 
 	/* Now we're all loaded up in memory. */
 
+#ifdef CYGSEM_REDBOOT_I386_LINUX_BOOT
+#include <cyg/hal/linux.inc>
+#endif        
+
 	/* Optionally switch to a high-res video before entering	*/
 	/* protected mode. The mode is controlled by an option in	*/
 	/* the RedBoot configuration, which is not readily visible	*/
@@ -357,6 +361,24 @@ gdtStart:
 	.byte	0x93
 	.byte	0xC7
 	.byte	0x00
+
+#ifdef CYGSEM_REDBOOT_I386_LINUX_BOOT
+        /* Selector 0x28 == code. real-mode boundary D-bit = 0*/
+        .word   0xFFFF
+        .word   0x0000
+        .byte   0x00
+        .byte   0x9B
+        .byte   0x00
+        .byte   0x00
+
+        /* Selector 0x30 == data. real-mode boundary D-bit = 0*/
+        .word   0xFFFF
+        .word   0x0000
+        .byte   0x00
+        .byte   0x93
+        .byte   0x00
+        .byte   0x00
+#endif
 
 	.align	4, 0xFF
 gdtEnd:
Index: redboot/current/include/redboot.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/include/redboot.h,v
retrieving revision 1.25
diff -u -p -r1.25 redboot.h
--- redboot/current/include/redboot.h	18 Jul 2002 20:05:22 -0000	1.25
+++ redboot/current/include/redboot.h	19 Jul 2002 04:22:52 -0000
@@ -89,7 +89,14 @@ EXTERN unsigned long workspace_size;
 EXTERN unsigned long entry_address;
 EXTERN unsigned long load_address;
 EXTERN unsigned long load_address_end;
+#ifdef CYGOPT_REDBOOT_I386_BZIMAGE
+EXTERN unsigned int linux_type;
 
+#define LINUX_RAW_IMAGE 0
+#define LINUX_ZIMAGE 1
+#define LINUX_BZIMAGE 2
+
+#endif
 
 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
 EXTERN bool console_selected;
Index: redboot/current/src/load.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/src/load.c,v
retrieving revision 1.26
diff -u -p -r1.26 load.c
--- redboot/current/src/load.c	18 Jul 2002 20:05:23 -0000	1.26
+++ redboot/current/src/load.c	19 Jul 2002 04:22:52 -0000
@@ -93,7 +93,7 @@ CYG_HAL_TABLE_END( __RedBoot_LOAD_TAB_EN
 extern struct load_io_entry __RedBoot_LOAD_TAB__[], __RedBoot_LOAD_TAB_END__;
 
 // Buffers, data used by redboot_getc
-#define BUF_SIZE 256
+#define BUF_SIZE 1024
 struct {
     getc_io_funcs_t *io;
     int (*fun)(char *, int len, int *err);
@@ -408,6 +408,78 @@ load_elf_image(getc_t getc, unsigned lon
 #endif // CYGSEM_REDBOOT_ELF
 }
 
+#ifdef CYGOPT_REDBOOT_I386_BZIMAGE
+
+#define LINUX_PARAM_UINT16(offset) ((cyg_uint16 *)(real_mode_kernel+offset))
+
+#define SUPPORTED_LINUX_VERSION 0x0202
+
+extern unsigned char **command_line;
+
+static unsigned long
+load_bzImage_image(int (*getc)(void))
+{
+    int res;
+    int i;
+
+    cyg_uint8 *real_mode_kernel = (cyg_uint8 *)0x90000;
+    cyg_uint8 *protect_mode_kernel = (cyg_uint8 *)0x100000;
+
+    cyg_uint8 *setup_sects = real_mode_kernel+0x1f1;
+    cyg_uint16 *root_flags = LINUX_PARAM_UINT16(0x1f2);
+    cyg_uint16 *vid_mode = LINUX_PARAM_UINT16(0x1fa);
+    cyg_uint16 *root_dev = LINUX_PARAM_UINT16(0x1fc);
+    cyg_uint16 *boot_flag = LINUX_PARAM_UINT16(0x1fe);
+
+    cyg_uint16 *version = LINUX_PARAM_UINT16(0x206);
+    cyg_uint16 *kernel_version = LINUX_PARAM_UINT16(0x20e);
+    cyg_uint8 *loadflags = real_mode_kernel+0x211;
+
+    cyg_uint8 *type_of_loader = real_mode_kernel+0x210;
+
+    cyg_uint32 *cmd_line_ptr = real_mode_kernel+0x228;
+
+    /* cyg_uint16 heap_end_ptr; FIXME: not supported yet */
+
+    for(i=0;i<0x230;i++) {
+      if((res = (*getc)()) >= 0) {
+	*(real_mode_kernel+i) = res;
+      } else {
+	diag_printf("error while reading bzImage header!\n");
+	return -1;
+      }
+    }
+
+    if (*setup_sects == 0) {
+      *setup_sects = 4;
+    }
+
+    if (*version < SUPPORTED_LINUX_VERSION) {
+      diag_printf("bzImage version %x not supported!\n", *version);
+      return 0;
+    }
+
+    *type_of_loader = 5;
+
+    *cmd_line_ptr = (cyg_uint32)command_line;
+
+    for(i=0x230; i<(*setup_sects+1)*512;i++)
+      *(real_mode_kernel+i) = (*getc)();
+
+    /* protect-mode kernel */
+    i = 0;
+    while((res = getc()) >= 0) {
+      *(protect_mode_kernel+i) = res;
+      i++;
+    }
+ 
+    diag_printf("Linux bzImage: %d bytes (setup %d bytes)\n", i, (*setup_sects)*512);
+
+    linux_type = LINUX_BZIMAGE;
+    return i;
+}
+#endif
+
 
 //
 // Scan a string of hex bytes and update the checksum
@@ -584,7 +656,11 @@ do_load(int argc, char *argv[])
 #endif
     unsigned long base = 0;
     unsigned long end = 0;
+#ifdef CYGOPT_REDBOOT_I386_BZIMAGE
+    char type[0x206];
+#else
     char type[4];
+#endif
     char *filename = 0;
     struct option_info opts[7];
     connection_info_t info;
@@ -751,6 +827,11 @@ do_load(int argc, char *argv[])
             } else if ((type[0] == 'S') &&
                        ((type[1] >= '0') && (type[1] <= '9'))) {
 		end = load_srec_image(redboot_getc, base);
+#ifdef CYGOPT_REDBOOT_I386_BZIMAGE
+	    } else if (strncmp(&type[0x202], "HdrS", 4) ==0) {
+	        end = load_bzImage_image(redboot_getc); 
+#endif
+
             } else {
                 redboot_getc_terminate(true);
                 diag_printf("Unrecognized image type: 0x%lx\n", *(unsigned long *)type);
--- /dev/null	Thu Jul 18 01:27:46 2002
+++ hal/i386/arch/current/include/linux.inc	Fri Jul 19 12:24:22 2002
@@ -0,0 +1,104 @@
+#ifndef CYGONCE_HAL_LINUX_INC
+#define CYGONCE_HAL_LINUX_INC
+##=============================================================================
+##
+##      linux.inc
+##
+##      linux support
+##
+##=============================================================================
+#####COPYRIGHTBEGIN####
+#                                                                          
+# -------------------------------------------                              
+# The contents of this file are subject to the Red Hat eCos Public License 
+# Version 1.1 (the "License"); you may not use this file except in         
+# compliance with the License.  You may obtain a copy of the License at    
+# http://www.redhat.com/                                                   
+#                                                                          
+# Software distributed under the License is distributed on an "AS IS"      
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+# License for the specific language governing rights and limitations under 
+# the License.                                                             
+#                                                                          
+# The Original Code is eCos - Embedded Configurable Operating System,      
+# released September 30, 1998.                                             
+#                                                                          
+# The Initial Developer of the Original Code is Red Hat.                   
+# Portions created by Red Hat are                                          
+# Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+# All Rights Reserved.                                                     
+# -------------------------------------------                              
+#                                                                          
+#####COPYRIGHTEND####
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):   taruishi
+## Contributors:
+## Date:        2002-07-05
+## Purpose:     linux boot support
+## Description: This file contains assembler macros needed to
+##		boot linux from eCos.
+##
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+	jmp linux_end
+
+.globl linux_gdt
+linux_gdt:
+	.word	linux_gdtEnd - linux_gdtStart
+	.long	linux_gdtStart
+
+	.align	4, 0xFF
+
+linux_gdtStart:
+	/* Selector 0x00 == invalid. */
+	.word	0x0000
+	.word	0x0000
+	.byte	0x00
+	.byte	0x00
+	.byte	0x00
+	.byte	0x00
+
+	/* Selector 0x08 == invalid. */
+	.word	0x0000
+	.word	0x0000
+	.byte	0x00
+	.byte	0x00
+	.byte	0x00
+	.byte	0x00
+
+	/* Selector 0x10 == code. */
+	.word	0xFFFF
+	.word	0x0000
+	.byte	0x00
+	.byte	0x9A
+	.byte	0xCF
+	.byte	0x00
+
+	/* Selector 0x18 == data. */
+	.word	0xFFFF
+	.word	0x0000
+	.byte	0x00
+	.byte	0x92
+	.byte	0xCF
+	.byte	0x00
+
+	.align	4, 0xFF
+linux_gdtEnd:
+
+linux_idt:
+	.globl linux_idt
+	.word 0
+	.long 0
+
+real_mode_idt:
+	.globl real_mode_idt
+	.word   0x03FF
+	.long   0 
+
+linux_end:
+#endif
\ No newline at end of file
--- /dev/null	Thu Jul 18 01:27:46 2002
+++ hal/i386/arch/current/src/redboot_linux_exec.c	Fri Jul 19 13:09:31 2002
@@ -0,0 +1,186 @@
+//==========================================================================
+//
+//      redboot_linux_exec.c
+//
+//      RedBoot exec command for Linux bzImage booting
+//
+//==========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2002 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.
+//
+// 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####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    taruishi
+// Contributors: 
+// Date:         2002-07-05
+// Purpose:      RedBoot exec command for Linux bzImage booting
+//
+// TODO: handle initrd, initial cursor location etc.
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#include <redboot.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.h>
+
+#define xstr(s) str(s)
+#define str(s...) #s
+
+static void do_exec(int argc, char *argv[]);
+RedBoot_cmd("exec",
+            "Execute linux",
+            "[-c \"kernel command line\"] [-w <timeout>]",
+            do_exec
+    );
+
+#define REAL_MODE_ADDR 0x90000
+#define COMMAND_LINE_ADDR 0x99000 
+
+const unsigned char **command_line = (unsigned char **)COMMAND_LINE_ADDR;
+
+#define LINUX_PARAM_UINT16(offset) ((cyg_uint16 *)(real_mode_kernel+offset))
+
+void
+do_exec(int argc, char *argv[])
+{
+  bool cmd_line_set, wait_time_set;
+  unsigned char *cmd_line = xstr(CYGDAT_REDBOOT_I386_LINUX_BOOT_COMMAND_LINE);
+  char *cmdp;
+  int wait_time, res;
+  struct option_info opts[2];
+  int oldints;
+  char line[8];
+
+  cyg_uint8 *real_mode_kernel = (cyg_uint8 *)REAL_MODE_ADDR;
+  cyg_uint16 *vid_mode = LINUX_PARAM_UINT16(0x1fa);
+  cyg_uint16 vid_val = 0;
+  int vid_mul;
+    
+  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, &cmd_line_set, "kernel command line");
+
+  if (!scan_opts(argc, argv, 1, opts, 2, NULL,
+		 OPTION_ARG_TYPE_NUM, ""))
+    return;
+
+  /* vga= special argument handling */
+  cmdp = cmd_line;
+  while(*cmdp != '\0') {
+    if (!memcmp(cmdp, "vga=", 4)) {
+      cmdp += 4;
+      if(!memcmp(cmdp, "normal", 6)) {
+        vid_val = 0xffff;
+      } else if(!memcmp(cmdp, "ext", 3)) {
+        vid_val = 0xfffe;
+      } else if(!memcmp(cmdp, "ask", 3)) {
+        vid_val = 0xfffd;
+      } else {
+	if(!memcmp(cmdp, "0x", 2)) {
+          cmdp += 2;
+	  vid_mul = 16;
+        } else if(*cmdp == '0') {
+          cmdp++;
+	  vid_mul = 8;
+        } else {
+	  vid_mul = 10;
+        }
+        while(*cmdp != '\0' && *cmdp != ' ') {
+          vid_val = vid_val * vid_mul;
+	  vid_val += *cmdp - '0';
+	 cmdp++;
+  	}
+      }
+      *vid_mode = vid_val;
+      break;
+    }
+    cmdp++;
+  }
+
+  strcpy(command_line, cmd_line);
+
+  diag_printf("Now booting linux kernel:\n");
+  diag_printf(" Cmdline : %s\n", command_line);
+
+  if (wait_time_set) {
+    diag_printf("About to start execution - abort with ^C within %d se
+conds\n", wait_time);
+    res = _rb_gets(line, sizeof(line), wait_time*1000);
+    if (res == _GETS_CTRLC) {
+      return;
+    }
+  }
+
+  HAL_DISABLE_INTERRUPTS(oldints);
+
+  asm volatile(" lidt real_mode_idt\n"
+
+	       /* set memory protect boundary to real-mode */
+
+	       " ljmp $0x28, $1f\n"
+	       "1:\n"
+	       " movw $0x30, %ax\n"
+	       " movw %ax, %ds\n"
+	       " movw %ax, %es\n"
+	       " movw %ax, %ss\n"
+	       " movw %ax, %fs\n"
+	       " movw %ax, %gs\n"
+
+	       /* now swith to real-mode */
+
+	       " movl %cr0, %eax\n"
+	       " andl $0xfffffffe, %eax\n"
+	       " movl %eax, %cr0\n"
+	       " jmp tmpseg\n"
+	       "tmpseg:\n"
+	       " ljmp $0, $realseg\n"
+	       "realseg:\n"
+	       ".code16\n"
+	       " xorw %ax, %ax\n"
+	       " movw %ax, %ds\n"
+	       " movw %ax, %es\n"
+	       " movw %ax, %ss\n"
+	       " movw %ax, %fs\n"
+	       " movw %ax, %gs\n"
+
+	       /* jump to linux setup segment */
+
+	       " ljmp $0x9020, $0\n"
+	       ".code32\n");
+
+}


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