0

IMPORTANT: this code will render media unusable without formatting or recovery. Use unused, empty, or unneeded media.

It should be straightforward to replicate BIOS interrupt functions' behavior but the information about it online is lackluster on the real life use scenarios. So I wrote code to read 2.5" hdd drive identification info, which is a function of int 13h. I get a hang at the stage of checking for the DRQ (data ready for query?) bit of the 0x1f7 status register. When I comment out the check-DRQ loop the code proceeds but the data is all 0s, possibly because it was not read. I've tried varying slave and master bit, and the primary/secondary bus... The secondary bus goes through the DRQ check but the data seems to be all 1s. Importantly, int 13h on the same drive and the same machine works fine. Does anyone know if there's a way to: a) know ide location (primary/secondary, master/slave) of the hdd that is booting, and then b) test it's there without reading from it, and c) figure out how to get the DRQ bit to green? Will error register be meaningful before DRQ ones out?

Interestingly, BIOS shows me 3 HDDs aside from USB, DVD, and LAN entries, but I only have two slots for hard drives. And I can never plug-in my HDD so that it's HDD1. Bizarre. Could this be related?

Here's my bootable code to read from ATA HDD primary master using control registers and to print several bytes of it on screen as binary numbers:

[bits 16]
[org 0x7c00]
xor ax, ax
cli
mov dx, 0x1f7
m1:
in al, dx
test al, 010000000b
jnz m1
mov dx, 0x1f6
mov al, 0xE0       ; LBA mode - not needed for this?
out dx,al
mov dx, 0x1f7
m2:
in al, dx
test al, 010000000b     ; wait for BSY to be 0
jnz m2
test al, 001000000b     ; wait for DRDY to be 1
jz m2
mov dx, 0x1f7
mov al, 0xEC          ; identify drive command
out dx, al
mov dx, 0x1f7
m3:
in al, dx
test al, 010000000b
jnz m3
mov dx, 0x1f7
m4:
in al, dx
test al, 000001000b    ; this test for DRQ never turns 1
jz m4
mov ax, 0
mov es, ax
mov di, 0x7e00       ;save the identification to 0x7e00
mov dx, 0x1f0
mov cx, 256
rep insw
mov ax, 0xb800     ; display in table of binary bytes
mov es, ax
mov di, 0
mov ax, 0
mov ds, ax
mov si, 0x7e00     ;starting RAM address to read
mov cx, 0
mov dl, 20      ;how many lines to print
morelines:
mov bh, 7      ;how many bytes per line
morebytes:      
mov ah, [ds:si]
mov bl, 8       ;counter for bits of each byte to print
morebits:
shl ah, 1
mov al, 48
jnc zero
mov al, 49
zero:
mov [es:di], al
inc di
inc di
dec bl
jnz morebits
mov al, 32
mov [es:di], al
inc di
inc di
inc si
dec bh
jnz morebytes
add cx, 80*2
mov di, cx
dec dl
jnz morelines
times 510 - ($ - $$) db 0
dw 0xaa55
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
user145453
  • 137
  • 10
  • @rcgldr Has anyone disassembled their INT 0x13 BIOS code online at all? – user145453 Dec 24 '18 at 17:50
  • " And I can never plug-in my HDD so that it's HDD1". On my system, the BIOS numbers the drives, and if there was only one drive, it would be drive 0, regardless of what slot it is connected in. My BIOS allows me to look at what is plugged into what slot, which could help in this situation. I deleted my prior comments. – rcgldr Dec 25 '18 at 00:40
  • This isn't an answer, it is only a bootloader that I cooked up that attempts to get the extended disk drive info that might be useful to the question. Can you tell us what drive, master/slave value, the IOport, the control port and the IRQ that this bootloader displays an add it to your question? http://www.capp-sysware.com/misc/osdev/eddinfo/boot.asm – Michael Petch Dec 25 '18 at 23:29

2 Answers2

2

It should be straightforward to replicate BIOS interrupt functions' behavior but the information about it online is lackluster on the real life use scenarios.

No, definitely not.

For example, to recreate the (relatively horrible and broken due to historical limitations and "waste CPU time polling for IO completion when there's better things CPU can do" design idiocy) int 0x13 interface you will need code for:

  • legacy/ISA floppy controllers, floppy drives, tape drives
  • legacy/ISA "parallel ATA" controllers, ATA disk drives and ATAPI CD-ROMs
  • about 50 different legacy/ISA "parallel ATA" RAID controllers
  • 80 different legacy/ISA SCSI controllers
  • 3 different USB controllers, USB floppy drives, USB mass storage devices
  • SATA/AHCI
  • about 20 different PCI SCSI controllers
  • about 30 different PCI (SATA, SAS) RAID controllers
  • NVMe
  • a bunch of device enumeration code (e.g. to scan PCI buses and figure out which devices there are, etc)
  • everything all of the above depends on (e.g. memory management, IRQ handling, etc)

This adds up to more code than will fit in a 512 byte boot loader, which begs the question "If you can use BIOS to load the code needed to handle the device, why can't you use BIOS to load the code needed to start a kernel and normal device drivers that don't suck?".

Note that for most of these cases (e.g. all SCSI, all RAID) the BIOS just uses a ROM provided by the device manufacturer and included in their ISA/PCI card so that the BIOS itself doesn't have any code of its own for device.

Brendan
  • 35,656
  • 2
  • 39
  • 66
  • 1
    If you read his previous question the past number of days, he doesn't believe he can trust the BIOS and that Putin and Russkis have probably exploited his system. He doesn't even trust CALL since it manipulates CS:IP lol under the hood ;-) – Michael Petch Dec 26 '18 at 05:18
  • 1
    @MichaelPetch: Sounds like the OP should check out https://en.wikipedia.org/wiki/Libreboot and https://en.wikipedia.org/wiki/Coreboot, which aim to fully *replace* the BIOS with open-source firmware. Having the BIOS load your code and *then* distrusting it makes no sense, as you say. – Peter Cordes Dec 26 '18 at 05:39
  • 1
    All of this came about because he discovered a bug (that I can duplicate on an Intel BIOS as well) with Int 0x13/ah=3(and ah=43): https://stackoverflow.com/questions/53870314/bios-interrupt-replaced-with-far-call-not-working – Michael Petch Dec 26 '18 at 05:39
  • You only have 1 or 2 controllers on one machine. People should not have barriers for educating themselves. Especially about something they own and/or entrust their well-being or heart and soul to. It's not the Russkies that manufacture Intel and force a full access, closed, inaccessible MINIX operating system chip into your CPU with unfettered access to RAM, TCP/IP stack, and devices. – user145453 Dec 26 '18 at 08:12
  • @user145453: You have a few controllers on one machine (and for modern machines AHCI/SCSI, NVMe, xHCI and USB mass storage are far more likely than floppy and SCSI and RAID), but when you want an OS to work on more than one machine (especially in a "general public downloads and installs" way) it's impossible to guess which few controllers a machine will have.in advance. – Brendan Dec 27 '18 at 00:52
  • 1
    @user145453: For the security/trust issues, don't forget that chipset has various pieces of hardware (e.g. "Intel management engine"), firmware can use SMM, and lots of the devices (e.g. hard drives, etc) have microcontrollers built in. There's no sane reason for an attacker to modify "int 0x13" when they could use other options that are more effective, more powerful and harder to detect; so if you've detected a problem with "int 0x13" it's likely to be a simple bug (and not a clueless/incompetent attacker that failed to make their attack undetectable). – Brendan Dec 27 '18 at 01:06
0

You may be working with the DVD drive plugged in the SATA0 port instead of HDD. In this case, command 0xA1 (IDENTIFY PACKET DEVICE) will return the identification data.

For SATA1 - SATA3 ports, try setting bit 4 (Drive Select) of register 0x1F6, or using registers at 0x170 - 0x177 as suggested by @rcgldr.

igorinov
  • 429
  • 3
  • 6
  • I tried setting bit 4 of 0x1f6, and I tried using second channel registers 0x170, it doesn't work. – user145453 Dec 24 '18 at 18:51
  • @user145453 - Some motherboards have two more sets of registers, possibly at 0x160 and 0x1e0, but I'm not sure of the port addresses. – rcgldr Dec 24 '18 at 19:07
  • 1
    @user145453 The HDD may be plugged in a SATA port that is not mapped to the legacy I/O range. In this case, the I/O base address assigned by BIOS can be found in the SATA controller's PCI header. – igorinov Dec 24 '18 at 20:33
  • @user145453 If you are using a SATA disk, try setting up IDE compatibility mode in your BIOS. – fuz Dec 25 '18 at 12:40
  • I believe it's set up. Otherwise, the busy bit wasn't clearing when I tried the other mode. – user145453 Dec 25 '18 at 14:28
  • @igorinov But running in legacy mode (SATA IDE) why wouldn't it be mapped to the standard port? – user145453 Dec 25 '18 at 15:04
  • @user145453 Only 4 SATA ports can work with the IDE controllers mapped to legacy I/O regions. The other IDE controllers have their I/O addresses set by PCI configuration registers. – igorinov Dec 25 '18 at 18:18