Hopefully this is my last commit of major infrasture changes for a while.
Highlights: - elfboot.c Now can load images to the ram location where linuxBIOS is running - Added the standalone directory for bootloaders built from the linuxBIOS source Other things: - Correctly maode fallback_boot.c conditional - Added entry32.lds to do the math for segment descriptor table entries - Merged ldscript.cacheram and ldscript.base - Moved assembly code to the sections .rom.text and .rom.data - Modified linuxBIOS so C code completely runs from RAM as the SiS630 case does - Updated and commented example config files for the supermicro p4dc6 - Bumped the elfboot loader version to 1.0 - Removed extra carriage returns in dump_northbridge.inc (DOS->UNIX) - General cleanups to the config of the supermicro p4dc6
This commit is contained in:
parent
5346fd33f9
commit
0f7f76fb40
56 changed files with 1191 additions and 375 deletions
|
|
@ -2,6 +2,8 @@
|
|||
#include <boot/elf.h>
|
||||
#include <boot/elf_boot.h>
|
||||
#include <string.h>
|
||||
#include <printk.h>
|
||||
|
||||
|
||||
#ifndef CMD_LINE
|
||||
#define CMD_LINE ""
|
||||
|
|
@ -65,21 +67,115 @@ int elf_check_arch(Elf_ehdr *ehdr)
|
|||
|
||||
}
|
||||
|
||||
void jmp_to_elf_entry(void *entry)
|
||||
void jmp_to_elf_entry(void *entry, unsigned long buffer)
|
||||
{
|
||||
unsigned long type = 0x0E1FB007;
|
||||
extern unsigned char _ram_seg, _eram_seg;
|
||||
unsigned long lb_start, lb_size;
|
||||
unsigned long adjust, adjusted_boot_notes;
|
||||
unsigned long type;
|
||||
|
||||
elf_boot_notes.hdr.b_checksum =
|
||||
compute_ip_checksum(&elf_boot_notes, sizeof(elf_boot_notes));
|
||||
|
||||
type = 0x0E1FB007;
|
||||
lb_start = (unsigned long)&_ram_seg;
|
||||
lb_size = (unsigned long)(&_eram_seg - &_ram_seg);
|
||||
adjust = buffer + lb_size - lb_start;
|
||||
|
||||
adjusted_boot_notes = (unsigned long)&elf_boot_notes;
|
||||
adjusted_boot_notes += adjust;
|
||||
|
||||
printk_spew("entry = 0x%08lx\n", (unsigned long)entry);
|
||||
printk_spew("lb_start = 0x%08lx\n", lb_start);
|
||||
printk_spew("lb_size = 0x%08lx\n", lb_size);
|
||||
printk_spew("adjust = 0x%08lx\n", adjust);
|
||||
printk_spew("buffer = 0x%08lx\n", buffer);
|
||||
printk_spew("adjusted_boot_notes = 0x%08lx\n", adjusted_boot_notes);
|
||||
|
||||
/* Jump to kernel */
|
||||
__asm__ __volatile__(
|
||||
"pushl %0\n\t"
|
||||
"pushl %1\n\t"
|
||||
"pushl %2\n\t"
|
||||
"popl %%ebx\n\t"
|
||||
"popl %%eax\n\t"
|
||||
"ret\n\t"
|
||||
:: "g" (entry), "g"(type), "g"(&elf_boot_notes));
|
||||
" cld \n\t"
|
||||
/* Save the callee save registers... */
|
||||
" pushl %%esi\n\t"
|
||||
" pushl %%edi\n\t"
|
||||
" pushl %%ebx\n\t"
|
||||
/* Save the parameters I was passed */
|
||||
" pushl $0\n\t" /* 20 adjust */
|
||||
" pushl %0\n\t" /* 16 lb_start */
|
||||
" pushl %1\n\t" /* 12 buffer */
|
||||
" pushl %2\n\t" /* 8 lb_size */
|
||||
" pushl %3\n\t" /* 4 entry */
|
||||
" pushl %4\n\t" /* 0 elf_boot_notes */
|
||||
/* Compute the adjustment */
|
||||
" xorl %%eax, %%eax\n\t"
|
||||
" subl 16(%%esp), %%eax\n\t"
|
||||
" addl 12(%%esp), %%eax\n\t"
|
||||
" addl 8(%%esp), %%eax\n\t"
|
||||
" movl %%eax, 20(%%esp)\n\t"
|
||||
/* Place a copy of linuxBIOS in it's new location */
|
||||
/* Move ``longs'' the linuxBIOS size is 4 byte aligned */
|
||||
" movl 12(%%esp), %%edi\n\t"
|
||||
" addl 8(%%esp), %%edi\n\t"
|
||||
" movl 16(%%esp), %%esi\n\t"
|
||||
" movl 8(%%esp), %%ecx\n\n"
|
||||
" shrl $2, %%ecx\n\t"
|
||||
" rep movsl\n\t"
|
||||
|
||||
/* Adjust the stack pointer to point into the new linuxBIOS image */
|
||||
" addl 20(%%esp), %%esp\n\t"
|
||||
/* Adjust the instruction pointer to point into the new linuxBIOS image */
|
||||
" movl $1f, %%eax\n\t"
|
||||
" addl 20(%%esp), %%eax\n\t"
|
||||
" jmp *%%eax\n\t"
|
||||
"1: \n\t"
|
||||
|
||||
/* Copy the linuxBIOS bounce buffer over linuxBIOS */
|
||||
/* Move ``longs'' the linuxBIOS size is 4 byte aligned */
|
||||
" movl 16(%%esp), %%edi\n\t"
|
||||
" movl 12(%%esp), %%esi\n\t"
|
||||
" movl 8(%%esp), %%ecx\n\t"
|
||||
" shrl $2, %%ecx\n\t"
|
||||
" rep movsl\n\t"
|
||||
|
||||
/* Now jump to the loaded image */
|
||||
" movl 0(%%esp), %%eax\n\t"
|
||||
" movl $0x0E1FB007, %%ebx\n\t"
|
||||
" call *4(%%esp)\n\t"
|
||||
|
||||
/* The loaded image returned? */
|
||||
" cli \n\t"
|
||||
" cld \n\t"
|
||||
|
||||
/* Copy the saved copy of linuxBIOS where linuxBIOS runs */
|
||||
/* Move ``longs'' the linuxBIOS size is 4 byte aligned */
|
||||
" movl 16(%%esp), %%edi\n\t"
|
||||
" movl 12(%%esp), %%esi\n\t"
|
||||
" addl 8(%%esp), %%esi\n\t"
|
||||
" movl 8(%%esp), %%ecx\n\t"
|
||||
" shrl $2, %%ecx\n\t"
|
||||
" rep movsl\n\t"
|
||||
|
||||
/* Adjust the stack pointer to point into the old linuxBIOS image */
|
||||
" subl 20(%%esp), %%esp\n\t"
|
||||
|
||||
/* Adjust the instruction pointer to point into the old linuxBIOS image */
|
||||
" movl $1f, %%eax\n\t"
|
||||
" subl 20(%%esp), %%eax\n\t"
|
||||
" jmp *%%eax\n\t"
|
||||
"1: \n\t"
|
||||
|
||||
/* Drop the parameters I was passed */
|
||||
" addl $24, %%esp\n\t"
|
||||
|
||||
/* Restore the callee save registers */
|
||||
" popl %%ebx\n\t"
|
||||
" popl %%edi\n\t"
|
||||
" popl %%esi\n\t"
|
||||
|
||||
::
|
||||
"g" (lb_start), "g" (buffer), "g" (lb_size),
|
||||
"g" (entry), "g"(&adjusted_boot_notes)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -142,11 +142,16 @@ unsigned long lb_table_fini(struct lb_header *head)
|
|||
return (unsigned long)rec;
|
||||
}
|
||||
|
||||
unsigned long setup_memory_table(
|
||||
struct lb_memory *mem,
|
||||
unsigned long totalram,
|
||||
unsigned long low_table_start, unsigned long low_table_end)
|
||||
|
||||
/* Routines to extract part so the linuxBIOS table or
|
||||
* information from the linuxBIOS table after we have written it.
|
||||
* Currently get_lb_mem relies on a global we can change the
|
||||
* implementaiton.
|
||||
*/
|
||||
static struct lb_memory *mem_ranges = 0;
|
||||
struct lb_memory *get_lb_mem(void)
|
||||
{
|
||||
return mem_ranges;
|
||||
}
|
||||
|
||||
unsigned long write_linuxbios_table(
|
||||
|
|
@ -173,5 +178,8 @@ unsigned long write_linuxbios_table(
|
|||
lb_memory_range(mem, LB_MEM_RAM, 0x00100000, (totalram - 1024) << 10);
|
||||
|
||||
low_table_end = lb_table_fini(head);
|
||||
|
||||
/* Remember where my valid memory ranges are */
|
||||
mem_ranges = mem;
|
||||
return low_table_end;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/* -*- asm -*-
|
||||
* $ $
|
||||
*
|
||||
*/
|
||||
|
|
@ -11,20 +11,14 @@
|
|||
#include <cpu/p6/apic.h>
|
||||
#endif
|
||||
/*
|
||||
* This is the entry code (the mkrom(8) utility makes a jumpvector
|
||||
* to this adddess.
|
||||
* This is the entry code the code in .reset section
|
||||
* jumps to this address.
|
||||
*
|
||||
* When we get here we are in x86 real mode.
|
||||
*
|
||||
* %cs = 0xf000 %ip = 0x0000
|
||||
* %ds = 0x0000 %es = 0x0000
|
||||
* %dx = 0x0yxx (y = 3 for i386, 5 for pentium, 6 for P6,
|
||||
* where x is undefined)
|
||||
* %fl = 0x0002
|
||||
*/
|
||||
.text
|
||||
.section ".rom.data", "a", @progbits
|
||||
.section ".rom.text", "ax", @progbits
|
||||
|
||||
CRT0_PARAMETERS
|
||||
#include "crt0_includes.h"
|
||||
|
||||
CONSOLE_DEBUG_TX_STRING($str_after_ram)
|
||||
|
||||
|
|
@ -41,15 +35,20 @@ __main:
|
|||
|
||||
cld /* clear direction flag */
|
||||
|
||||
/* copy data segment from FLASH ROM to RAM */
|
||||
leal EXT(_ldata), %esi
|
||||
leal EXT(_data), %edi
|
||||
movl $EXT(_eldata), %ecx
|
||||
/* copy linuxBIOS from it's initial load location to
|
||||
* the location it is compiled to run at.
|
||||
* Normally this is copying from FLASH ROM to RAM.
|
||||
*/
|
||||
leal EXT(_liseg), %esi
|
||||
leal EXT(_iseg), %edi
|
||||
cmpl %esi, %edi
|
||||
jz .Lnocopy
|
||||
movl $EXT(_eliseg), %ecx
|
||||
subl %esi, %ecx
|
||||
jz .Lnodata /* should not happen */
|
||||
jz .Lnocopy /* should not happen */
|
||||
rep
|
||||
movsb
|
||||
.Lnodata:
|
||||
.Lnocopy:
|
||||
intel_chip_post_macro(0x12) /* post 12 */
|
||||
|
||||
/** clear stack */
|
||||
|
|
@ -124,7 +123,7 @@ __main:
|
|||
hlt
|
||||
jmp .Lhlt
|
||||
|
||||
.section ".rodata"
|
||||
.section ".rom.data"
|
||||
str_after_ram: .string "Ram Initialize?\r\n"
|
||||
str_pre_main: .string "before main\r\n"
|
||||
.previous
|
||||
|
|
|
|||
|
|
@ -33,18 +33,32 @@ ENTRY(_start)
|
|||
|
||||
SECTIONS
|
||||
{
|
||||
. = DEFINED(_ROMBASE)? _ROMBASE : _RAMBASE;
|
||||
/* This section might be better named .setup */
|
||||
.rom . : {
|
||||
_rom = .;
|
||||
*(.rom.text);
|
||||
*(.rom.data);
|
||||
. = ALIGN(16);
|
||||
_erom = .;
|
||||
}
|
||||
_lrom = LOADADDR(.rom);
|
||||
_elrom = LOADADDR(.rom) + SIZEOF(.rom);
|
||||
. = DEFINED(_ROMBASE)? _RAMBASE : . ;
|
||||
/*
|
||||
* First we place the code and read only data (typically const declared).
|
||||
* This get placed in rom.
|
||||
*/
|
||||
. = _ROMBASE;
|
||||
.text (.) : {
|
||||
.text . : AT (_elrom) {
|
||||
_text = .;
|
||||
*(.text);
|
||||
*(.text.*);
|
||||
. = ALIGN(16);
|
||||
_etext = .;
|
||||
}
|
||||
.rodata (.) : {
|
||||
_ltext = LOADADDR(.text);
|
||||
_eltext = LOADADDR(.text) + SIZEOF(.text);
|
||||
.rodata . : AT(_eltext){
|
||||
_rodata = .;
|
||||
. = ALIGN(4);
|
||||
streams = . ;
|
||||
|
|
@ -53,10 +67,9 @@ SECTIONS
|
|||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
_erodata = .;
|
||||
}
|
||||
|
||||
. = _RAMBASE;
|
||||
|
||||
}
|
||||
_lrodata = LOADADDR(.rodata);
|
||||
_elrodata = LOADADDR(.rodata) + SIZEOF(.rodata);
|
||||
/*
|
||||
* After the code we place initialized data (typically initialized
|
||||
* global variables). This gets copied into ram by startup code.
|
||||
|
|
@ -64,19 +77,26 @@ SECTIONS
|
|||
* whereas __data_loadstart and __data_loadend shows where in rom to
|
||||
* copy from.
|
||||
*/
|
||||
.data (.): AT(_erodata) {
|
||||
.data . : AT(_elrodata) {
|
||||
_data = .;
|
||||
*(.data)
|
||||
_edata = .;
|
||||
}
|
||||
_ldata = LOADADDR(.data);
|
||||
_eldata = LOADADDR(.data) + SIZEOF(.data);
|
||||
/* The initialized data segment.
|
||||
* This is all of the data that we copy from rom into the ram.
|
||||
*/
|
||||
_iseg = _text;
|
||||
_eiseg = _edata;
|
||||
_liseg = _ltext;
|
||||
_eliseg = _eldata;
|
||||
/*
|
||||
* bss does not contain data, it is just a space that should be zero
|
||||
* initialized on startup. (typically uninitialized global variables)
|
||||
* crt0.S fills between _bss and _ebss with zeroes.
|
||||
*/
|
||||
.bss (.): {
|
||||
.bss . : {
|
||||
_bss = .;
|
||||
*(.bss)
|
||||
*(.sbss)
|
||||
|
|
@ -84,20 +104,24 @@ SECTIONS
|
|||
_ebss = .;
|
||||
}
|
||||
_end = .;
|
||||
|
||||
.heap (.): {
|
||||
_heap = .;
|
||||
/* Reserve 256K for the heap */
|
||||
. = HEAP_SIZE ;
|
||||
_eheap = .;
|
||||
}
|
||||
.stack (.) : {
|
||||
.stack . : {
|
||||
_stack = .;
|
||||
/* Reserve a stack for each possible cpu, +1 extra */
|
||||
. = ((MAX_CPUS * STACK_SIZE) + STACK_SIZE) ;
|
||||
_estack = .;
|
||||
}
|
||||
|
||||
.heap . : {
|
||||
_heap = .;
|
||||
/* Reserve 256K for the heap */
|
||||
. = HEAP_SIZE ;
|
||||
. = ALIGN(4);
|
||||
_eheap = .;
|
||||
}
|
||||
/* The ram segment
|
||||
* This is all address of the memory resident copy of linuxBIOS.
|
||||
*/
|
||||
_ram_seg = _text;
|
||||
_eram_seg = _eheap;
|
||||
/DISCARD/ : {
|
||||
*(.comment)
|
||||
*(.note)
|
||||
|
|
|
|||
|
|
@ -13,9 +13,7 @@ option STACK_SIZE=0x2000
|
|||
# By default on x86 we have a memory hole between 640K and 1MB
|
||||
option MEMORY_HOLE=1
|
||||
|
||||
option USE_DEFAULT_LAYOUT=1
|
||||
ldscript arch/i386/config/ldscript.base USE_DEFAULT_LAYOUT
|
||||
ldscript arch/i386/config/ldscript.cacheram USE_CACHE_RAM
|
||||
ldscript arch/i386/config/ldscript.base
|
||||
|
||||
# How do I add -mprefered-stack-boundary=2 if the compiler supports it?
|
||||
# On x86 tt results in a code size reduction.
|
||||
|
|
|
|||
|
|
@ -6,11 +6,18 @@
|
|||
#endif
|
||||
|
||||
#if !defined(ASSEMBLY)
|
||||
#define CACHE_RAM_SEG_BASE (((unsigned long)CACHE_RAM_BASE) - ((unsigned long)_RAMBASE))
|
||||
extern char _cache_ram_seg_base[];
|
||||
#define CACHE_RAM_SEG_BASE ((unsigned long)_cache_ram_seg_base)
|
||||
#else
|
||||
#define CACHE_RAM_SEG_BASE (CACHE_RAM_BASE - _RAMBASE)
|
||||
#define CACHE_RAM_SEG_BASE (_cache_ram_seg_base)
|
||||
#endif
|
||||
|
||||
#if !defined(ASSEMBLY)
|
||||
extern char _rom_code_seg_base[];
|
||||
#define ROM_CODE_SEG_BASE ((unsigned long)_rom_code_seg_base)
|
||||
#else
|
||||
#define ROM_CODE_SEG_BASE (_rom_code_seg_base)
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(ASSEMBLY)
|
||||
|
|
|
|||
|
|
@ -4,17 +4,16 @@ jmp cpu_reset_out
|
|||
#include <loglevel.h>
|
||||
|
||||
|
||||
.section ".rodata"
|
||||
.section ".rom.data"
|
||||
|
||||
#if ASM_CONSOLE_LOGLEVEL >= BIOS_SPEW
|
||||
cpu_reset_str: .string "cpu_reset\r\n";
|
||||
cpu_apic_str: .string "apic: ";
|
||||
cpu_size_set_str: .string "cpu memory size set\r\n";
|
||||
#endif
|
||||
.previous
|
||||
|
||||
|
||||
.text
|
||||
|
||||
__cpu_reset:
|
||||
CONSOLE_SPEW_TX_STRING($cpu_reset_str)
|
||||
|
||||
|
|
|
|||
25
src/arch/i386/standalone/crt0.S
Normal file
25
src/arch/i386/standalone/crt0.S
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* $ $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <arch/asm.h>
|
||||
#include <arch/intel.h>
|
||||
|
||||
.section ".rom.data", "a", @progbits
|
||||
.section ".rom.text", "ax", @progbits
|
||||
|
||||
#include "crt0_includes.h"
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
|
||||
/* set new stack */
|
||||
movl $_estack, %esp
|
||||
call EXT(standalonemain)
|
||||
/*NOTREACHED*/
|
||||
.Lhlt:
|
||||
intel_chip_post_macro(0xee) /* post fe */
|
||||
hlt
|
||||
jmp .Lhlt
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue