[U-Boot] [RFC PATCH] x86: Support booting SeaBIOS
Simon Glass
sjg at chromium.org
Sat Oct 3 16:29:29 CEST 2015
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?
>
> 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()?
> + 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
More information about the U-Boot
mailing list