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:
Ronald G. Minnich 2007-02-24 07:41:22 +00:00
parent 98d3059a2d
commit 326b94d572
2 changed files with 21 additions and 117 deletions

View file

@ -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)
{
#ifdef NOTYET
extern unsigned char _ram_seg, _eram_seg;
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
int (*v)() = entry;
v();
}

View file

@ -53,12 +53,17 @@ static int valid_area(struct lb_memory *mem,
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;
int i;
int size;
unsigned char *header = (unsigned char *) phdr;
for(i = 0; i < headers; i++) {
struct segment *new;
/* 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,
unsigned char *header, unsigned long header_size)
int elfload(struct lb_memory *mem, unsigned char *header, unsigned long header_size)
{
Elf_ehdr *ehdr;
Elf_phdr *phdr;
void *entry;
void (*v)(void);
struct verify_callback *cb_chain;
ehdr = (Elf_ehdr *)header;
entry = (void *)(ehdr->e_entry);
phdr = (Elf_phdr *)(&header[ehdr->e_phoff]);
/* Load the segments */
if (!load_elf_segments(mem, phdr, header_size))
if (!load_elf_segments(mem, header, header_size))
goto out;
printk(BIOS_SPEW, "Loaded segments\n");
@ -129,9 +131,11 @@ int elfload(struct lb_memory *mem,
post_code(0xfe);
/* Jump to kernel */
/* just call it as a function. If it wants to return, it will. */
v = entry;
v();
/* most of the time, jmp_to_elf_entry is just a call. But this hook gives us
* a handy way to get architecture-dependent operations done, if needed
* jmp_to_elf_entry is in arch/<architecture>/archelfboot.c
*/
jmp_to_elf_entry(entry);
return 1;
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);
result = elfload(mem, header + header_offset , ehdr->e_phnum);
result = elfload(mem, header, ehdr->e_phnum);
out:
if (!result) {