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:
Eric W. Biederman 2002-01-16 05:54:23 +00:00
commit 0f7f76fb40
56 changed files with 1191 additions and 375 deletions

View file

@ -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)
);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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)

View file

@ -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.

View file

@ -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)

View file

@ -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)

View 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