📄 hvmloader.c
字号:
resource = &io_resource; bar_data &= ~PCI_BASE_ADDRESS_IO_MASK; } base = (resource->base + bar_sz - 1) & ~(bar_sz - 1); bar_data |= base; base += bar_sz; if ( (base < resource->base) || (base > resource->max) ) { printf("pci dev %02x:%x bar %02x size %08x: no space for " "resource!\n", devfn>>3, devfn&7, bar_reg, bar_sz); continue; } resource->base = base; pci_writel(devfn, bar_reg, bar_data); printf("pci dev %02x:%x bar %02x size %08x: %08x\n", devfn>>3, devfn&7, bar_reg, bar_sz, bar_data); /* Now enable the memory or I/O mapping. */ cmd = pci_readw(devfn, PCI_COMMAND); if ( (bar_reg == PCI_ROM_ADDRESS) || ((bar_data & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) ) cmd |= PCI_COMMAND_MEMORY; else cmd |= PCI_COMMAND_IO; pci_writew(devfn, PCI_COMMAND, cmd); }}static int must_load_extboot(void){ return (inb(0x404) == 1);}/* * Scan the PCI bus for the first NIC supported by etherboot, and copy * the corresponding rom data to *copy_rom_dest. Returns the length of the * selected rom, or 0 if no NIC found. */static int scan_etherboot_nic(void *copy_rom_dest){ struct option_rom_header *rom; struct option_rom_pnp_header *pnph; struct option_rom_pci_header *pcih; uint32_t devfn; uint16_t class, vendor_id, device_id; uint8_t csum; int i; for ( devfn = 0; devfn < 128; devfn++ ) { class = pci_readw(devfn, PCI_CLASS_DEVICE); vendor_id = pci_readw(devfn, PCI_VENDOR_ID); device_id = pci_readw(devfn, PCI_DEVICE_ID); if ( (vendor_id == 0xffff) && (device_id == 0xffff) ) continue; /* We're only interested in NICs. */ if ( class != 0x0200 ) continue; rom = (struct option_rom_header *)etherboot; for ( ; ; ) { /* Invalid signature means we're out of option ROMs. */ if ( strncmp((char *)rom->signature, "\x55\xaa", 2) || (rom->rom_size == 0) ) break; /* Invalid checksum means we're out of option ROMs. */ csum = 0; for ( i = 0; i < (rom->rom_size * 512); i++ ) csum += ((uint8_t *)rom)[i]; if ( csum != 0 ) break; /* Check the PCI PnP header (if any) for a match. */ pcih = (struct option_rom_pci_header *) ((char *)rom + rom->pci_header_offset); if ( (rom->pci_header_offset != 0) && !strncmp((char *)pcih->signature, "PCIR", 4) && (pcih->vendor_id == vendor_id) && (pcih->device_id == device_id) ) goto found; rom = (struct option_rom_header *) ((char *)rom + rom->rom_size * 512); } } return 0; found: /* Find the PnP expansion header (if any). */ pnph = ((rom->expansion_header_offset != 0) ? ((struct option_rom_pnp_header *) ((char *)rom + rom->expansion_header_offset)) : ((struct option_rom_pnp_header *)NULL)); while ( (pnph != NULL) && strncmp((char *)pnph->signature, "$PnP", 4) ) pnph = ((pnph->next_header_offset != 0) ? ((struct option_rom_pnp_header *) ((char *)rom + pnph->next_header_offset)) : ((struct option_rom_pnp_header *)NULL)); printf("Loading PXE ROM ...\n"); if ( (pnph != NULL) && (pnph->manufacturer_name_offset != 0) ) printf(" - Manufacturer: %s\n", (char *)rom + pnph->manufacturer_name_offset); if ( (pnph != NULL) && (pnph->product_name_offset != 0) ) printf(" - Product name: %s\n", (char *)rom + pnph->product_name_offset); memcpy(copy_rom_dest, rom, rom->rom_size * 512); return rom->rom_size * 512;}/* Replace possibly erroneous memory-size CMOS fields with correct values. */static void cmos_write_memory_size(void){ struct e820entry *map = HVM_E820; int i, nr = *HVM_E820_NR; uint32_t base_mem = 640, ext_mem = 0, alt_mem = 0; for ( i = 0; i < nr; i++ ) if ( (map[i].addr >= 0x100000) && (map[i].type == E820_RAM) ) break; if ( i != nr ) { alt_mem = ext_mem = map[i].addr + map[i].size; ext_mem = (ext_mem > 0x0100000) ? (ext_mem - 0x0100000) >> 10 : 0; if ( ext_mem > 0xffff ) ext_mem = 0xffff; alt_mem = (alt_mem > 0x1000000) ? (alt_mem - 0x1000000) >> 16 : 0; } /* All BIOSes: conventional memory (CMOS *always* reports 640kB). */ cmos_outb(0x15, (uint8_t)(base_mem >> 0)); cmos_outb(0x16, (uint8_t)(base_mem >> 8)); /* All BIOSes: extended memory (1kB chunks above 1MB). */ cmos_outb(0x17, (uint8_t)( ext_mem >> 0)); cmos_outb(0x18, (uint8_t)( ext_mem >> 8)); cmos_outb(0x30, (uint8_t)( ext_mem >> 0)); cmos_outb(0x31, (uint8_t)( ext_mem >> 8)); /* Some BIOSes: alternative extended memory (64kB chunks above 16MB). */ cmos_outb(0x34, (uint8_t)( alt_mem >> 0)); cmos_outb(0x35, (uint8_t)( alt_mem >> 8));}static void init_xen_platform_io_base(void){ struct bios_info *bios_info = (struct bios_info *)ACPI_PHYSICAL_ADDRESS; uint32_t devfn, bar_data; uint16_t vendor_id, device_id; for ( devfn = 0; devfn < 128; devfn++ ) { vendor_id = pci_readw(devfn, PCI_VENDOR_ID); device_id = pci_readw(devfn, PCI_DEVICE_ID); if ( (vendor_id != 0x5853) || (device_id != 0x0001) ) continue; bar_data = pci_readl(devfn, PCI_BASE_ADDRESS_0); bios_info->xen_pfiob = bar_data & PCI_BASE_ADDRESS_IO_MASK; }}int main(void){ int vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz; int extboot_sz = 0; printf("HVM Loader\n"); init_hypercalls(); printf("CPU speed is %u MHz\n", get_cpu_mhz()); smp_initialise(); printf("Writing SMBIOS tables ...\n"); smbios_sz = hvm_write_smbios_tables(); printf("Loading ROMBIOS ...\n"); rombios_sz = sizeof(rombios); if ( rombios_sz > 0x10000 ) rombios_sz = 0x10000; memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, rombios_sz); highbios_setup(); apic_setup(); pci_setup(); if ( (get_vcpu_nr() > 1) || get_apic_mode() ) create_mp_tables(); switch ( virtual_vga ) { case VGA_cirrus: printf("Loading Cirrus VGABIOS ...\n"); memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, vgabios_cirrusvga, sizeof(vgabios_cirrusvga)); vgabios_sz = sizeof(vgabios_cirrusvga); break; case VGA_std: printf("Loading Standard VGABIOS ...\n"); memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, vgabios_stdvga, sizeof(vgabios_stdvga)); vgabios_sz = sizeof(vgabios_stdvga); break; default: printf("No emulated VGA adaptor ...\n"); break; } etherboot_sz = scan_etherboot_nic((void*)ETHERBOOT_PHYSICAL_ADDRESS); if ( must_load_extboot() ) { printf("Loading EXTBOOT ...\n"); memcpy((void *)EXTBOOT_PHYSICAL_ADDRESS, extboot, sizeof(extboot)); extboot_sz = sizeof(extboot); } if ( get_acpi_enabled() ) { printf("Loading ACPI ...\n"); acpi_build_tables(); } cmos_write_memory_size(); printf("BIOS map:\n"); if ( vgabios_sz ) printf(" %05x-%05x: VGA BIOS\n", VGABIOS_PHYSICAL_ADDRESS, VGABIOS_PHYSICAL_ADDRESS + vgabios_sz - 1); if ( etherboot_sz ) printf(" %05x-%05x: Etherboot ROM\n", ETHERBOOT_PHYSICAL_ADDRESS, ETHERBOOT_PHYSICAL_ADDRESS + etherboot_sz - 1); if ( extboot_sz ) printf(" %05x-%05x: Extboot ROM\n", EXTBOOT_PHYSICAL_ADDRESS, EXTBOOT_PHYSICAL_ADDRESS + extboot_sz - 1); if ( smbios_sz ) printf(" %05x-%05x: SMBIOS tables\n", SMBIOS_PHYSICAL_ADDRESS, SMBIOS_PHYSICAL_ADDRESS + smbios_sz - 1); if ( rombios_sz ) printf(" %05x-%05x: Main BIOS\n", ROMBIOS_PHYSICAL_ADDRESS, ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1); init_xen_platform_io_base(); printf("Invoking ROMBIOS ...\n"); return 0;}/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -