[U-Boot] [RFC PATCH] x86: Support booting SeaBIOS

Bin Meng bmeng.cn at gmail.com
Sat Oct 10 10:57:52 CEST 2015


Hi Simon,

On Sat, Oct 3, 2015 at 10:29 PM, Simon Glass <sjg at chromium.org> wrote:
> Hi Bin,
>
> On 29 September 2015 at 11:17, Bin Meng <bmeng.cn at 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?

If using CBFS, that means we may have to abandon ifdtool? Or maybe
mixed usage of both tools?

>
>>
>> Signed-off-by: Bin Meng <bmeng.cn at 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()?

Yes.

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

Yes

>
>> +       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?

It's sizeof(struct cb_memory) - sizeof(struct cb_memory_range)

>
>> +
>> +       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
>>  }
>> --

Regards,
Bin


More information about the U-Boot mailing list