Canonical Voices

Posts tagged with 'bios'

Colin Ian King

QEMU + EFI BIOS

I've been poking around with the Extensible Firmware Interface (EFI) and discovered that Tristan Gingold has kindly ported an EFI BIOS from the TianoCore project to QEMU.

The EFI tarball at the QEMU website contains an EFI BIOS image and a bootable linux image that uses the elilo boot loader. I simply grabbed the tarball, unpacked it and moved the EFI bios.bin to /usr/share/qemu/bios-efi.bin to make sure I don't get confused between BIOS filenames.

Then I booted using the EFI BIOS and EFI enabled linux disk image:

qemu qemu -bios bios-efi.bin -hda efi.disk

Here is the initial boot screen:



And here's the EFI command prompt:


So if you want to get to play with EFI, here's a great virtualized playground for one to experiment with. Kudos to TianoCore, Tristan Gingold and QEMU!


Read more
Colin Ian King

System Management Mode is Evil

System Management Mode (SMM) is an evil thing. It's a feature that was introduced on the Intel 386SL and allows an operating system to be interrupted and normal execution to be temporarily suspended to execute SMM code at a very high priviledge level. It's normally configured at boot-time by the BIOS and the OS has zero knowledge about it.

The System Management Interrupt (SMI) causes the CPU to enter system management mode, usually by:

  • The processor being configured to generate a SMI on a write to a predefined I/O address.
  • Signalling on a pre-defined pin on the CPU
  • Access to a predefined I/O port (port 0xB2 is generally used)
SMM has been used to catch chipset errors, handle system failures such as CPU overheating, perform fan control, emulate hardware, and even run rootkits(!)

SMM cannot be masked or overridden which mean an OS has no way of avoiding being interrupted by the SMI. The SMI will steal CPU cycles and modify CPU state - state is saved and restored using System Management RAM (SMRAM) and apparently the write-back caches have to be flushed to enter SMM. This can mess up real-time performance by adding in hidden latencies which the OS cannot block. CPU cycles are consumed and hence Time Stamp Counter (TSC) skewing occurs relative to the OS's view of CPU timing and generally the OS cannot account for the lost cycles. One also has to rely on the SMM code being written correctly and not interfering with the state of the OS - weird un-explicable problems may occur if the SMM code is buggy.

By monitoring the TSC one can detect if a system is has entered SMM. In face, Jon Masters had written a Linux module to do this.

Processors such as the MediaGX (from which the Geode was derived) used SMM to emulate real hardware such as VGA and the Sound Blaster audio, which is a novel solution, but means that one cannot reliably do any real-time work on this processor.

The worrying feature of SMM is that it can be exploited and used for rootkits - it's hard to detect and one cannot block it. Doing things behind an OS's back without it knowing and in a way that messes with critical timing and can lead to rootkit exploits is just plain evil in my opinion. If it was up to me, I'd ban the use of it completely.

For those who are interested at looking at an implementation of a SMM handing code, coreboot has some well written and commented code in src/cpu/x86/smm. Well worth eyeballing. Phrack has some useful documentation on SMM and generating SMI interrupts, and mjg59 has an article that shows an ACPI table that generates SMI interrupts by writing to port 0xb2.


Read more
Colin Ian King

Most of the time when I'm looking at BIOS issues I just look at the disassembled ACPI DSDT using the following runes:

$ sudo cat /proc/acpi/dsdt > dstd.dat
$ iasl -d dstd.dat

..and look at the disassembly in dstd.dsl

Some BIOS bugs need a little more examination, and that's where I use acpidump + acpixtract. The simplest way to dump all the ACPI tables is as follows:

$ sudo acpidump > acpi.dat
$ acpixtract -a acpi.dat
Acpi table [DSDT] - 24564 bytes written to DSDT.dat
Acpi table [FACS] - 64 bytes written to FACS.dat
Acpi table [FACP] - 244 bytes written to FACP1.dat
Acpi table [APIC] - 104 bytes written to APIC1.dat
Acpi table [HPET] - 56 bytes written to HPET.dat
Acpi table [MCFG] - 60 bytes written to MCFG.dat
Acpi table [TCPA] - 50 bytes written to TCPA.dat
Acpi table [TMOR] - 38 bytes written to TMOR.dat
Acpi table [SLIC] - 374 bytes written to SLIC.dat
Acpi table [APIC] - 104 bytes written to APIC2.dat
Acpi table [BOOT] - 40 bytes written to BOOT.dat
Acpi table [SSDT] - 685 bytes written to SSDT1.dat
Acpi table [SSDT] - 163 bytes written to SSDT2.dat
Acpi table [SSDT] - 607 bytes written to SSDT3.dat
Acpi table [SSDT] - 166 bytes written to SSDT4.dat
Acpi table [SSDT] - 1254 bytes written to SSDT5.dat
Acpi table [XSDT] - 148 bytes written to XSDT.dat
Acpi table [FACP] - 116 bytes written to FACP2.dat
Acpi table [RSDT] - 88 bytes written to RSDT.dat
Acpi table [RSDP] - 36 bytes written to RSDP.dat

..this dumps out all the tables into files.

One can the disassemble the required file using iasl, e.g.:

$ iasl -d APIC1.dat

or decode the table using madt:

$ madt < ACPI1.dsl
ACPI: APIC (v001 INTEL CRESTLNE 0x06040000 LOHR 0x0000005a) @ 0x(nil)
ACPI: LAPIC (acpi_id[0x00] lapic_id[0x00] enabled)
ACPI: LAPIC (acpi_id[0x01] lapic_id[0x01] enabled)
ACPI: IOAPIC (id[0x01] address[0xfec00000] global_irq_base[0x0])
ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
ACPI: LAPIC_NMI (acpi_id[0x00] high edge lint[0x1])
ACPI: LAPIC_NMI (acpi_id[0x01] high edge lint[0x1])
Length 104 OK
Checksum OK

Or to just get one particular table, I use:

$ sudo acpidump -t SSDT > SSDT.dat
$ acpixtract -a SSDT.dat
$ iasl -d SSDT.dat
Intel ACPI Component Architecture
AML Disassembler version 20090521 [Jun 30 2009]
Copyright (C) 2000 - 2009 Intel Corporation
Supports ACPI Specification Revision 3.0a

Loading Acpi table from file SSDT.dat
Acpi table [SSDT] successfully installed and loaded
Pass 1 parse of [SSDT]
Pass 2 parse of [SSDT]
Parsing Deferred Opcodes (Methods/Buffers/Packages/Regions)
.........
Parsing completed
Disassembly completed, written to "SSDT.dsl"

Armed with a copy of the ACPI spec, one can then start digging into why there are weird Linux/BIOS interactions occurring.


Read more