Hi Bin, On 29 September 2015 at 11:17, Bin Meng <bmeng...@gmail.com> wrote: > SeaBIOS is an open source implementation of a 16-bit X86 BIOS. > It can run in an emulator or natively on X86 hardware with the > use of coreboot. With SeaBIOS's help, we can boot some OSes > that require 16-bit BIOS services like Windows/DOS. > > As U-Boot, we have to manually create a table where SeaBIOS gets > system information (eg: E820) from. The table unfortunately has > to follow the coreboot table format as SeaBIOS currently supports > booting as a coreboot payload. No U-Boot native support there. > > Booting SeaBIOS is done via U-Boot's bootelf command. > > This is the initial attempt to support booting SeaBIOS from U-Boot. > If the basic concept is good, I can spend time working on follow-on > patches to enable BIOS tables as well as graphics support. One issue > is that U-Boot x86 does not has a ROM file system like coreboot. > This brings difficulities to pass PCI option ROM to SeaBIOS, if we > don't modify SeaBIOS's source codes. Maybe we should promote CBFS > in U-Boot x86? > > This is tested on an Intel Crown Bay board with VGA card, booting > SeaBIOS then chain loading a GRUB on a USB drive, then Linux kernel > finally.
Looks good to me. I think it is OK to use CBFS if needed - are you thinking of an option to build u-boot.rom as a CBFS filesystem? > > Signed-off-by: Bin Meng <bmeng...@gmail.com> > > --- > > arch/x86/Kconfig | 10 ++++++++++ > arch/x86/include/asm/tables.h | 29 +++++++++++++++++++++++++++++ > arch/x86/lib/tables.c | 39 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 78 insertions(+) > > diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig > index 5e42d7d..b432ff8 100644 > --- a/arch/x86/Kconfig > +++ b/arch/x86/Kconfig > @@ -401,6 +401,16 @@ config PCIE_ECAM_SIZE > so a default 0x10000000 size covers all of the 256 buses which is > the > maximum number of PCI buses as defined by the PCI specification. > > +config SEABIOS > + bool "Support booting SeaBIOS" > + help > + SeaBIOS is an open source implementation of a 16-bit X86 BIOS. > + It can run in an emulator or natively on X86 hardware with the use > + of coreboot/U-Boot. By turning on this option, U-Boot prepares > + all the configuration tables that are necessary to boot SeaBIOS. > + > + Check http://www.seabios.org/SeaBIOS for details. > + > source "arch/x86/lib/efi/Kconfig" > > endmenu > diff --git a/arch/x86/include/asm/tables.h b/arch/x86/include/asm/tables.h > index 0aa6d9b..a083cac 100644 > --- a/arch/x86/include/asm/tables.h > +++ b/arch/x86/include/asm/tables.h > @@ -7,6 +7,32 @@ > #ifndef _X86_TABLES_H_ > #define _X86_TABLES_H_ > > +#ifdef CONFIG_SEABIOS > + > +#define CB_TAG_MEMORY 1 > + > +struct cb_header { > + u8 signature[4]; > + u32 header_bytes; > + u32 header_checksum; > + u32 table_bytes; > + u32 table_checksum; > + u32 table_entries; > +}; > + > +struct cb_memory_range { > + u64 start; > + u64 size; > + u32 type; > +}; > + > +struct cb_memory { > + u32 tag; > + u32 size; > + struct cb_memory_range map[0]; > +}; > +#endif > + > /* > * All x86 tables happen to like the address range from 0xf0000 to 0x100000. > * We use 0xf0000 as the starting address to store those tables, including > @@ -14,6 +40,9 @@ > */ > #define ROM_TABLE_ADDR 0xf0000 > > +/* SeaBIOS expects coreboot tables at address range 0x0000-0x1000 */ > +#define CB_TABLE_ADDR 0x800 > + > /** > * table_compute_checksum() - Compute a table checksum > * > diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c > index f15b2e2..5849b2f 100644 > --- a/arch/x86/lib/tables.c > +++ b/arch/x86/lib/tables.c > @@ -9,6 +9,7 @@ > #include <asm/mpspec.h> > #include <asm/tables.h> > #include <asm/acpi_table.h> > +#include <asm/e820.h> > > u8 table_compute_checksum(void *v, int len) > { > @@ -36,6 +37,41 @@ void table_fill_string(char *dest, const char *src, size_t > n, char pad) > dest[i] = pad; > } > > +#ifdef CONFIG_SEABIOS > +static u32 write_cb_tables(u32 addr) > +{ > + struct cb_header *cbh = (struct cb_header *)addr; > + struct cb_memory *mem; > + struct cb_memory_range *map; > + struct e820entry entry[32]; > + int num, i; > + > + memset(cbh, 0, sizeof(struct cb_header)); > + strncpy((char *)cbh->signature, "LBIO", 4); memcpy()? > + cbh->header_bytes = sizeof(struct cb_header); > + > + /* populate memory map table */ > + mem = (struct cb_memory *)(cbh + 1); > + mem->tag = CB_TAG_MEMORY; > + map = mem->map; > + num = install_e820_map(32, entry); ARRAY_SIZE(entry) > + for (i = 0; i < num; i++) { > + map->start = entry[i].addr; > + map->size = entry[i].size; > + map->type = entry[i].type; > + map++; > + } > + mem->size = num * sizeof(struct cb_memory_range) + 8; What is 8? > + > + cbh->table_bytes = mem->size; > + cbh->table_checksum = compute_ip_checksum(mem, cbh->table_bytes); > + cbh->table_entries = 1; > + cbh->header_checksum = compute_ip_checksum(cbh, cbh->header_bytes); > + > + return (u32)map; > +} > +#endif > + > void write_tables(void) > { > u32 __maybe_unused rom_table_end = ROM_TABLE_ADDR; > @@ -56,4 +92,7 @@ void write_tables(void) > rom_table_end = write_acpi_tables(rom_table_end); > rom_table_end = ALIGN(rom_table_end, 1024); > #endif > +#ifdef CONFIG_SEABIOS > + write_cb_tables(CB_TABLE_ADDR); > +#endif > } > -- > 1.8.2.1 > Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot