diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2019-07-22 12:55:48 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2019-07-22 13:02:00 +0200 |
commit | a56aa64ed030a30377931a13a3da98a8419326ca (patch) | |
tree | 0e8b4044319305e0a1a422441c060e29d80c0f6a | |
parent | ab6d7ee29d95ecee28190644f8d001b08d480b34 (diff) | |
download | qboot-a56aa64ed030a30377931a13a3da98a8419326ca.zip qboot-a56aa64ed030a30377931a13a3da98a8419326ca.tar.gz qboot-a56aa64ed030a30377931a13a3da98a8419326ca.tar.bz2 |
drop cbfs experiment
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | README | 22 | ||||
-rw-r--r-- | cbfs.c | 157 | ||||
-rw-r--r-- | include/bios.h | 1 | ||||
-rw-r--r-- | main.c | 19 |
5 files changed, 8 insertions, 194 deletions
@@ -1,6 +1,5 @@ obj-y = code16.o entry.o main.o string.o printf.o cstart.o fw_cfg.o -obj-y += linuxboot.o malloc.o pflash.o cbfs.o tables.o hwsetup.o -obj-y += pci.o +obj-y += linuxboot.o malloc.o pflash.o tables.o hwsetup.o pci.o all-y = bios.bin all: $(all-y) @@ -1,6 +1,6 @@ A simple x86 firmware that can boot Linux. -Most of QEMU's 500-700 ms startup time is spent: +Most of QEMU's startup time is spent: * in the dynamic linker. This can be reduced by 150 ms simply by compiling a stripped down QEMU: @@ -17,10 +17,8 @@ Most of QEMU's 500-700 ms startup time is spent: * in the BIOS. qboot saves another 150 ms. -* in fw_cfg. qboot can use the new DMA interface to fw_cfg from QEMU 2.7+. - Alternatively, kernel and initrd can be put in a CoreBoot cbfs image - stored in flash. However, flash has a limit of 8 MB. In either case - 350 ms are saved, bringing the startup time down to 60 ms. +* until QEMU 2.7+, in fw_cfg. qboot uses the DMA interface which is pretty + much instantaneous. Compile qboot ============= @@ -39,26 +37,12 @@ The result will be a 64K file named bios.bin. Usage ===== -fw_cfg based example: - $ qemu-kvm -bios bios.bin \ -kernel /boot/vmlinuz-4.0.3-300.fc22.x86_64 \ -serial mon:stdio -append 'console=ttyS0,115200,8n1' -cbfs-based example (pflash isn't the definitive interface though): - - $ dd if=/dev/zero of=boot.bin bs=4096 count=1 - $ cbfstool cbfs.rom create -s 8128k -B boot.bin -m x86 -o 0x1000 - $ cbfstool cbfs.rom add -f /boot/vmlinuz-4.0.3-300.fc22.x86_64 -n vmlinuz -t raw - $ echo 'console=ttyS0,115200,8n1' > cmdline - $ cbfstool cbfs.rom add -f cmdline -n cmdline -t raw - $ qemu-kvm -drive if=pflash,file=bios.bin,readonly=on \ - -drive if=pflash,file=cbfs.rom,readonly=on \ - -serial mon:stdio - TODO ==== * SMBIOS tables * Add the possibility to configure out PIC and PCI bridge initialization -* Possibly drop cbfs support, superseded by fw_cfg DMA @@ -1,157 +0,0 @@ -#include "bios.h" -#include "stdio.h" -#include "ioport.h" -#include "string.h" -#include "bswap.h" -#include "linuxboot.h" - -#define CBFS_HEADER_MAGIC 0x4F524243 // ORBC -#define CBFS_HEADER_VERSION1 0x31313131 -#define CBFS_HEADER_VERSION2 0x31313132 - -static const char file_magic[8] = "LARCHIVE"; - -struct cbfs_header { - uint32_t magic; - uint32_t version; - uint32_t romsize; - uint32_t bootblocksize; - uint32_t align; - uint32_t offset; - uint32_t pad[2]; -} __attribute__((__packed__)); - -struct cbfs_file_header { - char magic[8]; - uint32_t len; - uint32_t type; - uint32_t checksum; - uint32_t offset; -} __attribute__((__packed__)); - - -struct cbfs_file { - uint32_t size; - const char *buf; - char name[57]; - struct cbfs_file *next; -}; - -static struct cbfs_file *files; - -static bool cbfs_setup(const char *base, size_t sz) -{ - uint32_t ofs; - struct cbfs_header hdr; - struct cbfs_file **pnext; - uint32_t align; - - ofs = sz + (intptr_t)(int32_t)ldl_le_p(base + sz - 4); - if (ofs >= sz - sizeof(struct cbfs_header) || - ldl_be_p(base + ofs) != CBFS_HEADER_MAGIC) - ofs = 0; - - for (; ofs + sizeof(struct cbfs_header) < sz; ofs++) { - if (ldl_be_p(base + ofs) != CBFS_HEADER_MAGIC) - continue; - memcpy(&hdr, base + ofs, sizeof(hdr)); - if (ldl_be_p(&hdr.version) != CBFS_HEADER_VERSION1 && - ldl_be_p(&hdr.version) != CBFS_HEADER_VERSION2) - continue; - break; - } - - if (ofs + sizeof(struct cbfs_header) >= sz) - return false; - - pnext = &files; - ofs = ldl_be_p(&hdr.offset); - align = ldl_be_p(&hdr.align); - while (ofs + sizeof(struct cbfs_file_header) < sz) { - struct cbfs_file_header fhdr; - struct cbfs_file *f; - - memcpy(&fhdr, base + ofs, sizeof(fhdr)); - if (memcmp(&fhdr.magic, file_magic, sizeof(file_magic))) - break; - - f = malloc_fseg(sizeof(*f)); - *pnext = f; - - f->size = ldl_be_p(&fhdr.len); - f->buf = base + ofs + ldl_be_p(&fhdr.offset); - strcpy(f->name, base + ofs + sizeof(fhdr)); - f->next = NULL; - pnext = &f->next; - - ofs = f->buf + f->size - base; - ofs = (ofs + align - 1) & -align; - } - return files != NULL; -} - -static struct cbfs_file *cbfs_file_find(const char *name) -{ - struct cbfs_file *f = files; - - for (f = files; f; f = f->next) - if (!strcmp(name, f->name)) - return f; - - return NULL; -} - -uint32_t cbfs_size(const char *name) -{ - struct cbfs_file *f = cbfs_file_find(name); - if (!f) - return 0; - - return f->size; -} - -void cbfs_read(const char *name, void *buf, size_t size, size_t skip) -{ - struct cbfs_file *f = cbfs_file_find(name); - if (!f) - panic(); - - if (skip > f->size) - return; - if (size + skip > f->size) - size = f->size - skip; - memcpy(buf, f->buf + skip, size); -} - -bool cbfs_boot(void) -{ - struct linuxboot_args args; - - args.vmlinuz_size = cbfs_size("vmlinuz"); - if (!args.vmlinuz_size) - return false; - - args.initrd_size = cbfs_size("initrd"); - args.cmdline_size = cbfs_size("cmdline"); - - cbfs_read("vmlinuz", args.header, sizeof(args.header), 0); - if (!parse_bzimage(&args)) - return false; - - cbfs_read("vmlinuz", args.setup_addr, args.setup_size, 0); - cbfs_read("vmlinuz", args.kernel_addr, args.kernel_size, args.setup_size); - - if (args.initrd_size) - cbfs_read("initrd", args.initrd_addr, args.initrd_size, 0); - if (args.cmdline_size) - cbfs_read("cmdline", args.cmdline_addr, args.cmdline_size, 0); - - boot_bzimage(&args); - return true; -} - -bool boot_from_cbfs(void *base, size_t sz) -{ - return cbfs_setup(base, sz) && cbfs_boot(); -} - diff --git a/include/bios.h b/include/bios.h index df60c5a..12087f2 100644 --- a/include/bios.h +++ b/include/bios.h @@ -43,7 +43,6 @@ extern void setup_hw(void); extern bool setup_mmconfig(void); extern void extract_acpi(void); extern void boot_from_fwcfg(void); -extern bool boot_from_cbfs(void *base, size_t sz); extern uint16_t e820_seg; extern uint32_t lowmem; @@ -77,17 +77,6 @@ static void extract_e820(void) e820_seg = ((uintptr_t) e820) >> 4; } -static bool detect_cbfs_and_boot(void) -{ - size_t sz; - void *base = pflash_base(1, &sz); - - if (!base) - return false; - - return boot_from_cbfs(base, sz); -} - int __attribute__ ((section (".text.startup"))) main(void) { #ifdef BENCHMARK_HACK @@ -95,8 +84,9 @@ int __attribute__ ((section (".text.startup"))) main(void) #endif setup_hw(); - // Now go to the F-segment: we need to move away from flash area - // in order to probe CBFS! + // Only the 16-bit trampoline for vmlinuz and the 16-bit interrupt + // handlers need to run from the F-segment, but keep things simple + // and jump there. From this point we can modify global variables. asm("ljmp $0x8, $1f; 1:"); have_mmconfig = setup_mmconfig(); @@ -106,7 +96,6 @@ int __attribute__ ((section (".text.startup"))) main(void) extract_acpi(); extract_e820(); // extract_smbios(); - if (!detect_cbfs_and_boot()) - boot_from_fwcfg(); + boot_from_fwcfg(); panic(); } |