UEFI and ATA PIO mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Je06
Posts: 11
Joined: Mon Dec 09, 2019 10:37 pm

UEFI and ATA PIO mode

Post by Je06 »

Recently, I've switched to UEFI. I'm trying to use ATA PIO to load my kernel from the disk. I do not wish to store any part of the kernel in the EFI partition. Whenever I try to issue a command, it always responds with the error: 0x4 (Command aborted). I'm using 64 UEFI, compiled with gcc targeted for windows. I used the EFI loaded image protocol to get the drive information.

Code: Select all

    #define     ERROR           1
    #define     LBA_LOW         3
    #define     LBA_MID         4
    #define     LBA_HIGH        5
    #define     DRIVE           6
    #define     STATUS          7
    #define     COMMAND         7

    UINT16 bus;

    if (info.Drive.ATAPI.primarySecondary == ATAPI_PRIMARY) {
        bus = 0x1f0;
    } else {
        bus = 0x170;
    }

    UINT8 selector;

    if (info.Drive.ATAPI.masterSlave == ATAPI_MASTER) {
        selector = 0xa0;
    } else {
        selector = 0xb0;
    }

    // Identify the drive
    outb(bus+DRIVE, selector);
    outb(bus+LBA_LOW, 0);
    outb(bus+LBA_MID, 0);
    outb(bus+LBA_HIGH, 0);
    outb(bus+COMMAND, 0xec);

    uint8_t status = inb(bus+STATUS);
    if (status == 0) {
        return 0;
    }

    while (status & 0x80) {
        status = inb(bus+STATUS);
    }

    while (!(status & 7) || !(status & 1)) {
        status = inb(bus+STATUS);
    }

    if (status & 1) {
        printhex(status, 0);
        print(" ");
        status = inb(bus+ERROR);
        printhex(status, 1);
        return 0;
    }
Octocontrabass
Member
Member
Posts: 5578
Joined: Mon Mar 25, 2013 7:01 pm

Re: UEFI and ATA PIO mode

Post by Octocontrabass »

You call ExitBootServices() before this, right?
Je06 wrote:I do not wish to store any part of the kernel in the EFI partition.
This means you will need to update your bootloader for each new storage device you support. Most hardware uses AHCI or NVMe for storage nowadays.
Je06 wrote:Whenever I try to issue a command, it always responds with the error: 0x4 (Command aborted).
Out of curiosity, what are the contents of the other registers after issuing the command? If it really is an ATAPI device like your code says, then it's supposed to return command aborted for the commands you're trying to use.
Je06 wrote:I'm using 64 UEFI, compiled with clang.
Je06 wrote:I'm using 64 UEFI, compiled with gcc targeted for windows.
Either of these should be fine, as long as you meet the ABI requirements of the UEFI boot services. (I believe GCC targeted for bare metal can also be convinced to work, though I haven't tried it myself yet.)
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: UEFI and ATA PIO mode

Post by BenLunt »

I would like to comment that UEFI and directly accessing the disk hardware should be completely separate of each other. One should not rely upon the other. This is the whole point of the firmware, whether it be the Legacy BIOS or the new UEFI.

If you are trying to access the disk drive using the controller, you *must* be out of the UEFI's way, meaning--as Octocontrabass stated--you have executed the ExitBootServices() function. Once you have called this function, it makes absolutely no difference if you booted UEFI or Legacy BIOS, at least as far as direct disk controller access is concerned.

The point of the firmware, especially UEFI, is to hide the underlining hardware allowing you to read from the disk no matter the hardware's type. Use the UEFI to load your system files, kernel, etc. Once you have, exit the UEFI and jump to the kernel. At this point, the kernel can assume that all drivers necessary to continue booting have been loaded.

Reading your post, you left me under the impression that you are trying to access the disk hardware while still under the UEFI blanket. Is this true? If so, use the UEFI, that is what it is there for. :-)

Ben
- http://www.fysnet.net/osdesign_book_series.htm
User avatar
zaval
Member
Member
Posts: 657
Joined: Fri Feb 17, 2017 4:01 pm
Location: Ukraine, Bachmut
Contact:

Re: UEFI and ATA PIO mode

Post by zaval »

Reading your post, you left me under the impression that you are trying to access the disk hardware while still under the UEFI blanket. Is this true? If so, use the UEFI, that is what it is there for. :-)
it looks like for many people, compiling UEFI by themselves (which is absolutely pointless) is easier, than reading the specification (which is absolutely needed when one goes - "I've switched to UEFI"). and where it's pretty clearly described how one is supposed to use it.

for the OP, you don't need to program disk controller to access your storage under UEFI. if you don't want to store your OS under ESP, that's fine, it is even good, it's not supposed to be used for that - you need to only store there your OS loader. you do access the volume, containing your OS files either using already given to you file/simple file system/load file protocols*, if it's FAT formatted and thus supported by UEFI or through disk IO/block device protocols**, and then add the code for reading your volume and its FS with any FS and overall structure you want. I suppose, you didn't invent your own block device, right? :D so, UEFI already is able to read/write the block device you put your boot volume on, everything left is adding your FS reading code.

*
12.4 Simple File System Protocol
This section defines the Simple File System protocol. This protocol allows code running in the EFI boot services environment to obtain file based access to a device. EFI_SIMPLE_FILE_SYSTEM_PROTOCOL is used to open a device volume and return an EFI_FILE_PROTOCOL that provides interfaces to access files on a device volume.
12.5 EFI File Protocol
The protocol and functions described in this section support access to EFI-supported file systems.
12.1 Load File Protocol
This section defines the Load File protocol. This protocol is designed to allow code running in the boot services environment to find and load other modules of code.
**
12.7 Disk I/O Protocol
This section defines the Disk I/O protocol. This protocol is used to abstract the block accesses of the Block I/O protocol to a more general offset-length protocol. The firmware is responsible for adding this protocol to any Block I/O interface that appears in the system that does not already have a Disk I/O protocol. File systems and other disk access code utilize the Disk I/O protocol.
12.9 EFI Block I/O Protocol
This section defines the Block I/O protocol. This protocol is used to abstract mass storage devices to allow code running in the EFI boot services environment to access them without specific knowledge of the type of device or controller that manages the device. Functions are defined to read and write data at a block level from mass storage devices as well as to manage such devices in the EFI boot services environment.
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).
Je06
Posts: 11
Joined: Mon Dec 09, 2019 10:37 pm

Re: UEFI and ATA PIO mode

Post by Je06 »

Thanks to everyone who posted! I have called ExitBootServices(), and I have referred to the UEFI specification. For some reason, I completely missed the part on Disk and Block I/O Protocols. #-o
Post Reply