mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
This set of changes allows FILO to boot in bochs:
Press <Enter> for default boot, or <Esc> for boot prompt... timed out boot: hdc1:/phase1 root=/dev/hdc1 console=ttyS0,115200 malloc_diag: alloc: 112 bytes (3 blocks), free: 16264 bytes (1 blocks) malloc_diag: alloc: 128 bytes (4 blocks), free: 16248 bytes (1 blocks) file_open: dev=hdc1, path=/phase1 find_ide_controller: PCI IDE #0 not found IDE channel 1 not found devopen: failed to open ide malloc_diag: alloc: 112 bytes (3 blocks), free: 16264 bytes (1 blocks) malloc_diag: alloc: 48 bytes (2 blocks), free: 16328 bytes (1 blocks) boot: hdc1:/phase1 root=/dev/hdc1 console=ttyS0,115200 So we've just booted our first payload in V3! Signed-off-by: Ronald G. Minnich <rminnich@gmail.com> Acked-by: Ronald G. Minnich <rminnich@gmail.com> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@110 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
98d3059a2d
commit
326b94d572
2 changed files with 21 additions and 117 deletions
|
@ -67,114 +67,14 @@ int elf_check_arch(Elf_ehdr *ehdr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* there used to be lots of complexity here to deal with the fact that this code ran in
|
||||||
|
* RAM. The code was awesome in its power, incomprehensible to most.
|
||||||
|
* But this code runs in ROM now, so the complexity went away
|
||||||
|
*/
|
||||||
void jmp_to_elf_entry(void *entry)
|
void jmp_to_elf_entry(void *entry)
|
||||||
{
|
{
|
||||||
#ifdef NOTYET
|
int (*v)() = entry;
|
||||||
extern unsigned char _ram_seg, _eram_seg;
|
v();
|
||||||
unsigned long lb_start, lb_size;
|
|
||||||
unsigned long 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);
|
|
||||||
|
|
||||||
adjusted_boot_notes = (unsigned long)&elf_boot_notes;
|
|
||||||
|
|
||||||
printk(BIOS_SPEW, "entry = 0x%08lx\n", (unsigned long)entry);
|
|
||||||
printk(BIOS_SPEW, "lb_start = 0x%08lx\n", lb_start);
|
|
||||||
printk(BIOS_SPEW, "lb_size = 0x%08lx\n", lb_size);
|
|
||||||
printk(BIOS_SPEW, " elf_boot_notes = 0x%08lx\n", (unsigned long)&elf_boot_notes);
|
|
||||||
printk(BIOS_SPEW, "adjusted_boot_notes = 0x%08lx\n", adjusted_boot_notes);
|
|
||||||
|
|
||||||
/* Jump to kernel */
|
|
||||||
__asm__ __volatile__(
|
|
||||||
" 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 $0x0E1FB007, %%eax\n\t"
|
|
||||||
" movl 0(%%esp), %%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)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -53,12 +53,17 @@ static int valid_area(struct lb_memory *mem,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_elf_segments(struct lb_memory *mem,Elf_phdr *phdr, int headers)
|
static int load_elf_segments(struct lb_memory *mem,unsigned char *header, int headers)
|
||||||
{
|
{
|
||||||
|
Elf_ehdr *ehdr;
|
||||||
|
Elf_phdr *phdr;
|
||||||
|
|
||||||
|
ehdr = (Elf_ehdr *)header;
|
||||||
|
phdr = (Elf_phdr *)(&header[ehdr->e_phoff]);
|
||||||
|
|
||||||
struct segment *ptr;
|
struct segment *ptr;
|
||||||
int i;
|
int i;
|
||||||
int size;
|
int size;
|
||||||
unsigned char *header = (unsigned char *) phdr;
|
|
||||||
for(i = 0; i < headers; i++) {
|
for(i = 0; i < headers; i++) {
|
||||||
struct segment *new;
|
struct segment *new;
|
||||||
/* Ignore data that I don't need to handle */
|
/* Ignore data that I don't need to handle */
|
||||||
|
@ -101,21 +106,18 @@ static int load_elf_segments(struct lb_memory *mem,Elf_phdr *phdr, int headers)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int elfload(struct lb_memory *mem,
|
int elfload(struct lb_memory *mem, unsigned char *header, unsigned long header_size)
|
||||||
unsigned char *header, unsigned long header_size)
|
|
||||||
{
|
{
|
||||||
Elf_ehdr *ehdr;
|
Elf_ehdr *ehdr;
|
||||||
Elf_phdr *phdr;
|
|
||||||
void *entry;
|
void *entry;
|
||||||
void (*v)(void);
|
void (*v)(void);
|
||||||
struct verify_callback *cb_chain;
|
struct verify_callback *cb_chain;
|
||||||
|
|
||||||
ehdr = (Elf_ehdr *)header;
|
ehdr = (Elf_ehdr *)header;
|
||||||
entry = (void *)(ehdr->e_entry);
|
entry = (void *)(ehdr->e_entry);
|
||||||
phdr = (Elf_phdr *)(&header[ehdr->e_phoff]);
|
|
||||||
|
|
||||||
/* Load the segments */
|
/* Load the segments */
|
||||||
if (!load_elf_segments(mem, phdr, header_size))
|
if (!load_elf_segments(mem, header, header_size))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
printk(BIOS_SPEW, "Loaded segments\n");
|
printk(BIOS_SPEW, "Loaded segments\n");
|
||||||
|
@ -129,9 +131,11 @@ int elfload(struct lb_memory *mem,
|
||||||
post_code(0xfe);
|
post_code(0xfe);
|
||||||
|
|
||||||
/* Jump to kernel */
|
/* Jump to kernel */
|
||||||
/* just call it as a function. If it wants to return, it will. */
|
/* most of the time, jmp_to_elf_entry is just a call. But this hook gives us
|
||||||
v = entry;
|
* a handy way to get architecture-dependent operations done, if needed
|
||||||
v();
|
* jmp_to_elf_entry is in arch/<architecture>/archelfboot.c
|
||||||
|
*/
|
||||||
|
jmp_to_elf_entry(entry);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -180,7 +184,7 @@ int elfboot_mem(struct lb_memory *mem, void *where, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
printk(BIOS_SPEW, "Try to load at offset 0x%x %d phdr\n", header_offset, ehdr->e_phnum);
|
printk(BIOS_SPEW, "Try to load at offset 0x%x %d phdr\n", header_offset, ehdr->e_phnum);
|
||||||
result = elfload(mem, header + header_offset , ehdr->e_phnum);
|
result = elfload(mem, header, ehdr->e_phnum);
|
||||||
out:
|
out:
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue