Author: mcayland Date: Fri Apr 2 15:01:10 2010 New Revision: 726 URL: http://tracker.coreboot.org/trac/openbios/changeset/726
Log: The new loader APIs in libopenbios already have routines to detect the type of executable at a given address and react accordingly. Hence since the loaders are currently written in C, it makes more sense to drop down into C and re-use the same code rather than have a second implementation in Forth.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk
Added: trunk/openbios-devel/include/libopenbios/initprogram.h trunk/openbios-devel/libopenbios/initprogram.c Modified: trunk/openbios-devel/forth/debugging/client.fs trunk/openbios-devel/libopenbios/aout_load.c trunk/openbios-devel/libopenbios/build.xml trunk/openbios-devel/libopenbios/init.c
Modified: trunk/openbios-devel/forth/debugging/client.fs ============================================================================== --- trunk/openbios-devel/forth/debugging/client.fs Fri Apr 2 13:41:35 2010 (r725) +++ trunk/openbios-devel/forth/debugging/client.fs Fri Apr 2 15:01:10 2010 (r726) @@ -16,6 +16,7 @@
\ 7.6.2 Program download and execute + struct ( saved-program-state ) /n field >sps.entry /n field >sps.file-size @@ -32,7 +33,8 @@
: load-size file-size @ ;
-variable file-type + +\ File types identified by (init-program)
0 constant elf-boot 1 constant elf @@ -43,289 +45,13 @@ 10 constant fcode 11 constant forth
-\ Array indexes and values for e_type - -d# 16 constant EI_NIDENT - -0 constant EI_MAG0 - h# 7f constant ELFMAG0 - -1 constant EI_MAG1 - [CHAR] E constant ELFMAG1 - -2 constant EI_MAG2 - [CHAR] L constant ELFMAG2 - -3 constant EI_MAG3 - [CHAR] F constant ELFMAG3 - -4 constant EI_CLASS - 0 constant ELFCLASSNONE - 1 constant ELFCLASS32 - 2 constant ELFCLASS64 - -5 constant EI_DATA - 0 constant ELFDATANONE - 1 constant ELFDATA2LSB - 2 constant ELFDATA2MSB - -6 constant EI_VERSION - 0 constant EV_NONE - 1 constant EV_CURRENT - -\ Values for e_type - -0 constant ET_NONE -1 constant ET_REL -2 constant ET_EXEC -3 constant ET_DYN -4 constant ET_CORE - -\ Values for e_machine - -d# 2 constant EM_SPARC -d# 3 constant EM_386 -d# 6 constant EM_486 -d# 18 constant EM_SPARC32PLUS -d# 20 constant EM_PPC -d# 43 constant EM_SPARCV9 - -/l constant Elf32_Addr -/w constant Elf32_Half -/l constant Elf32_Off -/l constant Elf32_Sword -/l constant Elf32_Word -/l constant Elf32_Size - -struct ( ELF header ) - EI_NIDENT field >Elf32_Ehdr.e_ident ( File identification ) - Elf32_Half field >Elf32_Ehdr.e_type ( File type ) - Elf32_Half field >Elf32_Ehdr.e_machine ( Machine archicture ) - Elf32_Word field >Elf32_Ehdr.e_version ( ELF format version ) - Elf32_Addr field >Elf32_Ehdr.e_entry ( Entry point ) - Elf32_Off field >Elf32_Ehdr.e_phoff ( Program header file offset ) - Elf32_Off field >Elf32_Ehdr.e_shoff ( Section header file offset ) - Elf32_Word field >Elf32_Ehdr.e_flags ( Architecture specific flags ) - Elf32_Half field >Elf32_Ehdr.e_ehsize ( Size of ELF header in bytes ) - Elf32_Half field >Elf32_Ehdr.e_phentsize ( Size of program header entries ) - Elf32_Half field >Elf32_Ehdr.e_phnum ( Number of program header entry ) - Elf32_Half field >Elf32_Ehdr.e_shentsize ( Size of section header entry ) - Elf32_Half field >Elf32_Ehdr.e_shnum ( Number of section header entries ) - Elf32_Half field >Elf32_Ehdr.e_shstrndx ( Section name strings section ) -constant /Elf32_Ehdr - -: @e_ident ( base index -- byte ) - swap >Elf32_Ehdr.e_ident + c@ -; - -: @e_type ( base -- type ) - >Elf32_Ehdr.e_type w@ -; - -: @e_machine ( base -- type ) - >Elf32_Ehdr.e_machine w@ -; - -: @e_entry ( base -- entry ) - >Elf32_Ehdr.e_entry l@ -; - -: @e_phoff ( base -- poffset ) - >Elf32_Ehdr.e_phoff l@ -; - -: @e_phnum ( base -- pnum ) - >Elf32_Ehdr.e_phnum w@ -; - -: elf? - " load-base" evaluate - dup EI_MAG0 @e_ident - ELFMAG0 <> if drop false exit then - dup EI_MAG1 @e_ident - ELFMAG1 <> if drop false exit then - dup EI_MAG2 @e_ident - ELFMAG2 <> if drop false exit then - dup EI_MAG3 @e_ident - ELFMAG3 <> if drop false exit then - dup EI_CLASS @e_ident -[IFDEF] CONFIG_SPARC64 - ELFCLASS64 <> if drop false exit then -[ELSE] - ELFCLASS32 <> if drop false exit then -[THEN] - dup EI_DATA @e_ident - " little-endian?" evaluate if - ELFDATA2LSB <> if drop false exit then - else - ELFDATA2MSB <> if drop false exit then - then - dup @e_type - ET_EXEC <> if drop false exit then ( not executable ) - @e_machine -[IFDEF] CONFIG_PPC - EM_PPC <> if false exit then -[THEN] -[IFDEF] CONFIG_X86 - dup - EM_386 <> if - EM_486 <> if - false exit - then - else - drop - then -[THEN] -[IFDEF] CONFIG_SPARC32 - dup - EM_SPARC <> if - EM_SPARC32PLUS <> if - false exit - then - else - drop - then -[THEN] -[IFDEF] CONFIG_SPARC64 - EM_SPARCV9 <> if false exit then -[THEN] - true - ; - -variable elf-entry -variable xcoff-entry -variable bootinfo-entry -variable bootinfo-size - -: init-program-elf - elf file-type ! - " /packages/elf-loader" open-dev dup if - dup - " init-program" rot $call-method - close-dev - else - drop - ." /packages/elf-loader is missing" cr - then -; - -: xcoff? - " load-base" evaluate w@ - h# 1df <> if - false - exit - then - true - ; - -: init-program-xcoff - xcoff file-type ! - " /packages/xcoff-loader" open-dev dup if - dup - " init-program" rot $call-method - close-dev - else - drop - ." /packages/xcoff-loader is missing" cr - then - ; - -: pe? - false -; - -: init-program-pe - pe file-type ! - " /packages/pe-loader" open-dev dup if - dup - " init-program" rot $call-method - close-dev - else - drop - ." /packages/pe-loader is missing" cr - then - ; - -: bootinfo? - " load-base" evaluate dup - " <CHRP-BOOT>" comp 0= if - drop - true - exit - then - " <chrp-boot>" comp 0= if - true - exit - then - false - ; - -: init-program-bootinfo - bootinfo file-type ! - " /packages/bootinfo-loader" open-dev dup if - dup - " init-program" rot $call-method - close-dev - else - drop - ." /packages/bootinfo-loader is missing" cr - then - ; - -: fcode? - " load-base" evaluate c@ - dup h# f0 = if \ start0 - drop - true - exit - then - dup h# f1 = if \ start1 - drop - true - exit - then - dup h# f2 = if \ start2 - drop - true - exit - then - dup h# f3 = if \ start4 - drop - true - exit - then - h# fd = if \ version1 - true - exit - then - false - ; - -: init-program-fcode - " load-base" evaluate 8 + - 1 byte-load - ;
: init-program ( -- ) - elf? if - init-program-elf - exit - then - xcoff? if - init-program-xcoff - exit - then - pe? if - init-program-pe - exit - then - bootinfo? if - init-program-bootinfo - exit - then - fcode? if - init-program-fcode - exit + \ Call down to the lower level for relocation etc. + s" (init-program)" $find if + execute + else + s" Unable to locate (init-program)!" type cr then ;
@@ -372,29 +98,21 @@
: go ( -- ) state-valid @ not if exit then - elf file-type @ = if + elf saved-program-state >sps.file-type @ = if [IFDEF] CONFIG_PPC - elf-entry @ " (go)" evaluate + saved-program-state >sps.entry @ " (go)" evaluate [ELSE] ." go is not yet implemented" [THEN] else - xcoff file-type @ = if + xcoff saved-program-state >sps.file-type @ = if [IFDEF] CONFIG_PPC - xcoff-entry @ " (go)" evaluate + saved-program-state >sps.entry @ " (go)" evaluate [ELSE] ." go is not yet implemented" [THEN] else - bootinfo file-type @ = if -[IFDEF] CONFIG_PPC - bootinfo-entry @ bootinfo-size @ evaluate -[ELSE] - ." go is not yet implemented" -[THEN] - else - ." go is not yet implemented" - then + ." go is not yet implemented" then then ;
Added: trunk/openbios-devel/include/libopenbios/initprogram.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/openbios-devel/include/libopenbios/initprogram.h Fri Apr 2 15:01:10 2010 (r726) @@ -0,0 +1,22 @@ +/* + * Creation Date: <2010/04/02 13:00:00 mcayland> + * Time-stamp: <2010/04/02 13:00:00 mcayland> + * + * <initprogram.h> + * + * C implementation of (init-program) word + * + * Copyright (C) 2010 Mark Cave-Ayland (mark.cave-ayland@siriusit.co.uk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 + * + */ + +#ifndef _H_INITPROGRAM +#define _H_INITPROGRAM + +extern void init_program(void); + +#endif /* _H_INITPROGRAM */
Modified: trunk/openbios-devel/libopenbios/aout_load.c ============================================================================== --- trunk/openbios-devel/libopenbios/aout_load.c Fri Apr 2 13:41:35 2010 (r725) +++ trunk/openbios-devel/libopenbios/aout_load.c Fri Apr 2 15:01:10 2010 (r726) @@ -10,7 +10,6 @@ #define CONFIG_SPARC64_PAGE_SIZE_8KB #endif
-#include "arch/common/a.out.h" #include "libopenbios/sys_info.h" #include "libopenbios/bindings.h" #include "libopenbios/aout_load.h"
Modified: trunk/openbios-devel/libopenbios/build.xml ============================================================================== --- trunk/openbios-devel/libopenbios/build.xml Fri Apr 2 13:41:35 2010 (r725) +++ trunk/openbios-devel/libopenbios/build.xml Fri Apr 2 15:01:10 2010 (r726) @@ -13,6 +13,7 @@ <object source="fcode_load.c" condition="LOADER_FCODE"/> <object source="forth_load.c" condition="LOADER_FORTH"/> <object source="init.c"/> + <object source="initprogram.c"/> <object source="ipchecksum.c"/> <object source="linuxbios_info.c" condition="LINUXBIOS"/> <object source="ofmem_common.c" condition="OFMEM"/>
Modified: trunk/openbios-devel/libopenbios/init.c ============================================================================== --- trunk/openbios-devel/libopenbios/init.c Fri Apr 2 13:41:35 2010 (r725) +++ trunk/openbios-devel/libopenbios/init.c Fri Apr 2 15:01:10 2010 (r726) @@ -16,9 +16,12 @@
#include "config.h" #include "libopenbios/openbios.h" +#include "libopenbios/bindings.h" +#include "libopenbios/initprogram.h"
void openbios_init( void ) { - // TODO + // Bind the C implementation of (init-program) into Forth + bind_func("(init-program)", init_program); }
Added: trunk/openbios-devel/libopenbios/initprogram.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/openbios-devel/libopenbios/initprogram.c Fri Apr 2 15:01:10 2010 (r726) @@ -0,0 +1,85 @@ +/* + * Creation Date: <2010/04/02 13:00:00 mcayland> + * Time-stamp: <2010/04/02 13:00:00 mcayland> + * + * <initprogram.c> + * + * C implementation of (init-program) word + * + * Copyright (C) 2010 Mark Cave-Ayland (mark.cave-ayland@siriusit.co.uk) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 + * + */ + +#include "config.h" +#include "kernel/kernel.h" +#include "libopenbios/bindings.h" +#include "libopenbios/initprogram.h" + +/* Because the a.out loader requires platform-specific headers */ +#ifdef CONFIG_LOADER_AOUT +#include "libopenbios/aout_load.h" +#endif + +#include "libopenbios/bootinfo_load.h" +#include "libopenbios/elf_load.h" +#include "libopenbios/fcode_load.h" +#include "libopenbios/forth_load.h" +#include "libopenbios/xcoff_load.h" + + +void init_program(void) +{ + /* Get the value of load-base and use it to determine the correct loader + to use */ + ucell addr; + + feval("load-base"); + addr = POP(); + +#ifdef CONFIG_LOADER_AOUT + if (is_aout((struct exec *)addr)) { + aout_init_program(); + return; + } +#endif + +#ifdef CONFIG_LOADER_BOOTINFO + if (is_bootinfo((char *)addr)) { + bootinfo_init_program(); + return; + } +#endif + +#ifdef CONFIG_LOADER_ELF + if (is_elf((Elf_ehdr *)addr)) { + elf_init_program(); + return; + } +#endif + +#ifdef CONFIG_LOADER_FCODE + if (is_fcode((unsigned char *)addr)) { + fcode_init_program(); + return; + } +#endif + +#ifdef CONFIG_LOADER_FORTH + if (is_forth((char *)addr)) { + forth_init_program(); + return; + } +#endif + +#ifdef CONFIG_LOADER_XCOFF + if (is_xcoff((COFF_filehdr_t *)addr)) { + xcoff_init_program(); + return; + } +#endif + +}