Hi,
out of curiosity, I'd like to reverse engineer - or at least try to understand a bit more of - the (old/classic/non-EFI) proprietary BIOS of my HP nc6320 laptop (BIOS dated from 2008). I'm fairly new to BIOS code and so far it's been a series of great discoveries and interesting reading for me :-)
I unsoldered the 8Mbit SPI flash from a damaged/broken laptop of the same type and dumped its contents, and now analyse it with radare2. At a very early stage (see below) I have some difficulties to understand what is done: the code accesses IO locations (via in/out instructions) that belong to the DMA controller but are marked "Reserved" in the ICH7 documentation [0, page 385].
Is there a way to find out what these addresses are used for?
http://www.coreboot.org/HP_COMPAQ_NC6320 - Processor: Intel Core 2 Duo T7200 - Northbridge: 945GM - Southbridge: Intel 82801GBM (ICH7-M)
Concerning "reserved" addresses, [0, page 255] says: "DMI (Direct Media Interface) cycles that go to target ranges that are marked "Reserved" will not be decoded by the ICH7, and will be passed to PCI"
In particular I'm interested in 0x80, 0x84/0x85, 0x8c/0x8d. Since dx contains CPU type/family information, does the code tell other components some CPU specifics?
f000:fff0 e9f591 jmp loc.000f91e8 | v f000:91e8 fa cli f000:91e9 e784 out 0x84, ax f000:91eb 8bc2 mov ax, dx f000:91ed e78c out 0x8c, ax f000:91ef b0b0 mov al, 0xb0 f000:91f1 e680 out 0x80, al f000:91f3 ba4e05 mov dx, 0x54e f000:91f6 ee out dx, al f000:91f7 e58c in ax, 0x8c f000:91f9 8bd0 mov dx, ax f000:91fb e584 in ax, 0x84 f000:91fd bd0392 mov bp, 0x9203 f000:9200 e9b001 jmp loc.000f93b3 ;[1] | +-> ; this function basically follows f000:93b3 662e0f011ed. o32 lidt [cs:0x91dc] f000:93ba 662e0f0116d. o32 lgdt [cs:0x89d0] ; set PE bit (Protection Enable) in cr0: switch to protected mode ... ; init the segment registers ; clear PE bit in cr0: switch to real-address mode ; clear PG bit in cr0: disable paging ... ; init the segment registers to another value f000:93f6 ffe5 jmp bp | <-+ f000:9203 bd0992 mov bp, 0x9209 f000:9206 e92bf4 jmp fcn.000f8634 ;[2] | +-> ; some other stuff happening ; return via jmp bp | <-+ f000:9209 e784 out 0x84, ax f000:920b 8bc2 mov ax, dx f000:920d e78c out 0x8c, ax f000:920f b0b1 mov al, 0xb1 f000:9211 e680 out 0x80, al f000:9213 ba4e05 mov dx, 0x54e f000:9216 ee out dx, al f000:9217 e58c in ax, 0x8c f000:9219 8bd0 mov dx, ax f000:921b e584 in ax, 0x84 ...
Thanks for any assistance and pointers, -- panic
[0] http://www.intel.com/content/dam/doc/datasheet/i-o-controller-hub-7-datashee...
Hi panic,
0x80 is a debug io port. There are pci cards showing you one byte on a lcd display. coreboot is using 0x80 too for debug output. The interface is simple, the firmware/bios will increment the value sent to that address while it's booting. In the case your bios is hangs somewhere while booting, you can read from the card it's last byte sent to that ioport 0x80.
No idea what for the others io codes are.
best, lynxis
Please don't post disassembly of code from outside the project. Thanks.
panic wrote:
I have some difficulties to understand what is done
Welcome to x86 firmware. Some day you may even grow to appreciate that feeling.
Is there a way to find out what these addresses are used for?
You have to look for a lot of different documentation, and piece together the complete picture on your own.
Get Ralf Brown's interrupt list. It includes an IO port list with some register explanations.
Also look at operating system programming documentation. This is 386 class hardware, read books about operating system programming on the 386 and on older hardware.
Writing a 386 operating system is also a good exercise to learn about the hardware.
There are good IA-32 books from Intel. They're a couple thousand pages.
In particular I'm interested in 0x80, 0x84/0x85, 0x8c/0x8d.
From ports.lst:
----------P0080008F-------------------------- PORT 0080-008F - DMA PAGE REGISTERS (74612)
.. 0084 RW extra page register 0085 RW extra page register 008C RW extra page register 008D RW extra page register
So either something is being done with the DMA controller (seems unlikely in early boot) or these registers have a completely different meaning at that time in the platform lifecycle.
I would not expect that there is any good documentation about this.
Good luck and have fun!
//Peter
Peter Stuge:
Please don't post disassembly of code from outside the project. Thanks.
ok. noted.
In particular I'm interested in 0x80, 0x84/0x85, 0x8c/0x8d.
From ports.lst:
----------P0080008F-------------------------- PORT 0080-008F - DMA PAGE REGISTERS (74612)
.. 0084 RW extra page register 0085 RW extra page register 008C RW extra page register 008D RW extra page register
So either something is being done with the DMA controller (seems unlikely in early boot) or these registers have a completely different meaning at that time in the platform lifecycle.
An idea is that, probably, these registers serve as scratchpad copy and recover ax and dx because they are modified during the subroutines.
-- panic