aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2019-07-22 12:55:48 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2019-07-22 13:02:00 +0200
commita56aa64ed030a30377931a13a3da98a8419326ca (patch)
tree0e8b4044319305e0a1a422441c060e29d80c0f6a
parentab6d7ee29d95ecee28190644f8d001b08d480b34 (diff)
downloadqboot-a56aa64ed030a30377931a13a3da98a8419326ca.zip
qboot-a56aa64ed030a30377931a13a3da98a8419326ca.tar.gz
qboot-a56aa64ed030a30377931a13a3da98a8419326ca.tar.bz2
drop cbfs experiment
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--Makefile3
-rw-r--r--README22
-rw-r--r--cbfs.c157
-rw-r--r--include/bios.h1
-rw-r--r--main.c19
5 files changed, 8 insertions, 194 deletions
diff --git a/Makefile b/Makefile
index 476436c..1ac923d 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/README b/README
index a180244..7f45a06 100644
--- a/README
+++ b/README
@@ -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
diff --git a/cbfs.c b/cbfs.c
deleted file mode 100644
index b4c235e..0000000
--- a/cbfs.c
+++ /dev/null
@@ -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;
diff --git a/main.c b/main.c
index 8ac2a68..547712c 100644
--- a/main.c
+++ b/main.c
@@ -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();
}