mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
Basic elfboot functionality is in now.
We're trying to avoid the bounce buffer mess, which is really complex, by running elfboot out of the boot block. This code includes a really dumb allocator in elfboot which may or may not work. It basically allocates off the elfboot() stack. This builds, but elfboot is not tested. That's next. 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@102 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
83ac9292bd
commit
08016c4ca8
6 changed files with 67 additions and 17 deletions
|
@ -75,16 +75,19 @@ $(obj)/stage0.init:
|
|||
$(Q)# console lib
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/arch/x86/console.c -o $(obj)/console.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/arch/x86/serial.c -o $(obj)/serial.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/arch/x86/archelfboot.c -o $(obj)/archelfboot.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/console/vtxprintf.c -o $(obj)/vtxprintf.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/console/vsprintf.c -o $(obj)/vsprintf.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/lib/uart8250.c -o $(obj)/uart8250.o
|
||||
$(Q)# other lib parts
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/lib/mem.c -o $(obj)/mem.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/lib/elfboot.c -o $(obj)/elfboot.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/lib/compute_ip_checksum.c -o $(obj)/compute_ip_checksum.o
|
||||
|
||||
$(Q)cd $(obj); $(CC) -m32 -nostdlib -static \
|
||||
-T $(src)/arch/x86/ldscript.ld cachemain.o \
|
||||
console.o uart8250.o serial.o vtxprintf.o \
|
||||
vsprintf.o lar.o mem.o stage0_i586.o -o stage0.o
|
||||
console.o uart8250.o serial.o archelfboot.o vtxprintf.o \
|
||||
vsprintf.o lar.o elfboot.o compute_ip_checksum.o mem.o stage0_i586.o -o stage0.o
|
||||
|
||||
$(Q)objcopy -O binary $(obj)/stage0.o $(obj)/stage0.init.pre
|
||||
|
||||
|
@ -115,8 +118,6 @@ $(obj)/linuxbios.stage2: $(obj)/stage0.init $(obj)/statictree.o
|
|||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/device/device.c -o $(obj)/device.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/device/device_util.c -o $(obj)/device_util.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/device/root_device.c -o $(obj)/root_device.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/lib/elfboot.c -o $(obj)/elfboot.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/lib/compute_ip_checksum.c -o $(obj)/compute_ip_checksum.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/lib/mem.c -o $(obj)/mem.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/lib/malloc.c -o $(obj)/malloc.o
|
||||
$(Q)$(CC) $(INITCFLAGS) -c $(src)/lib/clog2.c -o $(obj)/clog2.o
|
||||
|
|
|
@ -69,6 +69,7 @@ int elf_check_arch(Elf_ehdr *ehdr)
|
|||
|
||||
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;
|
||||
|
@ -83,12 +84,11 @@ void jmp_to_elf_entry(void *entry)
|
|||
|
||||
adjusted_boot_notes = (unsigned long)&elf_boot_notes;
|
||||
|
||||
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("buffer = 0x%08lx\n", buffer);
|
||||
printk_spew(" elf_boot_notes = 0x%08lx\n", (unsigned long)&elf_boot_notes);
|
||||
printk_spew("adjusted_boot_notes = 0x%08lx\n", adjusted_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__(
|
||||
|
@ -174,6 +174,7 @@ void jmp_to_elf_entry(void *entry)
|
|||
"g" (lb_start), "g" (buffer), "g" (lb_size),
|
||||
"g" (entry), "g"(adjusted_boot_notes)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <console/console.h>
|
||||
#include <console/loglevel.h>
|
||||
#include <lar.h>
|
||||
#include <linuxbios_tables.h>
|
||||
#include "config.h"
|
||||
|
||||
/* these prototypes should go into headers */
|
||||
|
@ -61,7 +62,9 @@ void stage1_main(u32 bist)
|
|||
{
|
||||
int ret;
|
||||
struct mem_file archive;
|
||||
|
||||
int elfboot_mem(struct lb_memory *mem, void *where, int size);
|
||||
/* HACK -- fake memory table for now */
|
||||
struct lb_memory mem = {LB_TAG_MEMORY, 1, .map = { {0, 32*1024*1024, LB_MEM_RAM}}};
|
||||
post_code(0x02);
|
||||
|
||||
// before we do anything, we want to stop if we dont run
|
||||
|
@ -210,6 +213,16 @@ printk(BIOS_INFO, "Start search at 0x%x, size %d\n", archive.start, archive.len)
|
|||
|
||||
printk(BIOS_INFO, "Done stage2 code\n");
|
||||
|
||||
ret = find_file(&archive, "payload", &result);
|
||||
if (ret) {
|
||||
printk(BIOS_INFO, "no such name %s\n", "payload");
|
||||
die("cachemain finding payload");
|
||||
}
|
||||
|
||||
ret = elfboot_mem(&mem, result.start, result.len);
|
||||
|
||||
printk("elfboot_mem returns %d\n", ret);
|
||||
|
||||
die ("FATAL: This is as far as it goes\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ typedef Elf64_Phdr Elf_phdr;
|
|||
#endif
|
||||
|
||||
extern int elf_check_arch(Elf_ehdr *ehdr);
|
||||
extern void jmp_to_elf_entry(void *entry, unsigned long buffer);
|
||||
extern void jmp_to_elf_entry(void *entry);
|
||||
struct lb_memory;
|
||||
extern int elfboot(struct lb_memory *mem);
|
||||
|
||||
|
|
|
@ -41,4 +41,3 @@ struct mem_file {
|
|||
int find_file(struct mem_file *archive, char *filename, struct mem_file *result);
|
||||
int copy_file(struct mem_file *archive, char *filename, void *where);
|
||||
int run_file(struct mem_file *archive, char *filename, void *where);
|
||||
|
||||
|
|
|
@ -32,13 +32,39 @@ struct ip_checksum_vcb {
|
|||
unsigned short ip_checksum;
|
||||
};
|
||||
|
||||
/* we're trying to keep out of the way of elf segments, without requiring the
|
||||
* bounce buffer. This may fail, but it's worth the effort.
|
||||
*/
|
||||
static unsigned char *arena;
|
||||
int arenasize;
|
||||
|
||||
static void
|
||||
setupmalloc(void *s, int size)
|
||||
{
|
||||
arena = s;
|
||||
arenasize = size;
|
||||
}
|
||||
|
||||
static void *localmalloc(int nbytes)
|
||||
{
|
||||
char *ret;
|
||||
if (nbytes > arenasize)
|
||||
return NULL;
|
||||
|
||||
arenasize -= nbytes;
|
||||
ret = arena;
|
||||
arena += nbytes;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* streams are a nice way to abstract the pointer/size-based nature of the
|
||||
* memory away. The main good part is that we have a way to fail out if the
|
||||
* elfboot code is running off the end of the array for some reason. So we won't
|
||||
* rip it out just yet.
|
||||
*/
|
||||
unsigned char *streambase = NULL;
|
||||
int streamsize = -1;
|
||||
static unsigned char *streambase = NULL;
|
||||
static int streamsize = -1;
|
||||
|
||||
int stream_init(void){
|
||||
return 0;
|
||||
|
@ -143,7 +169,7 @@ static struct verify_callback *process_elf_notes(
|
|||
case EIN_PROGRAM_CHECKSUM:
|
||||
{
|
||||
struct ip_checksum_vcb *cb;
|
||||
cb = malloc(sizeof(*cb));
|
||||
cb = localmalloc(sizeof(*cb));
|
||||
cb->ip_checksum = *((uint16_t *)n_desc);
|
||||
cb->data.callback = verify_ip_checksum;
|
||||
cb->data.next = cb_chain;
|
||||
|
@ -231,7 +257,7 @@ static int build_elf_segment_list(
|
|||
printk(BIOS_DEBUG, "Dropping empty segment\n");
|
||||
continue;
|
||||
}
|
||||
new = malloc(sizeof(*new));
|
||||
new = localmalloc(sizeof(*new));
|
||||
new->s_addr = phdr[i].p_paddr;
|
||||
new->s_memsz = phdr[i].p_memsz;
|
||||
new->s_offset = phdr[i].p_offset;
|
||||
|
@ -446,7 +472,10 @@ int elfboot(struct lb_memory *mem)
|
|||
static unsigned char header[ELF_HEAD_SIZE];
|
||||
int header_offset;
|
||||
int i, result;
|
||||
/* for stupid allocator which won't run into trouble with segments */
|
||||
char alloc[256];
|
||||
|
||||
setupmalloc(alloc, sizeof(alloc));
|
||||
result = 0;
|
||||
printk(BIOS_INFO, "\n");
|
||||
printk(BIOS_INFO, "Welcome to %s, the open sourced starter.\n", BOOTLOADER);
|
||||
|
@ -508,3 +537,10 @@ int elfboot(struct lb_memory *mem)
|
|||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int elfboot_mem(struct lb_memory *mem, void *where, int size)
|
||||
{
|
||||
streambase = where;
|
||||
streamsize = size;
|
||||
return elfboot(mem);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue