Skip to the content.

seabios

现在的设想是,如果知道只是一些 ioport 来这些设备,一个个的填补也不错。 对于 pci 只需要一个很小的支持,而对于 acpi 的支持几乎为 0

问题

device seabios QEMU
pci pci_probe_host, pci_config_readw  
acpi    
serial serial_setup (PORT_SERIAL1 0x3f8)  
timer tsctimer_setup (PORT_PIT_MODE 0x43)  
rtc rtc_write / rtc_read  

vga

取决于启动的方式,如果 -nographic 的话这个这三个函数被注释掉似乎没有任何影响。

但是如果是在 graphic mode, 那么会导致 gtk 的界面永远都是 Guest has not initialized the diaplay(yet)

threads

The goal of these threads is to reduce overall boot time by parallelizing hardware delays. (For example, by allowing the wait for an ATA hard drive to spin-up and respond to commands to occur in parallel with the wait for a PS/2 keyboard to respond to a setup command.) These hardware setup threads are only available during the “setup” sub-phase of the POST phase.1

基本调用路径

The emulators map the SeaBIOS binary to this address, and SeaBIOS arranges for romlayout.S:reset_vector() to be present there. This code calls romlayout.S:entry_post() which then calls post.c:handle_post() in 32bit mode.1

结论

kvm_detect 中使用一条 cpuid 指令,来知道当前在 KVM 中间运行

P69 : 在 fw_cfg_io_realize 调用 memory_region_init_io 来实现分配 FW_CFG_CTL_SIZE 的

总结下,fw_cfg : 存在一些数值是常规定义的,没有定义过的为 file,fw_cfg_add_file_callback 会计算出其偏移 file 的偏移,并且将文件信息放到 FWCfgFiles *files; 中间:

acpi 在 seabios 中是怎么处理的

  1. ACPI 在 seabios 中是一个标准定义项目
    #define QEMU_CFG_ACPI_TABLES            (QEMU_CFG_ARCH_LOCAL + 0)
    
  2. qemu_cfg_legacy : 中通过约定好的位置读去 acpi 的代码
    • qemu_cfg_read_entry(&cnt, QEMU_CFG_ACPI_TABLES, sizeof(cnt));
    • qemu_romfile_add(name, QEMU_CFG_ACPI_TABLES, offset, len);
  3. qemu_platform_setup
    • pci_setup
    • smbios_setup
    • smbios_romfile_setup : 参考 smbios.c - [ ] romfile_loader_execute : 这个 table loader 是做什么的 - find_acpi_rsdp : 在一个范围 find_acpi_rsdp f48c0 --> f50c0 内比对字符串
    • 其实让我疑惑的问题在于,rsdp 不是通过 fw_cfg 传递过来的吗? - acpi_dsdt_parse
    • struct fadt_descriptor_rev1 *fadt = find_acpi_table(FACP_SIGNATURE); : 通过 rdsp 找到 fadt
    • u8 *dsdt = (void*)(fadt->dsdt);
    • 然后会遍历所有的设备 - virtio_mmio_setup_acpi
    • acpi_dsdt_find_string : static const char *virtio_hid = "LNRO0005"; 使用 hid 在 static struct hlist_head acpi_devices VARVERIFY32INIT; 中查询
    • 因为没有配置 virtio,所以,这里并没有找到设备
    • virtio 为什么需要 bios 支持,是不是为了枚举出来这个 virtio 设备 - acpi_setup : fw_cfg 当没有提供 acpi table 的时候,这个函数将会让 seabios 重新构建一次 acpi 的内容

在 seabios/src/std/acpi.h 中定义了 RSDP 和 RSDT/XSDT

struct rsdp_descriptor {        /* Root System Descriptor Pointer */
    u64 signature;              /* ACPI signature, contains "RSD PTR " */
    u8  checksum;               /* To make sum of struct == 0 */
    u8  oem_id [6];             /* OEM identification */
    u8  revision;               /* Must be 0 for 1.0, 2 for 2.0 */
    u32 rsdt_physical_address;  /* 32-bit physical address of RSDT */
    u32 length;                 /* XSDT Length in bytes including hdr */
    u64 xsdt_physical_address;  /* 64-bit physical address of XSDT */
    u8  extended_checksum;      /* Checksum of entire table */
    u8  reserved [3];           /* Reserved field must be 0 */
};

/* Table structure from Linux kernel (the ACPI tables are under the
   BSD license) */

#define ACPI_TABLE_HEADER_DEF   /* ACPI common table header */ \
    u32 signature;          /* ACPI signature (4 ASCII characters) */ \
    u32 length;                 /* Length of table, in bytes, including header */ \
    u8  revision;               /* ACPI Specification minor version # */ \
    u8  checksum;               /* To make sum of entire table == 0 */ \
    u8  oem_id [6];             /* OEM identification */ \
    u8  oem_table_id [8];       /* OEM table identification */ \
    u32 oem_revision;           /* OEM revision number */ \
    u8  asl_compiler_id [4];    /* ASL compiler vendor ID */ \
    u32 asl_compiler_revision;  /* ASL compiler revision number */

/*
 * ACPI 1.0 Root System Description Table (RSDT)
 */
#define RSDT_SIGNATURE 0x54445352 // RSDT
struct rsdt_descriptor_rev1
{
    ACPI_TABLE_HEADER_DEF       /* ACPI common table header */
    u32 table_offset_entry[0];  /* Array of pointers to other */
    /* ACPI tables */
} PACKED;

/*
 * ACPI 2.0 eXtended System Description Table (XSDT)
 */
#define XSDT_SIGNATURE 0x54445358 // XSDT
struct xsdt_descriptor_rev2
{
    ACPI_TABLE_HEADER_DEF       /* ACPI common table header */
    u64 table_offset_entry[0];  /* Array of pointers to other */
    /* ACPI tables */
} PACKED;

length : 从而知道 table_offset_entry 到底存在多少项了.

ACPI: dumping dsdt devices

ACPI: dumping dsdt devices
    SF8
    SF0
    SE8
    SE0
    SD8
    SD0
    SC8
    SC0
    SB8
    SB0
    SA8
    SA0
    S98
    S90
    S88
    S80
    S78
    S70
    S68
    S60
    S58
    S50
    S48
    S40
    S38
    S30
    S28
    S20
    S18
    S10
    S00
    FWCF, hid, sta (0x8), crs
        i/o 0x510 -> 0x51b
    PHPR, hid, sta (0x8), crs
        i/o 0xae00 -> 0xae17  // acpi-pci-hotplug
    GPE0, hid, sta (0x8), crs // acpi-gpe0
        i/o 0xafe0 -> 0xafe3
    \_SB.CPUS, hid
    \_SB.PCI0.PRES, hid, crs // acpi-cpu-hotplug
        i/o 0xaf00 -> 0xaf0b
    LNKS, hid, sta (0x14)
    LNKD, hid, sta (0x14)
    LNKC, hid, sta (0x14)
    LNKB, hid, sta (0x14)
    LNKA, hid, sta (0x14)
    RTC, hid, crs
        i/o 0x70 -> 0x77
        irq 8
    COM1, hid, sta (0x8), crs // 串口
        i/o 0x3f8 -> 0x3ff
        irq 4
    LPT1, hid, sta (0x8), crs // 并口
        i/o 0x378 -> 0x37f
        irq 7
    FLPA
    FDC0, hid, crs            // 软盘
        i/o 0x3f2 -> 0x3f5
        i/o 0x3f7 -> 0x3f7
        irq 6
parse_resource: small: 0x5 (len 3)
    MOU, hid, sta (0x8), crs
        irq 12
    KBD, hid, sta (0x8), crs
        i/o 0x60 -> 0x60
        i/o 0x64 -> 0x64
        irq 1
    ISA
    HPET, hid, sta (0x14), crs
        mem 0xfed00000 -> 0xfed003ff
    PCI0, hid

在 seabios/src/fw/dsdt_parser.c: parse_resource 将资源划分为 small resource, 所以打印分为两种。

qemu 是如何制作这个东西的

参考 ./hack/acpi/acpi.md 中 ACPI considerations for PCI host bridges, 大概可以知道 acpi 的 crs 就是用于记录 io 空间和 irq 的

在 https://github.com/disdi/ACPI/blob/master/debian/ssdt.dsl 似乎找到了对应的 QEMU 对应的 dsl

总体来说,是从 build_dsdt 的位置触发的。

[ ] 为什么在 seabios 中间会调用 acpi_build_update

调用位置在 romfile_loader_execute 中间的

[rom : kvmvapic.bin]
[rom : linuxboot_dma.bin]
[rom : /home/maritns3/core/seabios/out/bios.bin]
[rom : etc/acpi/tables]
[rom : etc/table-loader]
[rom : etc/acpi/rsdp]

下面三个都是在 acpi_setup 中初始化的,通过函数 acpi_add_rom_blob

qemu_detect

在 qemu_detect 中,通过检测 host bridge, 可以发现判断当前在 qemu 中间运行。

其在 Qemu 中设置的位置是,而检测正好是 device_id

static void i440fx_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->realize = i440fx_realize;
    k->config_write = i440fx_write_config;
    k->vendor_id = PCI_VENDOR_ID_INTEL;
    k->device_id = PCI_DEVICE_ID_INTEL_82441;
    k->revision = 0x02;
    k->class_id = PCI_CLASS_BRIDGE_HOST;
    dc->desc = "Host bridge";
    dc->vmsd = &vmstate_i440fx;
    /*
     * PCI-facing part of the host bridge, not usable without the
     * host-facing part, which can't be device_add'ed, yet.
     */
    dc->user_creatable = false;
    dc->hotpluggable   = false;
}
/**
#0  do_pci_register_device (errp=<optimized out>, devfn=<optimized out>, name=<optimized out>, pci_dev=<optimized out>) at ../hw/pci/pci.c:1016
#1  pci_qdev_realize (qdev=0x555556892a90, errp=0x7fffffffd330) at ../hw/pci/pci.c:2110
#2  0x0000555555cade57 in device_set_realized (obj=<optimized out>, value=true, errp=0x7fffffffd3b0) at ../hw/core/qdev.c:761
#3  0x0000555555c9b1aa in property_set_bool (obj=0x555556892a90, v=<optimized out>, name=<optimized out>, opaque=0x5555565d1db0, errp=0x7fffffffd3b0) at ../qom/object.c :2257
#4  0x0000555555c9d6bc in object_property_set (obj=obj@entry=0x555556892a90, name=name@entry=0x555555ed7fb6 "realized", v=v@entry=0x555556ac7f00, errp=errp@entry=0x5555 564e2e30 <error_fatal>) at ../qom/object.c:1402
#5  0x0000555555c9f9f4 in object_property_set_qobject (obj=obj@entry=0x555556892a90, name=name@entry=0x555555ed7fb6 "realized", value=value@entry=0x5555568bc0f0, errp=e rrp@entry=0x5555564e2e30 <error_fatal>) at ../qom/qom-qobject.c:28
#6  0x0000555555c9d909 in object_property_set_bool (obj=0x555556892a90, name=0x555555ed7fb6 "realized", value=<optimized out>, errp=0x5555564e2e30 <error_fatal>) at ../ qom/object.c:1472
#7  0x0000555555cacd23 in qdev_realize_and_unref (dev=0x555556892a90, bus=<optimized out>, errp=<optimized out>) at ../hw/core/qdev.c:396
#8  0x000055555596d5f0 in pci_create_simple_multifunction (bus=0x555556e09800, devfn=<optimized out>, multifunction=<optimized out>, name=<optimized out>) at ../hw/pci/ pci.c:2190
#9  0x000055555589012f in i440fx_init (host_type=host_type@entry=0x555555d80e54 "i440FX-pcihost", pci_type=pci_type@entry=0x555555dbe5ad "i440FX", pi440fx_state=pi440fx _state@entry=0x7fffffffd540, address_space_mem=address_space_mem@entry=0x5555566f6400, address_space_io=address_space_io@entry=0x55555668f800, ram_size=8589934592, belo w_4g_mem_size=3221225472, above_4g_mem_size=5368709120, pci_address_space=0x55555681a700, ram_memory=0x555556602c60) at ../hw/pci-host/i440fx.c:266
#10 0x0000555555a65b2d in pc_init1 (machine=0x5555566c0000, pci_type=0x555555dbe5ad "i440FX", host_type=0x555555d80e54 "i440FX-pcihost") at ../hw/i386/pc_piix.c:202
#11 0x00005555558ff1ae in machine_run_board_init (machine=machine@entry=0x5555566c0000) at ../hw/core/machine.c:1232
#12 0x0000555555bae1de in qemu_init_board () at ../softmmu/vl.c:2514
#13 qmp_x_exit_preconfig (errp=<optimized out>) at ../softmmu/vl.c:2588
#14 0x0000555555bb1e32 in qemu_init (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at ../softmmu/vl.c:3612
#15 0x000055555582b4bd in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at ../softmmu/main.c:49
*/

每一个地址空间都存在:

struct PCIDevice {
    DeviceState qdev;
    bool partially_hotplugged;

    /* PCI config space */
    uint8_t *config;

    PCIConfigReadFunc *config_read;
    PCIConfigWriteFunc *config_write;
#0  pci_default_read_config (d=0x5555568923a0, address=0, len=2) at ../hw/pci/pci.c:1419
#1  0x00005555558780f8 in pci_host_config_read_common (pci_dev=0x5555568923a0, addr=0, limit=<optimized out>, limit@entry=256, len=2) at ../hw/pci/pci_host.c:104
#2  0x00005555558782ee in pci_data_read (s=<optimized out>, addr=<optimized out>, len=<optimized out>) at ../hw/pci/pci_host.c:133
#3  0x0000555555878323 in pci_host_data_read (opaque=<optimized out>, addr=<optimized out>, len=<optimized out>) at ../hw/pci/pci_host.c:178
#4  0x0000555555b8da11 in memory_region_read_accessor (mr=mr@entry=0x5555569aa1a0, addr=0, value=value@entry=0x7fffd9ff9130, size=size@entry=2, shift=0, mask=mask@entry
=65535, attrs=...) at ../softmmu/memory.c:442
#5  0x0000555555b8c10e in access_with_adjusted_size (addr=addr@entry=0, value=value@entry=0x7fffd9ff9130, size=size@entry=2, access_size_min=<optimized out>, access_siz
e_max=<optimized out>, access_fn=0x555555b8d9d0 <memory_region_read_accessor>, mr=0x5555569aa1a0, attrs=...) at ../softmmu/memory.c:552
#6  0x0000555555b8fb61 in memory_region_dispatch_read1 (attrs=..., size=<optimized out>, pval=0x7fffd9ff9130, addr=0, mr=0x5555569aa1a0) at ../softmmu/memory.c:1422
#7  memory_region_dispatch_read (mr=mr@entry=0x5555569aa1a0, addr=0, pval=pval@entry=0x7fffd9ff9130, op=MO_16, attrs=attrs@entry=...) at ../softmmu/memory.c:1450
#8  0x0000555555bd9ba9 in flatview_read_continue (fv=fv@entry=0x555556b98730, addr=addr@entry=3324, attrs=..., ptr=ptr@entry=0x7fffeaf82000, len=len@entry=2, addr1=<opt
imized out>, l=<optimized out>, mr=0x5555569aa1a0) at /home/maritns3/core/kvmqemu/include/qemu/host-utils.h:164
#9  0x0000555555bd9d63 in flatview_read (fv=0x555556b98730, addr=addr@entry=3324, attrs=attrs@entry=..., buf=buf@entry=0x7fffeaf82000, len=len@entry=2) at ../softmmu/ph
ysmem.c:2849
#10 0x0000555555bd9eb6 in address_space_read_full (as=0x5555564e0ba0 <address_space_io>, addr=3324, attrs=..., buf=0x7fffeaf82000, len=2) at ../softmmu/physmem.c:2862
#11 0x0000555555bda035 in address_space_rw (as=<optimized out>, addr=addr@entry=3324, attrs=..., attrs@entry=..., buf=<optimized out>, len=len@entry=2, is_write=is_writ
e@entry=false) at ../softmmu/physmem.c:2890
#12 0x0000555555bb8869 in kvm_handle_io (count=1, size=2, direction=<optimized out>, data=<optimized out>, attrs=..., port=3324) at ../accel/kvm/kvm-all.c:2256
#13 kvm_cpu_exec (cpu=cpu@entry=0x555556a9fca0) at ../accel/kvm/kvm-all.c:2507
#14 0x0000555555b771a5 in kvm_vcpu_thread_fn (arg=arg@entry=0x555556a9fca0) at ../accel/kvm/kvm-accel-ops.c:49
#15 0x0000555555d248b3 in qemu_thread_start (args=<optimized out>) at ../util/qemu-thread-posix.c:521
#16 0x00007ffff6096609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#17 0x00007ffff5fbb293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
*/

到底在 pci 配置空间中写入了什么东西

e1000 的三个 bar 空间:

PCI: map device bdf=00:03.0  bar 1, addr 0000c000, size 00000040 [io]
PCI: map device bdf=00:03.0  bar 6, addr feb80000, size 00040000 [mem]
PCI: map device bdf=00:03.0  bar 0, addr febc0000, size 00020000 [mem]

pci 设备的 bar 的起始位置映射的配置是 bios 中的代码扫描完成的

martins3:e1000_write_config 10 ffffffff 4
martins3:e1000_write_config 10 0 4
martins3:e1000_write_config 14 ffffffff 4
martins3:e1000_write_config 14 1 4
martins3:e1000_write_config 18 ffffffff 4
martins3:e1000_write_config 18 0 4
martins3:e1000_write_config 1c ffffffff 4
martins3:e1000_write_config 1c 0 4
martins3:e1000_write_config 20 ffffffff 4
martins3:e1000_write_config 20 0 4
martins3:e1000_write_config 24 ffffffff 4
martins3:e1000_write_config 24 0 4
martins3:e1000_write_config 30 fffff800 4
martins3:e1000_write_config 30 0 4
martins3:e1000_write_config 14 c000 4
martins3:e1000_write_config 30 feb80000 4
martins3:e1000_write_config 10 febc0000 4
martins3:e1000_write_config 3c b 1
martins3:e1000_write_config 4 103 2
martins3:e1000_write_config 30 fffffffe 4
martins3:e1000_write_config 30 feb80001 4
martins3:e1000_write_config 30 feb80000 4
// 下面是内核日志

martins3:e1000_write_config 4 503 2
martins3:e1000_write_config 4 103 2
martins3:e1000_write_config 4 100 2
martins3:e1000_write_config 10 ffffffff 4
martins3:e1000_write_config 10 febc0000 4
martins3:e1000_write_config 4 103 2
martins3:e1000_write_config 4 100 2
martins3:e1000_write_config 14 ffffffff 4
martins3:e1000_write_config 14 c001 4
martins3:e1000_write_config 4 103 2
martins3:e1000_write_config 4 100 2
martins3:e1000_write_config 18 ffffffff 4
martins3:e1000_write_config 18 0 4
martins3:e1000_write_config 4 103 2
martins3:e1000_write_config 4 100 2
martins3:e1000_write_config 1c ffffffff 4
martins3:e1000_write_config 1c 0 4
martins3:e1000_write_config 4 103 2
martins3:e1000_write_config 4 100 2
martins3:e1000_write_config 20 ffffffff 4
martins3:e1000_write_config 20 0 4
martins3:e1000_write_config 4 103 2
martins3:e1000_write_config 4 100 2
martins3:e1000_write_config 24 ffffffff 4
martins3:e1000_write_config 24 0 4
martins3:e1000_write_config 4 103 2
martins3:e1000_write_config 4 100 2
martins3:e1000_write_config 30 fffff800 4
martins3:e1000_write_config 30 feb80000 4
martins3:e1000_write_config 4 103 2
martins3:e1000_write_config 4 107 2
martins3:e1000_write_config d 40 1

真相就是在这里:

#0  pci_write_config_word (dev=0xffff8881002d9800, where=4, val=256) at drivers/pci/pci.h:383
#1  0xffffffff8142f3f5 in __pci_read_base (dev=dev@entry=0xffff8881002d9800, type=type@entry=pci_bar_unknown, res=res@entry=0xffff8881002d9c50, pos=pos@entry=28) at dri
vers/pci/probe.c:190
#2  0xffffffff8142f4b2 in pci_read_bases (dev=0xffff8881002d9800, howmany=6, rom=48) at drivers/pci/probe.c:335
#3  0xffffffff8142fa17 in pci_setup_device (dev=dev@entry=0xffff8881002d9800) at drivers/pci/probe.c:1848
#4  0xffffffff8143060d in pci_scan_device (devfn=8, bus=0xffff888100259c00) at drivers/pci/probe.c:2355
#5  pci_scan_single_device (devfn=8, bus=0xffff888100259c00) at drivers/pci/probe.c:2512
#6  pci_scan_single_device (bus=0xffff888100259c00, devfn=8) at drivers/pci/probe.c:2502
#7  0xffffffff8143068d in pci_scan_slot (bus=bus@entry=0xffff888100259c00, devfn=devfn@entry=8) at drivers/pci/probe.c:2591
#8  0xffffffff814317b0 in pci_scan_child_bus_extend (bus=bus@entry=0xffff888100259c00, available_buses=available_buses@entry=0) at drivers/pci/probe.c:2808
#9  0xffffffff81431997 in pci_scan_child_bus (bus=bus@entry=0xffff888100259c00) at drivers/pci/probe.c:2938
#10 0xffffffff81471601 in acpi_pci_root_create (root=root@entry=0xffff888100222a00, ops=ops@entry=0xffffffff826411c0 <acpi_pci_root_ops>, info=info@entry=0xffff88810022
ca20, sysdata=sysdata@entry=0xffff88810022ca58) at drivers/acpi/pci_root.c:925
#11 0xffffffff81b23a9d in pci_acpi_scan_root (root=root@entry=0xffff888100222a00) at arch/x86/pci/acpi.c:368
#12 0xffffffff81b4142c in acpi_pci_root_add (device=0xffff888100217000, not_used=<optimized out>) at drivers/acpi/pci_root.c:597
#13 0xffffffff8146a1e3 in acpi_scan_attach_handler (device=0xffff888100217000) at drivers/acpi/scan.c:2038
#14 acpi_bus_attach (device=device@entry=0xffff888100217000, first_pass=first_pass@entry=true) at drivers/acpi/scan.c:2086
#15 0xffffffff8146a130 in acpi_bus_attach (device=device@entry=0xffff888100216800, first_pass=first_pass@entry=true) at drivers/acpi/scan.c:2107
#16 0xffffffff8146a130 in acpi_bus_attach (device=0xffff888100216000, first_pass=first_pass@entry=true) at drivers/acpi/scan.c:2107
#17 0xffffffff8146bf3f in acpi_bus_scan (handle=handle@entry=0xffffffffffffffff) at drivers/acpi/scan.c:2167
#18 0xffffffff82b6f9a2 in acpi_scan_init () at drivers/acpi/scan.c:2342
#19 0xffffffff82b6f6d3 in acpi_init () at drivers/acpi/bus.c:1341
#20 0xffffffff81000def in do_one_initcall (fn=0xffffffff82b6f2e1 <acpi_init>) at init/main.c:1249
#21 0xffffffff82b3d26b in do_initcall_level (command_line=0xffff888100123400 "root", level=4) at ./include/linux/compiler.h:234
#22 do_initcalls () at init/main.c:1338
#23 do_basic_setup () at init/main.c:1358
#24 kernel_init_freeable () at init/main.c:1560
#25 0xffffffff81b7c249 in kernel_init (unused=<optimized out>) at init/main.c:1447
#26 0xffffffff810019b2 in ret_from_fork () at arch/x86/entry/entry_64.S:294
#27 0x0000000000000000 in ?? ()
e of these components can be found at github.com/loongson.However, it is not so easy to find proper combination of all components that can work. I forked them, make necessary patches and tag the source versions for binaries here to help you to reproduce and further customizations.

从 pci_read_bases 中可以看的超级清晰,为什么在 Linux kernel 中间依旧存在配置 bar 空间的行为.

cat /proc/ioports

0000-0cf7 : PCI Bus 0000:00
  0000-001f : dma1
  0020-0021 : pic1
  0040-0043 : timer0
  0050-0053 : timer1
  0060-0060 : keyboard
  0064-0064 : keyboard
  0070-0077 : rtc0
  0080-008f : dma page reg
  00a0-00a1 : pic2
  00c0-00df : dma2
  00f0-00ff : fpu
  0170-0177 : 0000:00:01.1
    0170-0177 : ata_piix
  01f0-01f7 : 0000:00:01.1
    01f0-01f7 : ata_piix
  0376-0376 : 0000:00:01.1
    0376-0376 : ata_piix
  03c0-03df : vga+
  03f2-03f2 : floppy
  03f4-03f5 : floppy
  03f6-03f6 : 0000:00:01.1
    03f6-03f6 : ata_piix
  03f7-03f7 : floppy
  03f8-03ff : serial
  0510-051b : QEMU0002:00
  0600-063f : 0000:00:01.3
    0600-0603 : ACPI PM1a_EVT_BLK
    0604-0605 : ACPI PM1a_CNT_BLK
    0608-060b : ACPI PM_TMR
  0700-070f : 0000:00:01.3
0cf8-0cff : PCI conf1
0d00-ffff : PCI Bus 0000:00
  afe0-afe3 : ACPI GPE0_BLK
  c000-c03f : 0000:00:03.0
    c000-c03f : e1000
  c040-c05f : 0000:00:05.0
  c060-c06f : 0000:00:01.1
    c060-c06f : ata_piix

尝试解释下未解之谜

为什么中 int 10 可以调用 bios 的代码: lab/bootloader/run.sh

我猜测其实应该很简单,应该是类似 int 80 进入系统调用一样, 提前设置一下 idt 的入口

其调用的函数中,实现 vgasrc/vgabios.c

但是现在 idt 的入口设置没找到:

seabios debug

https://www.seabios.org/Debugging

还是直接 print 把

现在 seabio 的构建会有一堆警告

commit 9029a010ec41 (“kconfig: fix the check-lxdialog.sh to work with gcc 14+”) 对应的 commit 为:

/nix/store/vk4mlknqk9yjbqa68a7rvpfxfdw3rad7-binutils-2.43.1/bin/ld: warning: out/code16.o: requires executable stack
(because the .note.GNU-stack section is executable)
/nix/store/vk4mlknqk9yjbqa68a7rvpfxfdw3rad7-binutils-2.43.1/bin/ld: warning: out/rom16.o has a LOAD segment with RWX
permissions
  Stripping out/rom16.noexec.o
  Linking out/rom.o
/nix/store/vk4mlknqk9yjbqa68a7rvpfxfdw3rad7-binutils-2.43.1/bin/ld: warning: out/rom32seg.noexec.o: missing .note.GNU
-stack section implies executable stack
/nix/store/vk4mlknqk9yjbqa68a7rvpfxfdw3rad7-binutils-2.43.1/bin/ld: NOTE: This behaviour is deprecated and will be re
moved in a future version of the linker
/nix/store/vk4mlknqk9yjbqa68a7rvpfxfdw3rad7-binutils-2.43.1/bin/ld: warning: out/rom.o has a LOAD segment with RWX pe
rmissions
  Prepping out/bios.bin.prep
Total size: 180288  Fixed: 89920  Free: 81856 (used 68.8% of 256KiB rom)

pmm

src/pmm.c

看看这里触发的原因是什么?

Running option rom at c000:0003
handle_smi cmd=b5 smbase=0x000a0000
A
pmm call arg1=1
handle_smi cmd=b5 smbase=0x000a0000
B
handle_smi cmd=b5 smbase=0x000a0000

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。

  1. https://www.seabios.org/Execution_and_code_flow  2

  2. reloc_preinit 将 maininit 执行的代码再次进行一次拷贝,但是不知道为什么如此操作 

  3. https://en.wikipedia.org/wiki/System_Management_Mode 

  4. https://docs.microsoft.com/en-us/windows-hardware/test/hlk/testref/trusted-execution-environment-acpi-profile