Compare commits
23 Commits
cherry-053
...
oss-qemu-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6745ec44d9 | ||
|
|
ae65270530 | ||
|
|
4bc5ceac65 | ||
|
|
cc88f32641 | ||
|
|
a97042cdf6 | ||
|
|
5414785620 | ||
|
|
0ed5f6b991 | ||
|
|
f6c413a993 | ||
|
|
bd3ef58432 | ||
|
|
4d8ad27f8e | ||
|
|
5f65048550 | ||
|
|
9fea52af75 | ||
|
|
1aa8ff8220 | ||
|
|
be79f70a11 | ||
|
|
80c56d399c | ||
|
|
c872780ba6 | ||
|
|
21abce189f | ||
|
|
8099cce624 | ||
|
|
793bb912e1 | ||
|
|
403ad10115 | ||
|
|
add868d853 | ||
|
|
057ec035cf | ||
|
|
7665482b11 |
@@ -31,6 +31,7 @@
|
|||||||
#define POST_DRAM 0x30
|
#define POST_DRAM 0x30
|
||||||
#define POST_LAPIC 0x31
|
#define POST_LAPIC 0x31
|
||||||
#define POST_OS_RESUME 0x40
|
#define POST_OS_RESUME 0x40
|
||||||
|
#define POST_BOOT 0x42
|
||||||
|
|
||||||
#define POST_RAM_FAILURE 0xea
|
#define POST_RAM_FAILURE 0xea
|
||||||
#define POST_BIST_FAILURE 0xeb
|
#define POST_BIST_FAILURE 0xeb
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <asm/bootparam.h>
|
#include <asm/bootparam.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
#include <asm/post.h>
|
||||||
#include <asm/zimage.h>
|
#include <asm/zimage.h>
|
||||||
#ifdef CONFIG_SYS_COREBOOT
|
#ifdef CONFIG_SYS_COREBOOT
|
||||||
#include <asm/arch/timestamp.h>
|
#include <asm/arch/timestamp.h>
|
||||||
@@ -201,6 +202,8 @@ int boot_linux_kernel(ulong setup_base, ulong entry, bool image_64bit)
|
|||||||
if (IS_ENABLED(CONFIG_EFI_APP))
|
if (IS_ENABLED(CONFIG_EFI_APP))
|
||||||
return efi_boot(setup_base, entry, image_64bit);
|
return efi_boot(setup_base, entry, image_64bit);
|
||||||
|
|
||||||
|
post_code(POST_BOOT);
|
||||||
|
|
||||||
if (image_64bit) {
|
if (image_64bit) {
|
||||||
if (!cpu_has_64bit()) {
|
if (!cpu_has_64bit()) {
|
||||||
puts("Cannot boot 64-bit kernel on 32-bit machine\n");
|
puts("Cannot boot 64-bit kernel on 32-bit machine\n");
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
|
|||||||
def_bool y
|
def_bool y
|
||||||
select X86_RESET_VECTOR
|
select X86_RESET_VECTOR
|
||||||
select QEMU
|
select QEMU
|
||||||
select QFW_PIO if CMD_QFW
|
select QFW_PIO
|
||||||
select BOARD_ROMSIZE_KB_1024 if TARGET_QEMU_X86
|
select BOARD_ROMSIZE_KB_1024 if TARGET_QEMU_X86
|
||||||
select BOARD_ROMSIZE_KB_2048 if TARGET_QEMU_X86_64
|
select BOARD_ROMSIZE_KB_2048 if TARGET_QEMU_X86_64
|
||||||
imply VIRTIO_PCI
|
imply VIRTIO_PCI
|
||||||
|
|||||||
@@ -557,7 +557,7 @@ config BOOTSTD_DEFAULTS
|
|||||||
bool "Select some common defaults for standard boot"
|
bool "Select some common defaults for standard boot"
|
||||||
depends on BOOTSTD
|
depends on BOOTSTD
|
||||||
select BOOT_DEFAULTS
|
select BOOT_DEFAULTS
|
||||||
select BOOTMETH_DISTRO
|
imply BOOTMETH_DISTRO
|
||||||
help
|
help
|
||||||
These are not required but are commonly needed to support a good
|
These are not required but are commonly needed to support a good
|
||||||
selection of booting methods. Enable this to improve the capability
|
selection of booting methods. Enable this to improve the capability
|
||||||
@@ -731,9 +731,9 @@ config BOOTMETH_VBE
|
|||||||
config BOOTMETH_DISTRO
|
config BOOTMETH_DISTRO
|
||||||
bool # Options needed to boot any distro
|
bool # Options needed to boot any distro
|
||||||
select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts
|
select BOOTMETH_SCRIPT if CMDLINE # E.g. Armbian uses scripts
|
||||||
select BOOTMETH_EXTLINUX # E.g. Debian uses these
|
imply BOOTMETH_EXTLINUX # E.g. Debian uses these
|
||||||
select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH
|
select BOOTMETH_EXTLINUX_PXE if CMD_PXE && CMD_NET && DM_ETH
|
||||||
select BOOTMETH_EFILOADER if EFI_BINARY_EXEC # E.g. Ubuntu uses this
|
imply BOOTMETH_EFILOADER if EFI_BINARY_EXEC # E.g. Ubuntu uses this
|
||||||
|
|
||||||
config SPL_BOOTMETH_VBE
|
config SPL_BOOTMETH_VBE
|
||||||
bool "Bootdev support for Verified Boot for Embedded (SPL)"
|
bool "Bootdev support for Verified Boot for Embedded (SPL)"
|
||||||
|
|||||||
@@ -998,10 +998,10 @@ struct bootflow_img *bootflow_img_add(struct bootflow *bflow, const char *fname,
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct bootflow_img *bootflow_img_find(const struct bootflow *bflow,
|
struct bootflow_img *bootflow_img_findw(const struct bootflow *bflow,
|
||||||
enum bootflow_img_t type)
|
enum bootflow_img_t type)
|
||||||
{
|
{
|
||||||
const struct bootflow_img *img;
|
struct bootflow_img *img;
|
||||||
|
|
||||||
alist_for_each(img, &bflow->images) {
|
alist_for_each(img, &bflow->images) {
|
||||||
if (img->type == type)
|
if (img->type == type)
|
||||||
|
|||||||
@@ -8,11 +8,14 @@
|
|||||||
|
|
||||||
#define LOG_CATEGORY UCLASS_BOOTSTD
|
#define LOG_CATEGORY UCLASS_BOOTSTD
|
||||||
|
|
||||||
|
#include <abuf.h>
|
||||||
#include <command.h>
|
#include <command.h>
|
||||||
#include <bootdev.h>
|
#include <bootdev.h>
|
||||||
#include <bootflow.h>
|
#include <bootflow.h>
|
||||||
|
#include <bootm.h>
|
||||||
#include <bootmeth.h>
|
#include <bootmeth.h>
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
|
#include <mapmem.h>
|
||||||
#include <qfw.h>
|
#include <qfw.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
|
|
||||||
@@ -31,26 +34,86 @@ static int qfw_check(struct udevice *dev, struct bootflow_iter *iter)
|
|||||||
static int qfw_read_bootflow(struct udevice *dev, struct bootflow *bflow)
|
static int qfw_read_bootflow(struct udevice *dev, struct bootflow *bflow)
|
||||||
{
|
{
|
||||||
struct udevice *qfw_dev = dev_get_parent(bflow->dev);
|
struct udevice *qfw_dev = dev_get_parent(bflow->dev);
|
||||||
ulong load, initrd;
|
ulong setup, kern, ramdisk, cmdline_size, setup_addr;
|
||||||
|
struct abuf cmdline;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
load = env_get_hex("kernel_addr_r", 0);
|
/* Get the size of each region */
|
||||||
initrd = env_get_hex("ramdisk_addr_r", 0);
|
ret = qemu_fwcfg_read_info(qfw_dev, &setup, &kern, &ramdisk, &cmdline,
|
||||||
log_debug("setup kernel %s %lx %lx\n", qfw_dev->name, load, initrd);
|
&setup_addr);
|
||||||
|
if (ret)
|
||||||
|
return log_msg_ret("qri", ret);
|
||||||
|
bflow->cmdline = abuf_uninit_move(&cmdline, &cmdline_size);
|
||||||
|
|
||||||
bflow->name = strdup("qfw");
|
bflow->name = strdup("qfw");
|
||||||
if (!bflow->name)
|
if (!bflow->name)
|
||||||
return log_msg_ret("name", -ENOMEM);
|
return log_msg_ret("name", -ENOMEM);
|
||||||
|
|
||||||
ret = qemu_fwcfg_setup_kernel(qfw_dev, load, initrd);
|
/*
|
||||||
log_debug("setup kernel result %d\n", ret);
|
* create images for each; only cmdline has the actual data; the others
|
||||||
if (ret)
|
* only have a size for now, since the data has yet not been read
|
||||||
return log_msg_ret("cmd", -EIO);
|
*/
|
||||||
|
if (!bootflow_img_add(bflow, "setup",
|
||||||
|
(enum bootflow_img_t)IH_TYPE_X86_SETUP,
|
||||||
|
setup_addr, setup))
|
||||||
|
return log_msg_ret("cri", -ENOMEM);
|
||||||
|
if (!bootflow_img_add(bflow, "kernel",
|
||||||
|
(enum bootflow_img_t)IH_TYPE_KERNEL, 0, kern))
|
||||||
|
return log_msg_ret("qrk", -ENOMEM);
|
||||||
|
if (ramdisk && !bootflow_img_add(bflow, "ramdisk",
|
||||||
|
(enum bootflow_img_t)IH_TYPE_RAMDISK,
|
||||||
|
0, ramdisk))
|
||||||
|
return log_msg_ret("qrr", -ENOMEM);
|
||||||
|
if (!bootflow_img_add(bflow, "cmdline", BFI_CMDLINE,
|
||||||
|
map_to_sysmem(bflow->cmdline), cmdline_size))
|
||||||
|
return log_msg_ret("qrc", -ENOMEM);
|
||||||
bflow->state = BOOTFLOWST_READY;
|
bflow->state = BOOTFLOWST_READY;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int qfw_read_files(struct udevice *dev, struct bootflow *bflow,
|
||||||
|
bool re_read, const struct bootflow_img **simgp,
|
||||||
|
const struct bootflow_img **kimgp,
|
||||||
|
const struct bootflow_img **rimgp)
|
||||||
|
{
|
||||||
|
struct udevice *qfw_dev = dev_get_parent(bflow->dev);
|
||||||
|
struct bootflow_img *kimg, *rimg;
|
||||||
|
struct abuf setup, kern, ramdisk;
|
||||||
|
const struct bootflow_img *simg;
|
||||||
|
|
||||||
|
simg = bootflow_img_find(bflow,
|
||||||
|
(enum bootflow_img_t)IH_TYPE_X86_SETUP);
|
||||||
|
kimg = bootflow_img_findw(bflow, (enum bootflow_img_t)IH_TYPE_KERNEL);
|
||||||
|
rimg = bootflow_img_findw(bflow, (enum bootflow_img_t)IH_TYPE_RAMDISK);
|
||||||
|
if (!kimg)
|
||||||
|
return log_msg_ret("qfs", -EINVAL);
|
||||||
|
|
||||||
|
/* read files only if not already read */
|
||||||
|
if (re_read || !kimg->addr) {
|
||||||
|
abuf_init_const_addr(&setup, simg ? simg->addr : 0,
|
||||||
|
simg ? simg->size : 0);
|
||||||
|
abuf_init_const_addr(&kern, env_get_hex("kernel_addr_r", 0),
|
||||||
|
kimg->size);
|
||||||
|
abuf_init_const_addr(&ramdisk, env_get_hex("ramdisk_addr_r", 0),
|
||||||
|
rimg ? rimg->size : 0);
|
||||||
|
|
||||||
|
qemu_fwcfg_read_files(qfw_dev, &setup, &kern, &ramdisk);
|
||||||
|
kimg->addr = abuf_addr(&kern);
|
||||||
|
if (rimg)
|
||||||
|
rimg->addr = abuf_addr(&ramdisk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simgp)
|
||||||
|
*simgp = simg;
|
||||||
|
if (kimgp)
|
||||||
|
*kimgp = kimg;
|
||||||
|
if (rimgp)
|
||||||
|
*rimgp = rimg;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int qfw_read_file(struct udevice *dev, struct bootflow *bflow,
|
static int qfw_read_file(struct udevice *dev, struct bootflow *bflow,
|
||||||
const char *file_path, ulong addr,
|
const char *file_path, ulong addr,
|
||||||
enum bootflow_img_t type, ulong *sizep)
|
enum bootflow_img_t type, ulong *sizep)
|
||||||
@@ -58,15 +121,55 @@ static int qfw_read_file(struct udevice *dev, struct bootflow *bflow,
|
|||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int qfw_boot(struct udevice *dev, struct bootflow *bflow)
|
#if CONFIG_IS_ENABLED(BOOTSTD_FULL)
|
||||||
|
static int qfw_read_all(struct udevice *dev, struct bootflow *bflow)
|
||||||
{
|
{
|
||||||
|
struct bootflow_img *kimg;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = run_command("booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdtcontroladdr}",
|
kimg = bootflow_img_findw(bflow, (enum bootflow_img_t)IH_TYPE_KERNEL);
|
||||||
0);
|
if (!kimg)
|
||||||
if (ret) {
|
return log_msg_ret("qra", -ENOENT);
|
||||||
ret = run_command("bootz ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} "
|
|
||||||
"${fdtcontroladdr}", 0);
|
ret = qfw_read_files(dev, bflow, true, NULL, NULL, NULL);
|
||||||
|
if (ret)
|
||||||
|
return log_msg_ret("qrA", ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int qfw_boot(struct udevice *dev, struct bootflow *bflow)
|
||||||
|
{
|
||||||
|
const struct bootflow_img *simg, *kimg, *rimg;
|
||||||
|
char conf_fdt[20], conf_ramdisk[40], addr_img_str[20];
|
||||||
|
struct bootm_info bmi;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* read the files if not already done */
|
||||||
|
ret = qfw_read_files(dev, bflow, false, &simg, &kimg, &rimg);
|
||||||
|
if (!kimg)
|
||||||
|
return log_msg_ret("qkf", -EINVAL);
|
||||||
|
|
||||||
|
ret = booti_run(&bmi);
|
||||||
|
bootm_init(&bmi);
|
||||||
|
snprintf(conf_fdt, sizeof(conf_fdt), "%lx",
|
||||||
|
(ulong)map_to_sysmem(gd->fdt_blob));
|
||||||
|
snprintf(addr_img_str, sizeof(addr_img_str), "%lx", kimg->addr);
|
||||||
|
bmi.addr_img = addr_img_str;
|
||||||
|
snprintf(conf_ramdisk, sizeof(conf_ramdisk), "%lx:%lx", rimg->addr,
|
||||||
|
rimg->size);
|
||||||
|
bmi.conf_ramdisk = conf_ramdisk;
|
||||||
|
|
||||||
|
ret = -ENOENT;
|
||||||
|
if (IS_ENABLED(CONFIG_CMD_BOOTI))
|
||||||
|
ret = booti_run(&bmi);
|
||||||
|
if (ret && IS_ENABLED(CONFIG_CMD_BOOTZ))
|
||||||
|
ret = bootz_run(&bmi);
|
||||||
|
if (ret && IS_ENABLED(CONFIG_ZBOOT) && simg) {
|
||||||
|
ret = zboot_run_args(kimg->addr, kimg->size,
|
||||||
|
rimg->addr, rimg->size, simg->addr,
|
||||||
|
*bflow->cmdline ? bflow->cmdline : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret ? -EIO : 0;
|
return ret ? -EIO : 0;
|
||||||
@@ -85,6 +188,9 @@ static struct bootmeth_ops qfw_bootmeth_ops = {
|
|||||||
.check = qfw_check,
|
.check = qfw_check,
|
||||||
.read_bootflow = qfw_read_bootflow,
|
.read_bootflow = qfw_read_bootflow,
|
||||||
.read_file = qfw_read_file,
|
.read_file = qfw_read_file,
|
||||||
|
#if CONFIG_IS_ENABLED(BOOTSTD_FULL)
|
||||||
|
.read_all = qfw_read_all,
|
||||||
|
#endif
|
||||||
.boot = qfw_boot,
|
.boot = qfw_boot,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1413,7 +1413,7 @@ static int parse_pxefile_top(struct pxe_context *ctx, char *p, unsigned long bas
|
|||||||
err = 0;
|
err = 0;
|
||||||
switch (t.type) {
|
switch (t.type) {
|
||||||
case T_MENU:
|
case T_MENU:
|
||||||
cfg->prompt = 1;
|
// cfg->prompt = 1;
|
||||||
err = parse_menu(ctx, &p, cfg,
|
err = parse_menu(ctx, &p, cfg,
|
||||||
base + ALIGN(strlen(b) + 1, 4),
|
base + ALIGN(strlen(b) + 1, 4),
|
||||||
nest_level);
|
nest_level);
|
||||||
@@ -1460,6 +1460,7 @@ static int parse_pxefile_top(struct pxe_context *ctx, char *p, unsigned long bas
|
|||||||
|
|
||||||
case T_PROMPT:
|
case T_PROMPT:
|
||||||
err = parse_integer(&p, &cfg->prompt);
|
err = parse_integer(&p, &cfg->prompt);
|
||||||
|
cfg->prompt = 0;
|
||||||
// Do not fail if prompt configuration is undefined
|
// Do not fail if prompt configuration is undefined
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
eol_or_eof(&p);
|
eol_or_eof(&p);
|
||||||
@@ -1732,6 +1733,7 @@ struct pxe_menu *pxe_prepare(struct pxe_context *ctx, ulong pxefile_addr_r,
|
|||||||
|
|
||||||
if (prompt)
|
if (prompt)
|
||||||
cfg->prompt = prompt;
|
cfg->prompt = prompt;
|
||||||
|
cfg->prompt = 0;
|
||||||
|
|
||||||
return cfg;
|
return cfg;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,7 +95,10 @@ __weak void board_add_ram_info(int use_default)
|
|||||||
|
|
||||||
static int init_baud_rate(void)
|
static int init_baud_rate(void)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_SERIAL
|
||||||
gd->baudrate = env_get_ulong("baudrate", 10, CONFIG_BAUDRATE);
|
gd->baudrate = env_get_ulong("baudrate", 10, CONFIG_BAUDRATE);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
117
common/qfw.c
117
common/qfw.c
@@ -4,6 +4,7 @@
|
|||||||
* (C) Copyright 2021 Asherah Connor <ashe@kivikakk.ee>
|
* (C) Copyright 2021 Asherah Connor <ashe@kivikakk.ee>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <abuf.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
#include <mapmem.h>
|
#include <mapmem.h>
|
||||||
@@ -105,62 +106,106 @@ bool qfw_file_iter_end(struct fw_cfg_file_iter *iter)
|
|||||||
return iter->entry == iter->end;
|
return iter->entry == iter->end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qfw_read_size() - Read the size of an entry
|
||||||
|
*
|
||||||
|
* @sel: Selector value, e.g. FW_CFG_SETUP_SIZE, FW_CFG_CMDLINE_SIZE
|
||||||
|
* Return: Size of the entry
|
||||||
|
*/
|
||||||
|
static ulong qfw_read_size(struct udevice *qfw_dev, enum fw_cfg_selector sel)
|
||||||
|
{
|
||||||
|
u32 size = 0;
|
||||||
|
|
||||||
|
qfw_read_entry(qfw_dev, sel, 4, &size);
|
||||||
|
|
||||||
|
return le32_to_cpu(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int qemu_fwcfg_read_info(struct udevice *qfw_dev, ulong *setupp, ulong *kernp,
|
||||||
|
ulong *initrdp, struct abuf *cmdline,
|
||||||
|
ulong *setup_addrp)
|
||||||
|
{
|
||||||
|
uint cmdline_size;
|
||||||
|
|
||||||
|
*setupp = qfw_read_size(qfw_dev, FW_CFG_SETUP_SIZE);
|
||||||
|
*kernp = qfw_read_size(qfw_dev, FW_CFG_KERNEL_SIZE);
|
||||||
|
*initrdp = qfw_read_size(qfw_dev, FW_CFG_INITRD_SIZE);
|
||||||
|
cmdline_size = qfw_read_size(qfw_dev, FW_CFG_CMDLINE_SIZE);
|
||||||
|
if (!*kernp)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
*setup_addrp = qfw_read_size(qfw_dev, FW_CFG_SETUP_ADDR);
|
||||||
|
|
||||||
|
if (!abuf_init_size(cmdline, cmdline_size))
|
||||||
|
return log_msg_ret("qri", -ENOMEM);
|
||||||
|
qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_DATA, cmdline_size,
|
||||||
|
cmdline->data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void qemu_fwcfg_read_files(struct udevice *qfw_dev, const struct abuf *setup,
|
||||||
|
const struct abuf *kern, const struct abuf *initrd)
|
||||||
|
{
|
||||||
|
if (setup->size) {
|
||||||
|
qfw_read_entry(qfw_dev, FW_CFG_SETUP_DATA, setup->size,
|
||||||
|
setup->data);
|
||||||
|
}
|
||||||
|
qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA, kern->size, kern->data);
|
||||||
|
if (initrd->size) {
|
||||||
|
qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA, initrd->size,
|
||||||
|
initrd->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int qemu_fwcfg_setup_kernel(struct udevice *qfw_dev, ulong load_addr,
|
int qemu_fwcfg_setup_kernel(struct udevice *qfw_dev, ulong load_addr,
|
||||||
ulong initrd_addr)
|
ulong initrd_addr)
|
||||||
{
|
{
|
||||||
char *data_addr;
|
ulong setup_size, kernel_size, initrd_size, setup_addr;
|
||||||
u32 setup_size, kernel_size, cmdline_size, initrd_size;
|
struct abuf cmdline, setup, kern, initrd;
|
||||||
|
int ret;
|
||||||
|
|
||||||
qfw_read_entry(qfw_dev, FW_CFG_SETUP_SIZE, 4, &setup_size);
|
ret = qemu_fwcfg_read_info(qfw_dev, &setup_size, &initrd_size,
|
||||||
qfw_read_entry(qfw_dev, FW_CFG_KERNEL_SIZE, 4, &kernel_size);
|
&kernel_size, &cmdline, &setup_addr);
|
||||||
|
if (ret) {
|
||||||
if (!kernel_size) {
|
|
||||||
printf("fatal: no kernel available\n");
|
printf("fatal: no kernel available\n");
|
||||||
return -ENOENT;
|
return log_msg_ret("qsk", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
data_addr = map_sysmem(load_addr, 0);
|
/*
|
||||||
if (setup_size) {
|
* always put the setup area where QEMU wants it, since it includes
|
||||||
qfw_read_entry(qfw_dev, FW_CFG_SETUP_DATA,
|
* absolute pointers to itself
|
||||||
le32_to_cpu(setup_size), data_addr);
|
*/
|
||||||
data_addr += le32_to_cpu(setup_size);
|
abuf_init_const_addr(&setup, setup_addr, 0);
|
||||||
}
|
abuf_init_const_addr(&kern, load_addr, 0);
|
||||||
|
|
||||||
qfw_read_entry(qfw_dev, FW_CFG_KERNEL_DATA,
|
abuf_init_const_addr(&initrd, initrd_addr, 0);
|
||||||
le32_to_cpu(kernel_size), data_addr);
|
qemu_fwcfg_read_files(qfw_dev, &setup, &kern, &initrd);
|
||||||
data_addr += le32_to_cpu(kernel_size);
|
|
||||||
env_set_hex("filesize", le32_to_cpu(kernel_size));
|
|
||||||
|
|
||||||
data_addr = map_sysmem(initrd_addr, 0);
|
env_set_hex("filesize", kern.size);
|
||||||
qfw_read_entry(qfw_dev, FW_CFG_INITRD_SIZE, 4, &initrd_size);
|
|
||||||
if (!initrd_size) {
|
if (!initrd_size)
|
||||||
printf("warning: no initrd available\n");
|
printf("warning: no initrd available\n");
|
||||||
} else {
|
else
|
||||||
qfw_read_entry(qfw_dev, FW_CFG_INITRD_DATA,
|
env_set_hex("filesize", initrd_size);
|
||||||
le32_to_cpu(initrd_size), data_addr);
|
|
||||||
data_addr += le32_to_cpu(initrd_size);
|
|
||||||
env_set_hex("filesize", le32_to_cpu(initrd_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_SIZE, 4, &cmdline_size);
|
if (cmdline.data) {
|
||||||
if (cmdline_size) {
|
|
||||||
qfw_read_entry(qfw_dev, FW_CFG_CMDLINE_DATA,
|
|
||||||
le32_to_cpu(cmdline_size), data_addr);
|
|
||||||
/*
|
/*
|
||||||
* if kernel cmdline only contains '\0', (e.g. no -append
|
* if kernel cmdline only contains '\0', (e.g. no -append
|
||||||
* when invoking qemu), do not update bootargs
|
* when invoking qemu), do not update bootargs
|
||||||
*/
|
*/
|
||||||
if (*data_addr) {
|
if (*(char *)cmdline.data) {
|
||||||
if (env_set("bootargs", data_addr) < 0)
|
if (env_set("bootargs", cmdline.data) < 0)
|
||||||
printf("warning: unable to change bootargs\n");
|
printf("warning: unable to change bootargs\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
abuf_uninit(&cmdline);
|
||||||
|
|
||||||
printf("loading kernel to address %lx size %x", load_addr,
|
printf("loading kernel to address %lx size %zx", abuf_addr(&kern),
|
||||||
le32_to_cpu(kernel_size));
|
kern.size);
|
||||||
if (initrd_size)
|
if (initrd_size)
|
||||||
printf(" initrd %lx size %x\n", initrd_addr,
|
printf(" initrd %lx size %lx\n", abuf_addr(&initrd),
|
||||||
le32_to_cpu(initrd_size));
|
initrd_size);
|
||||||
else
|
else
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
|||||||
@@ -94,3 +94,34 @@ CONFIG_GENERATE_ACPI_TABLE=y
|
|||||||
CONFIG_CMD_DHRYSTONE=y
|
CONFIG_CMD_DHRYSTONE=y
|
||||||
# CONFIG_GZIP is not set
|
# CONFIG_GZIP is not set
|
||||||
CONFIG_UNIT_TEST=y
|
CONFIG_UNIT_TEST=y
|
||||||
|
CONFIG_BOOTDELAY=-1
|
||||||
|
# CONFIG_DM_ETH is not set
|
||||||
|
# CONFIG_VIRTIO_NET is not set
|
||||||
|
CONFIG_NO_NET=y
|
||||||
|
# CONFIG_VIDEO is not set
|
||||||
|
# CONFIG_SPL_VIDEO is not set
|
||||||
|
# CONFIG_CMDLINE is not set
|
||||||
|
# CONFIG_BOOTMETH_GLOBAL is not set
|
||||||
|
# CONFIG_BOOTMETH_CROS is not set
|
||||||
|
# CONFIG_BOOTMETH_EXTLINUX is not set
|
||||||
|
# CONFIG_BOOTMETH_EFILOADER is not set
|
||||||
|
# CONFIG_BOOTMETH_EFI_BOOTMGR is not set
|
||||||
|
# CONFIG_BOOTMETH_VBE is not set
|
||||||
|
CONFIG_PXE_UTILS=y
|
||||||
|
CONFIG_AUTOBOOT=y
|
||||||
|
CONFIG_PARTITION_TYPE_GUID=y
|
||||||
|
CONFIG_QFW_PIO=y
|
||||||
|
# CONFIG_EFI_LOADER is not set
|
||||||
|
# CONFIG_FIT is not set
|
||||||
|
# CONFIG_USB is not set
|
||||||
|
# CONFIG_SPI is not set
|
||||||
|
# CONFIG_SCSI is not set
|
||||||
|
# CONFIG_FS_FAT is not set
|
||||||
|
CONFIG_ENV_IS_NOWHERE=y
|
||||||
|
# CONFIG_ENV_IS_IN_FAT is not set
|
||||||
|
# CONFIG_DOS_PARTITION is not set
|
||||||
|
# CONFIG_ISO_PARTITION is not set
|
||||||
|
# CONFIG_SPL_PARTITIONS is not set
|
||||||
|
# CONFIG_NVME_PCI is not set
|
||||||
|
# CONFIG_SCSI_AHCI is not set
|
||||||
|
# CONFIG_FS_EXT4 is not set
|
||||||
|
|||||||
15
contrib/README.rst
Normal file
15
contrib/README.rst
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
The `contrib` directory contains software / files which have been contributed
|
||||||
|
to the U-Boot project but are not maintained by the core developers.
|
||||||
|
|
||||||
|
Note to contributors: Each item must have at least an entry in this file. Be
|
||||||
|
sure to add the appropriate GPL-2.0-or-later SPDX tag to files.
|
||||||
|
|
||||||
|
QEMU boot-timer script
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Runs qboot (or builds and starts U-Boot) and measures how long it takes to
|
||||||
|
start Lunux. Must be run in the U-Boot source directory.
|
||||||
|
|
||||||
|
File: `qemu-boot-timer.sh <../../../../contrib/qemu-boot-timer.sh>`_
|
||||||
99
contrib/qemu-boot-timer.sh
Executable file
99
contrib/qemu-boot-timer.sh
Executable file
@@ -0,0 +1,99 @@
|
|||||||
|
#/bin/bash
|
||||||
|
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
# .. code-block:: bash
|
||||||
|
# qemu-boot-timer.sh
|
||||||
|
#
|
||||||
|
# Runs qboot (or builds and starts U-Boot) and measures how long it takes to
|
||||||
|
# start Linux. Must be run in the U-Boot source directory.
|
||||||
|
|
||||||
|
# You will need to first install tracing tools, e.g.:
|
||||||
|
#
|
||||||
|
# sudo apt install linux-tools-common linux-tools-generic linux-tools-`uname -r`
|
||||||
|
#
|
||||||
|
# and also change files and directories below
|
||||||
|
#
|
||||||
|
# Example usage to test qboot:
|
||||||
|
|
||||||
|
# $ ./contrib/qemu-boot-timer.sh
|
||||||
|
# qemu-system-x86_64: terminating on signal 15 from pid 3548708 (bash)
|
||||||
|
# 1) pid 3548829
|
||||||
|
# qemu_init_end: 48.352996
|
||||||
|
# fw_start: 48.480586 (+0.12759)
|
||||||
|
# linux_start_boot: 66.16271 (+17.682124)
|
||||||
|
# Exit point 0: 66.37544 (+0.21273)
|
||||||
|
#
|
||||||
|
# That shows a time of 17.7 milliseconds for qboot itself
|
||||||
|
|
||||||
|
# Enable this to boot qboot instead of U-Boot
|
||||||
|
#QBOOT=-QB
|
||||||
|
|
||||||
|
# Linux version to boot (read from /boot)
|
||||||
|
version=6.8.0-60-generic
|
||||||
|
|
||||||
|
# UUID of root disk within your disk image, which must be called root.img
|
||||||
|
uuid=bcfdda4a-8249-4f40-9f0f-7c1a76b6cbe8
|
||||||
|
|
||||||
|
# Set up directories to use
|
||||||
|
DIR=/scratch/sglass/qemu-boot-time/
|
||||||
|
PERF_DATA=perf.data
|
||||||
|
export PERF_EXEC_PATH=/scratch/sglass/linux/tools/perf
|
||||||
|
|
||||||
|
# No settings below here:
|
||||||
|
|
||||||
|
# Turn on tracing in Linux
|
||||||
|
sudo bash <<EOF
|
||||||
|
echo 1 > /sys/kernel/debug/tracing/events/kvm/enable
|
||||||
|
echo -1 > /proc/sys/kernel/perf_event_paranoid
|
||||||
|
mount -o remount,mode=755 /sys/kernel/debug
|
||||||
|
mount -o remount,mode=755 /sys/kernel/debug/tracing
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Start recording
|
||||||
|
echo "starting perf"
|
||||||
|
sleep 1
|
||||||
|
cd $DIR
|
||||||
|
sudo perf record -a -e kvm:kvm_entry -e kvm:kvm_pio -e sched:sched_process_exec \
|
||||||
|
-o $PERF_DATA 2> /tmp/trace.log &
|
||||||
|
PERF_PID=$!
|
||||||
|
|
||||||
|
# Run QEWU with qboot or U-Boot (builds U-Boot automatically)
|
||||||
|
sleep 1
|
||||||
|
cd ~/u
|
||||||
|
echo "building U-Boot"
|
||||||
|
./scripts/build-qemu -a x86 ${QBOOT} -s -v -K /boot/vmlinuz-${version} \
|
||||||
|
-k -d root.img -I /boot/initrd.img-${version} -C -U ${uuid} \
|
||||||
|
2>&1 >/tmp/qemu.log
|
||||||
|
|
||||||
|
echo "running U-Boot in QEMU"
|
||||||
|
./scripts/build-qemu -a x86 ${QBOOT} -rsB -v -K /boot/vmlinuz-${version} \
|
||||||
|
-k -d root.img -I /boot/initrd.img-${version} -C -U ${uuid} \
|
||||||
|
2>&1 >/tmp/qemu.log &
|
||||||
|
|
||||||
|
while [[ -z "$QEMU_PID" ]]; do
|
||||||
|
QEMU_PID=$(pgrep qemu-system-x86)
|
||||||
|
done
|
||||||
|
|
||||||
|
# Wait for it to boot (increase this on slow machines)
|
||||||
|
echo "waiting for a bit"
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# Kill QEMU and the perf process
|
||||||
|
kill $QEMU_PID
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
kill $PERF_PID
|
||||||
|
wait $PERF_PID
|
||||||
|
|
||||||
|
# Adjust permissions on perf data
|
||||||
|
cd $DIR
|
||||||
|
sudo chmod a+r $PERF_DATA
|
||||||
|
|
||||||
|
# Generate the Python script to permit access to the trace
|
||||||
|
perf script -g python 2>/dev/null
|
||||||
|
|
||||||
|
# Run our script which looks for timing points and prints the results
|
||||||
|
echo "parsing perf results"
|
||||||
|
perf script -s ~/perf-script.py -s ${DIR}/perf-script/qemu-perf-script.py \
|
||||||
|
-i $PERF_DATA
|
||||||
6
doc/develop/contrib/index.rst
Normal file
6
doc/develop/contrib/index.rst
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
Contributions
|
||||||
|
=============
|
||||||
|
|
||||||
|
.. include:: ../../../contrib/README.rst
|
||||||
@@ -113,3 +113,11 @@ Historical documentation
|
|||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
historical/index
|
historical/index
|
||||||
|
|
||||||
|
Contributions
|
||||||
|
-------------
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
contrib/index
|
||||||
|
|||||||
@@ -202,6 +202,18 @@ void abuf_init_set(struct abuf *abuf, void *data, size_t size);
|
|||||||
*/
|
*/
|
||||||
void abuf_init_const(struct abuf *abuf, const void *data, size_t size);
|
void abuf_init_const(struct abuf *abuf, const void *data, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* abuf_init_const_addr() - Set up a new buffer at a given address
|
||||||
|
*
|
||||||
|
* This is similar to abuf_init_const() except that it takes an address instead
|
||||||
|
* of a pointer. Note that the abuf is unallocated.
|
||||||
|
*
|
||||||
|
* @abuf: abuf to set up
|
||||||
|
* @addr: Address to use
|
||||||
|
* @size: Size of buffer
|
||||||
|
*/
|
||||||
|
void abuf_init_const_addr(struct abuf *abuf, ulong addr, size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* abuf_init_size() - Set up an allocated abuf
|
* abuf_init_size() - Set up an allocated abuf
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -648,6 +648,16 @@ struct bootflow_img *bootflow_img_add(struct bootflow *bflow, const char *fname,
|
|||||||
enum bootflow_img_t type, ulong addr,
|
enum bootflow_img_t type, ulong addr,
|
||||||
ulong size);
|
ulong size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bootflow_img_findw() - Find the first image of a given type
|
||||||
|
*
|
||||||
|
* @bflow: Bootflow to search
|
||||||
|
* @type: Image type to search for
|
||||||
|
* Return: Non-const pointer to image, or NULL if not found
|
||||||
|
*/
|
||||||
|
struct bootflow_img *bootflow_img_findw(const struct bootflow *bflow,
|
||||||
|
enum bootflow_img_t type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bootflow_img_find() - Find the first image of a given type
|
* bootflow_img_find() - Find the first image of a given type
|
||||||
*
|
*
|
||||||
@@ -655,8 +665,12 @@ struct bootflow_img *bootflow_img_add(struct bootflow *bflow, const char *fname,
|
|||||||
* @type: Image type to search for
|
* @type: Image type to search for
|
||||||
* Return: Pointer to image, or NULL if not found
|
* Return: Pointer to image, or NULL if not found
|
||||||
*/
|
*/
|
||||||
const struct bootflow_img *bootflow_img_find(const struct bootflow *bflow,
|
static inline const struct bootflow_img *
|
||||||
enum bootflow_img_t type);
|
bootflow_img_find(const struct bootflow *bflow,
|
||||||
|
enum bootflow_img_t type)
|
||||||
|
{
|
||||||
|
return bootflow_img_findw(bflow, type);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bootflow_get_seq() - Get the sequence number of a bootflow
|
* bootflow_get_seq() - Get the sequence number of a bootflow
|
||||||
|
|||||||
2
include/env/x86.env
vendored
2
include/env/x86.env
vendored
@@ -11,7 +11,7 @@ netdev=eth0
|
|||||||
consoledev=ttyS0
|
consoledev=ttyS0
|
||||||
scriptaddr=0x7000000
|
scriptaddr=0x7000000
|
||||||
kernel_addr_r=0x1000000
|
kernel_addr_r=0x1000000
|
||||||
ramdisk_addr_r=0x4000000
|
ramdisk_addr_r=0x8000000
|
||||||
ramdiskfile=initramfs.gz
|
ramdiskfile=initramfs.gz
|
||||||
|
|
||||||
/* common console settings */
|
/* common console settings */
|
||||||
|
|||||||
@@ -8,12 +8,14 @@
|
|||||||
|
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
|
|
||||||
|
struct abuf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List of firmware configuration item selectors. The official source of truth
|
* List of firmware configuration item selectors. The official source of truth
|
||||||
* for these is the QEMU source itself; see
|
* for these is the QEMU source itself; see
|
||||||
* https://github.com/qemu/qemu/blob/master/hw/nvram/fw_cfg.c
|
* https://github.com/qemu/qemu/blob/master/hw/nvram/fw_cfg.c
|
||||||
*/
|
*/
|
||||||
enum {
|
enum fw_cfg_selector {
|
||||||
FW_CFG_SIGNATURE = 0x00,
|
FW_CFG_SIGNATURE = 0x00,
|
||||||
FW_CFG_ID = 0x01,
|
FW_CFG_ID = 0x01,
|
||||||
FW_CFG_UUID = 0x02,
|
FW_CFG_UUID = 0x02,
|
||||||
@@ -316,12 +318,47 @@ bool qfw_file_iter_end(struct fw_cfg_file_iter *iter);
|
|||||||
*/
|
*/
|
||||||
int qemu_cpu_fixup(void);
|
int qemu_cpu_fixup(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemu_fwcfg_read_info() - See if QEMU has provided kernel, etc.
|
||||||
|
*
|
||||||
|
* Read info about the kernel and cmdline
|
||||||
|
*
|
||||||
|
* @qfw_dev: UCLASS_QFW device
|
||||||
|
* @setupp: Returns the size of the setup area on succes
|
||||||
|
* @kernp: Returns kernel size on success
|
||||||
|
* @initrd: Returns initrd size on success
|
||||||
|
* @cmdline: Set to the cmdline in the image (allocated by this function, must
|
||||||
|
* be freed by the caller)
|
||||||
|
* @setup_addrp: Address for the setup block, as requested by QEMU
|
||||||
|
*
|
||||||
|
* Return 0 on success, -ENOENT if there is no kernel provided, -ENOMEM if there
|
||||||
|
* was no memory for the cmdline
|
||||||
|
*/
|
||||||
|
int qemu_fwcfg_read_info(struct udevice *qfw_dev, ulong *setupp, ulong *kernp,
|
||||||
|
ulong *initrdp, struct abuf *cmdline,
|
||||||
|
ulong *setup_addrp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemu_fwcfg_read_files() - Read files from a qfw
|
||||||
|
*
|
||||||
|
* Reads kernel and optional setup/initrd images. For each image, the abuf
|
||||||
|
* controls how many bytes are read and the address into which they are read
|
||||||
|
*
|
||||||
|
* @qfw_dev: UCLASS_QFW device
|
||||||
|
* @setup: Buffer into which to read setup (skipped if setup->size is 0)
|
||||||
|
* @kern: Buffer into which to read kernel
|
||||||
|
* @initrd: Buffer into which to read initrd (skipped if initrd->size is 0)
|
||||||
|
*/
|
||||||
|
void qemu_fwcfg_read_files(struct udevice *qfw_dev, const struct abuf *setup,
|
||||||
|
const struct abuf *kern, const struct abuf *initrd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* qemu_fwcfg_setup_kernel() - Prepare the kernel for zboot
|
* qemu_fwcfg_setup_kernel() - Prepare the kernel for zboot
|
||||||
*
|
*
|
||||||
* Loads kernel data to 'load_addr', initrd to 'initrd_addr' and kernel command
|
* Loads kernel data to 'load_addr', initrd to 'initrd_addr' and kernel command
|
||||||
* line using qemu fw_cfg interface
|
* line using qemu fw_cfg interface
|
||||||
*
|
*
|
||||||
|
* @qfw_dev: UCLASS_QFW device
|
||||||
* @load_addr: Load address for kernel
|
* @load_addr: Load address for kernel
|
||||||
* @initrd_addr: Load address for ramdisk
|
* @initrd_addr: Load address for ramdisk
|
||||||
* @return 0 if OK, -ENOENT if no kernel
|
* @return 0 if OK, -ENOENT if no kernel
|
||||||
|
|||||||
@@ -183,6 +183,13 @@ void abuf_init_const(struct abuf *abuf, const void *data, size_t size)
|
|||||||
abuf_init_set(abuf, (void *)data, size);
|
abuf_init_set(abuf, (void *)data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_HOSTCC
|
||||||
|
void abuf_init_const_addr(struct abuf *abuf, ulong addr, size_t size)
|
||||||
|
{
|
||||||
|
return abuf_init_const(abuf, map_sysmem(addr, size), size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void abuf_init_move(struct abuf *abuf, void *data, size_t size)
|
void abuf_init_move(struct abuf *abuf, void *data, size_t size)
|
||||||
{
|
{
|
||||||
abuf_init_set(abuf, data, size);
|
abuf_init_set(abuf, data, size);
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ def parse_args():
|
|||||||
help='Select architecture (arm, x86) Default: arm')
|
help='Select architecture (arm, x86) Default: arm')
|
||||||
parser.add_argument('-B', '--no-build', action='store_true',
|
parser.add_argument('-B', '--no-build', action='store_true',
|
||||||
help="Don't build; assume a build exists")
|
help="Don't build; assume a build exists")
|
||||||
|
parser.add_argument('-C', '--enable-console', action='store_true',
|
||||||
|
help="Enable linux console (x86 only)")
|
||||||
parser.add_argument('-d', '--disk',
|
parser.add_argument('-d', '--disk',
|
||||||
help='Root disk image file to use with QEMU')
|
help='Root disk image file to use with QEMU')
|
||||||
parser.add_argument('-D', '--share-dir', metavar='DIR',
|
parser.add_argument('-D', '--share-dir', metavar='DIR',
|
||||||
@@ -52,11 +54,17 @@ def parse_args():
|
|||||||
help='Run UEFI Self-Certification Test (SCT)')
|
help='Run UEFI Self-Certification Test (SCT)')
|
||||||
parser.add_argument('-E', '--use-tianocore', action='store_true',
|
parser.add_argument('-E', '--use-tianocore', action='store_true',
|
||||||
help='Run Tianocore (OVMF) instead of U-Boot')
|
help='Run Tianocore (OVMF) instead of U-Boot')
|
||||||
|
parser.add_argument('-I', '--initrd',
|
||||||
|
help='Initial ramdisk to run using -initrd')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-k', '--kvm', action='store_true',
|
'-k', '--kvm', action='store_true',
|
||||||
help='Use KVM (Kernel-based Virtual Machine) for acceleration')
|
help='Use KVM (Kernel-based Virtual Machine) for acceleration')
|
||||||
|
parser.add_argument('-K', '--kernel',
|
||||||
|
help='Kernel to run using -kernel')
|
||||||
parser.add_argument('-o', '--os', metavar='NAME', choices=['ubuntu'],
|
parser.add_argument('-o', '--os', metavar='NAME', choices=['ubuntu'],
|
||||||
help='Run a specified Operating System')
|
help='Run a specified Operating System')
|
||||||
|
parser.add_argument('-Q', '--use-qboot', action='store_true',
|
||||||
|
help='Run qboot instead of U-Boot')
|
||||||
parser.add_argument('-r', '--run', action='store_true',
|
parser.add_argument('-r', '--run', action='store_true',
|
||||||
help='Run QEMU with the built/specified image')
|
help='Run QEMU with the built/specified image')
|
||||||
parser.add_argument('-x', '--xpl', action='store_true',
|
parser.add_argument('-x', '--xpl', action='store_true',
|
||||||
@@ -70,6 +78,12 @@ def parse_args():
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-S', '--sct-seq',
|
'-S', '--sct-seq',
|
||||||
help='SCT sequence-file to be written into the SCT image if -e')
|
help='SCT sequence-file to be written into the SCT image if -e')
|
||||||
|
parser.add_argument(
|
||||||
|
'-t', '--root',
|
||||||
|
help='Pass the given root device to linux via root=xxx')
|
||||||
|
parser.add_argument(
|
||||||
|
'-U', '--uuid',
|
||||||
|
help='Pass the given root device to linux via root=/dev/disk/by-uuid/')
|
||||||
parser.add_argument('-v', '--verbose', action='store_true',
|
parser.add_argument('-v', '--verbose', action='store_true',
|
||||||
help='Show executed commands')
|
help='Show executed commands')
|
||||||
parser.add_argument('-w', '--word-32bit', action='store_true',
|
parser.add_argument('-w', '--word-32bit', action='store_true',
|
||||||
@@ -92,6 +106,7 @@ class BuildQemu:
|
|||||||
self.sctdir = Path(self.helper.get_setting('sct_dir', '~/dev/efi/sct'))
|
self.sctdir = Path(self.helper.get_setting('sct_dir', '~/dev/efi/sct'))
|
||||||
self.tiano = Path(self.helper.get_setting('tianocore_dir',
|
self.tiano = Path(self.helper.get_setting('tianocore_dir',
|
||||||
'~/dev/tiano'))
|
'~/dev/tiano'))
|
||||||
|
self.qboot = Path(self.helper.get_setting('qboot_dir', '~/dev/qboot'))
|
||||||
self.mnt = Path(self.helper.get_setting('sct_mnt', '/mnt/sct'))
|
self.mnt = Path(self.helper.get_setting('sct_mnt', '/mnt/sct'))
|
||||||
|
|
||||||
self.bitness = 32 if args.word_32bit else 64
|
self.bitness = 32 if args.word_32bit else 64
|
||||||
@@ -138,6 +153,12 @@ class BuildQemu:
|
|||||||
tout.fatal(
|
tout.fatal(
|
||||||
'Error: Tianocore BIOS specified (-E) but not found at '
|
'Error: Tianocore BIOS specified (-E) but not found at '
|
||||||
f'{bios_override}')
|
f'{bios_override}')
|
||||||
|
elif args.use_qboot:
|
||||||
|
bios_override = Path(self.qboot, 'bios.bin')
|
||||||
|
if not bios_override.exists():
|
||||||
|
tout.fatal(
|
||||||
|
'Error: qboot BIOS specified (-Q) but not found at '
|
||||||
|
f'{bios_override}')
|
||||||
|
|
||||||
self.seq_fname = Path(args.sct_seq) if args.sct_seq else None
|
self.seq_fname = Path(args.sct_seq) if args.sct_seq else None
|
||||||
self.img_fname = Path(args.disk) if args.disk else None
|
self.img_fname = Path(args.disk) if args.disk else None
|
||||||
@@ -281,13 +302,15 @@ class BuildQemu:
|
|||||||
if not self.bios.exists():
|
if not self.bios.exists():
|
||||||
tout.fatal(f"Error: BIOS file '{self.bios}' not found")
|
tout.fatal(f"Error: BIOS file '{self.bios}' not found")
|
||||||
|
|
||||||
|
cmdline = []
|
||||||
|
|
||||||
qemu_cmd = [str(self.qemu)]
|
qemu_cmd = [str(self.qemu)]
|
||||||
if self.bios:
|
if self.bios:
|
||||||
qemu_cmd.extend(['-bios', str(self.bios)])
|
qemu_cmd.extend(['-bios', str(self.bios)])
|
||||||
qemu_cmd.extend(self.kvm_params)
|
qemu_cmd.extend(self.kvm_params)
|
||||||
qemu_cmd.extend(['-m', self.mem])
|
qemu_cmd.extend(['-m', self.mem])
|
||||||
|
|
||||||
if not self.args.sct_run:
|
if not self.args.sct_run and not self.qboot:
|
||||||
qemu_cmd.extend(['-netdev', 'user,id=net0,hostfwd=tcp::2222-:22',
|
qemu_cmd.extend(['-netdev', 'user,id=net0,hostfwd=tcp::2222-:22',
|
||||||
'-device', 'virtio-net-pci,netdev=net0'])
|
'-device', 'virtio-net-pci,netdev=net0'])
|
||||||
|
|
||||||
@@ -301,6 +324,21 @@ class BuildQemu:
|
|||||||
if not any(item.startswith('-serial') for item in self.qemu_extra):
|
if not any(item.startswith('-serial') for item in self.qemu_extra):
|
||||||
qemu_cmd.extend(['-serial', 'mon:stdio'])
|
qemu_cmd.extend(['-serial', 'mon:stdio'])
|
||||||
|
|
||||||
|
if self.args.kernel:
|
||||||
|
qemu_cmd.extend(['-kernel', self.args.kernel])
|
||||||
|
if self.args.initrd:
|
||||||
|
qemu_cmd.extend(['-initrd', self.args.initrd])
|
||||||
|
|
||||||
|
if self.args.enable_console:
|
||||||
|
cmdline.append('console=ttyS0,115200,8n1')
|
||||||
|
if self.args.root:
|
||||||
|
cmdline.append(f'root={self.args.root}')
|
||||||
|
if self.args.uuid:
|
||||||
|
cmdline.append(f'root=/dev/disk/by-uuid/{self.args.uuid}')
|
||||||
|
|
||||||
|
if cmdline:
|
||||||
|
qemu_cmd.extend(['-append'] + [' '.join(cmdline)])
|
||||||
|
|
||||||
# Add other parameters gathered from options
|
# Add other parameters gathered from options
|
||||||
qemu_cmd.extend(self.qemu_extra)
|
qemu_cmd.extend(self.qemu_extra)
|
||||||
if self.os_path:
|
if self.os_path:
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class Helper:
|
|||||||
self.settings = configparser.ConfigParser()
|
self.settings = configparser.ConfigParser()
|
||||||
fname = f'{os.getenv("HOME")}/.u_boot_qemu'
|
fname = f'{os.getenv("HOME")}/.u_boot_qemu'
|
||||||
if not os.path.exists(fname):
|
if not os.path.exists(fname):
|
||||||
print('No config file found: {fname}\nCreating one...\n')
|
print(f'No config file found: {fname}\nCreating one...\n')
|
||||||
tools.write_file(fname, '''# U-Boot QEMU-scripts config
|
tools.write_file(fname, '''# U-Boot QEMU-scripts config
|
||||||
|
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
|||||||
@@ -1417,6 +1417,7 @@ static int bootstd_images(struct unit_test_state *uts)
|
|||||||
const struct legacy_img_hdr *hdr;
|
const struct legacy_img_hdr *hdr;
|
||||||
const struct bootflow_img *img;
|
const struct bootflow_img *img;
|
||||||
const struct bootflow *bflow;
|
const struct bootflow *bflow;
|
||||||
|
struct bootflow_img *wimg;
|
||||||
struct bootstd_priv *std;
|
struct bootstd_priv *std;
|
||||||
const char **old_order;
|
const char **old_order;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
@@ -1504,6 +1505,15 @@ static int bootstd_images(struct unit_test_state *uts)
|
|||||||
|
|
||||||
ut_assertnull(bootflow_img_find(bflow, BFI_CMDLINE));
|
ut_assertnull(bootflow_img_find(bflow, BFI_CMDLINE));
|
||||||
|
|
||||||
|
/* check we can update an image size */
|
||||||
|
wimg = bootflow_img_findw(bflow, (enum bootflow_img_t)IH_TYPE_SCRIPT);
|
||||||
|
ut_assertnonnull(wimg);
|
||||||
|
wimg->size = 123;
|
||||||
|
|
||||||
|
img = bootflow_img_find(bflow, (enum bootflow_img_t)IH_TYPE_SCRIPT);
|
||||||
|
ut_assertnonnull(img);
|
||||||
|
ut_asserteq(123, img->size);
|
||||||
|
|
||||||
ut_assert_console_end();
|
ut_assert_console_end();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -68,6 +68,28 @@ static int lib_test_abuf_init_const(struct unit_test_state *uts)
|
|||||||
}
|
}
|
||||||
LIB_TEST(lib_test_abuf_init_const, 0);
|
LIB_TEST(lib_test_abuf_init_const, 0);
|
||||||
|
|
||||||
|
/* Test abuf_init_const_addr() */
|
||||||
|
static int lib_test_abuf_init_const_addr(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct abuf buf;
|
||||||
|
ulong start;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
start = ut_check_free();
|
||||||
|
|
||||||
|
ptr = map_sysmem(0x100, 0);
|
||||||
|
|
||||||
|
abuf_init_const_addr(&buf, 0x100, 10);
|
||||||
|
ut_asserteq_ptr(ptr, buf.data);
|
||||||
|
ut_asserteq(10, buf.size);
|
||||||
|
|
||||||
|
/* No memory should have been allocated */
|
||||||
|
ut_assertok(ut_check_delta(start));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LIB_TEST(lib_test_abuf_init_const_addr, 0);
|
||||||
|
|
||||||
/* Test abuf_map_sysmem() and abuf_addr() */
|
/* Test abuf_map_sysmem() and abuf_addr() */
|
||||||
static int lib_test_abuf_map_sysmem(struct unit_test_state *uts)
|
static int lib_test_abuf_map_sysmem(struct unit_test_state *uts)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user