Page 2 of 8

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Fri Mar 24, 2017 1:03 pm
by MollenOS
If you don't have the motivation or interest to write your own kernel and drivers, I don't see how you would ever succeed. Writing an OS or just a simple driver requires immense knowledge of both software and hardware, and I'm saying this again, there is no shortcut. You don't have to read an entire specification, you do like normal people would and find the parts that are relevant, 60-80% of an specification can be directly ignored as it's primarily technical information/for hardware designers.

If you seriously don't have the will, or the motivation do finish what you've started, then stop now. OS development is not for you. Find something else to do, use windows and write an application in C#. You have other options.

I'll say this the last time, you have to start at the bottom like everyone else. Driver development is OS-specific, so no such library exists. Every driver is tailored to the OS, and while it's possible to standardize an implementation, you still have to support the same function-set as the driver uses.

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Fri Mar 24, 2017 1:16 pm
by iansjack
If it were possible I would have avoided working on such a low level, but frankly I wasn't able to and therefore I'm simply trying to make it as easy as possible so that I can get to programming the higher level parts of an OS as soon as possible.
It looks like the basic problem here is that you don't actually understand what an operating system is and what it does. I'd stick with your original plan of writing some sort of user application on top of the Linux kernel; that way you get all the hardware support that you need.

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Fri Mar 24, 2017 1:39 pm
by SpyderTL
natiiix wrote:Well, that explains a lot for sure. Thanks for that, I totally haven't noticed there was a coherence between the text and the bit table.
My pleasure.

A lot of people on this site get quickly frustrated when people show up and start asking simple questions instead of finding the answer on their own. It doesn't bother me near as much. I like to give back to the community where possible. But maybe one day after I've answered the "How do I communicate with the PCI bus?" or "How do I write a video driver?" or "How do I get my USB keyboard to work?" type questions for long enough, I'll start getting frustrated as well.

Maybe even you will stick around long enough to get tired of all of the "I know the wiki says that I should set a flag, but how do I 'set a flag'?" type questions. :)

Good luck, though. Let us know if there is anything else we can help with. (Just try to be a little more specific when asking questions.)

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Fri Mar 24, 2017 5:09 pm
by natiiix
MollenOS wrote:If you don't have the motivation or interest to write your own kernel and drivers, I don't see how you would ever succeed. Writing an OS or just a simple driver requires immense knowledge of both software and hardware, and I'm saying this again, there is no shortcut. You don't have to read an entire specification, you do like normal people would and find the parts that are relevant, 60-80% of an specification can be directly ignored as it's primarily technical information/for hardware designers.

If you seriously don't have the will, or the motivation do finish what you've started, then stop now. OS development is not for you. Find something else to do, use windows and write an application in C#. You have other options.

I'll say this the last time, you have to start at the bottom like everyone else. Driver development is OS-specific, so no such library exists. Every driver is tailored to the OS, and while it's possible to standardize an implementation, you still have to support the same function-set as the driver uses.
I've been developing .NET applications for the past 5 years give or take and it's getting pretty boring. That's why I want to take a break and do something funny in C++. And the only thing I really wanted to make and haven't ever been able to is an OS. Basic one suffices for as long as I can keep on adding modules.

Drivers such as these aren't necessarily OS specific. You can have a library that gives you some kind of API and it can be implemented into any OS with ease, because it works directly with hardware. The AHCI driver is merely being used by the rest of the system, it doesn't need to communicate with it and therefore a simply read/write sector API is all I really need. That surely doesn't have to be OS dependent.
iansjack wrote:It looks like the basic problem here is that you don't actually understand what an operating system is and what it does. I'd stick with your original plan of writing some sort of user application on top of the Linux kernel; that way you get all the hardware support that you need.
Frankly I know very well what an OS is. I just hoped it would be easier to use parts of the Linux kernel. I need mine to be simply and fast, that would be impossible if I relied on Linux.
SpyderTL wrote:Let us know if there is anything else we can help with. (Just try to be a little more specific when asking questions.)
So.. If I understand correctly.. I first check all the slots on all the PCI buses for SATA mass storage devices and then read their BAR5 and use the returned value as a pointer to the HBA_MEM struct of that device. Is that so?
Because that was the initial question "How do I get the ABAR?" and it appears to me that this might just as well be the answer.

Edit: The BAR5 of a SATA device (CD-ROM drive) in VMWare machine is 0xFD5FF000 which is definitely out of my memory's reach. What am I supposed to do with it?
I've allocated 0x0 - 0x800000 physical / 0xC0000000 - 0xC0800000 virtual memory if that's related in any sense.
And yes, I've already read the Wiki page regarding this matter.

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 2:40 am
by Octocontrabass
natiiix wrote:The BAR5 of a SATA device (CD-ROM drive) in VMWare machine is 0xFD5FF000 which is definitely out of my memory's reach. What am I supposed to do with it?
Map that physical address somewhere in your virtual address space so you can access the HBA registers.

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 2:41 am
by iansjack
I just hoped it would be easier to use parts of the Linux kernel. I need mine to be simply and fast, that would be impossible if I relied on Linux.
There's no reason to suppose it would be any simpler and faster to rely upon hypothetical libraries.
The BAR5 of a SATA device (CD-ROM drive) in VMWare machine is 0xFD5FF000 which is definitely out of my memory's reach. What am I supposed to do with it?
The registers are not mapped to physical RAM attached to the machine; they are mapped into the memory space (normally using an address far beyond that which likely to be occupied by RAM). To access the registers you just read and write the addresses pointed to by that BAR (although you should note that device registers may be read/write, write only, or read only).

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 2:56 am
by natiiix
iansjack wrote:The registers are not mapped to physical RAM attached to the machine; they are mapped into the memory space (normally using an address far beyond that which likely to be occupied by RAM). To access the registers you just read and write the addresses pointed to by that BAR (although you should note that device registers may be read/write, write only, or read only).
It wasn't supposed to be faster because of the libraries, the speed comparison was with the Linux kernel, not with writing it myself.

How exactly am I supposed to "just read and write the addresses pointed to by that BAR"? Because it doesn't seem that simple to me when the memory pointed to by BAR doesn't really exist in context of my OS. I thought I'd case the BAR5's content to HBA_MEM* and use that struct to access those registers.

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 3:49 am
by Octocontrabass
natiiix wrote:How exactly am I supposed to "just read and write the addresses pointed to by that BAR"? Because it doesn't seem that simple to me when the memory pointed to by BAR doesn't really exist in context of my OS. I thought I'd case the BAR5's content to HBA_MEM* and use that struct to access those registers.
Make it exist in the context of your OS by mapping the physical address in the BAR to a virtual address. Once you do that, you can use the virtual address to access the HBA registers.

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 4:35 am
by natiiix
Octocontrabass wrote:Make it exist in the context of your OS by mapping the physical address in the BAR to a virtual address. Once you do that, you can use the virtual address to access the HBA registers.
Okay, but I can't know what the BAR5 is gonna be, right? So how am I supposed to know which parts of the physical memory should be mapped to the virtual memory? Or can I just map them at runtime? Is it safe to do that?

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 5:02 am
by iansjack
Octocontrabass wrote:Make it exist in the context of your OS by mapping the physical address in the BAR to a virtual address. Once you do that, you can use the virtual address to access the HBA registers.
That assumes that the OP is using paging and virtual addresses. From what has been said so far I would doubt that that is the case. In which case you just use the address as if it were real RAM (with the exception that it may be read only or write only - and the value that you "store" in it might not be the value that you retrieve from it).

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 5:06 am
by natiiix
iansjack wrote:That assumes that the OP is using paging and virtual addresses. From what has been said so far I would doubt that that is the case. In which case you just use the address as if it were real RAM (with the exception that it may be read only or write only - and the value that you "store" in it might not be the value that you retrieve from it).
Obviously I'm using paging. That's why the address is out of the memory's boundaries, because such far addresses can't be mapped in higher-half kernel. (I assume it's obvious enough why it can't be done, but just in case it isn't.. The difference between 0xC0000000 and 0xFFFFFFFF is not enough to contain the physical address 0xFD5FF000.)

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 5:14 am
by MollenOS
Drivers such as these aren't necessarily OS specific. You can have a library that gives you some kind of API and it can be implemented into any OS with ease, because it works directly with hardware. The AHCI driver is merely being used by the rest of the system, it doesn't need to communicate with it and therefore a simply read/write sector API is all I really need. That surely doesn't have to be OS dependent.
Wrong, a proper AHCI driver relies on OS-specifc features, especially support for interrupts, dma-transfers, features like "Sleep" (Implementation of this varies based on hardware available, and thus you must have a timing driver). And of course it must have some method of allocating memory with their physical pointers.


Yes, the address that the BAR5 points too is physical memory, and that means you have to allocate some virtual memory and map it directly to the address that is pointed too by BAR5. Then you can access the hardware registers by using the virtual memory address

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 5:18 am
by Octocontrabass
natiiix wrote:Or can I just map them at runtime? Is it safe to do that?
You can map it at runtime. It's safe to do that, as long as you pay attention to the TLB so the CPU doesn't use stale mappings.
natiiix wrote:(I assume it's obvious enough why it can't be done, but just in case it isn't.. The difference between 0xC0000000 and 0xFFFFFFFF is not enough to contain the physical address 0xFD5FF000.)
It absolutely can be done. It sounds like you don't understand the full potential of paging.

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 5:54 am
by natiiix
MollenOS wrote:Wrong, a proper AHCI driver relies on OS-specifc features, especially support for interrupts, dma-transfers, features like "Sleep" (Implementation of this varies based on hardware available, and thus you must have a timing driver). And of course it must have some method of allocating memory with their physical pointers.
I don't really need anything like a proper AHCI driver. I want just a very basic one.
Octocontrabass wrote:It absolutely can be done. It sounds like you don't understand the full potential of paging.
That's not really what I meant, but whatever. I was referring to the impossibility of having the physical address already mapped when the virtual addresses are 0xC0000000 shifted are thus it would be significantly higher than the maximum size_t value. Please refrain from linking whole Wikipedia pages, it's meaningless and definitely not helpful.

Re: How to read from SATA HDD (AHCI) on low level?

Posted: Sat Mar 25, 2017 6:09 am
by iansjack
I'm a little surprised that you have mastered the complexities of setting up paging in the x86 architecture but can't manage a relatively simple concept like accessing the PCI device registers.

Whatever, you are asking for finished code and that's not really what this site is designed for, as I understand it. It's more about guiding people to write such code (amongst other things). Perhaps you would have more joy on somewhere like StackExchange?