Page 1 of 1

AHCI driver error on qemu

Posted: Thu Oct 24, 2024 12:44 pm
by MikyBart
Hi all, I wrote an ahci driver for my kernel in assembly (nasm).
when I run qemu, the kernel in the initialization of the ahci driver does not hang but in exit qemu gives me the following error:

Code: Select all

qemu: AHCI: Failed to start FIS receive engine: bad FIS receive buffer address
so that the buffer must be in physical memory and not virtual.

What can I do to overcome this problem?

thanks to all.

Re: AHCI driver error on qemu

Posted: Fri Oct 25, 2024 4:06 pm
by Octocontrabass
Put a valid physical address in the PxFB and PxFBU registers.

Re: AHCI driver error on qemu

Posted: Sat Nov 16, 2024 5:16 am
by MikyBart
Thanks for the reply, how can I get a physical address with limine?

Re: AHCI driver error on qemu

Posted: Sat Nov 16, 2024 7:14 pm
by MichaelPetch
I assume you allocated the space for the buffers in virtual memory somewhere?

Re: AHCI driver error on qemu

Posted: Sun Nov 17, 2024 12:19 am
by miky
Yes, I use Limine as a bootloader.
So I have to assign a physical address to a buffer, but I don't know where to assign it, in which area of ​​memory.

Re: AHCI driver error on qemu

Posted: Sun Nov 17, 2024 12:35 am
by MichaelPetch
Q1: Might be easier to ask it this way - have you implemented a physical memory manager yet?
Q2: As I recall you are writing this all in NASM? Is that still the case?
Q3: Have you at this stage setup any Limine requests? Do you know how to? There is probably quick and dirty way where you have to do a Limine request

I ask this because there is a way you could probably do it by putting the buffer in the .bss section and using the LIMINE_KERNEL_ADDRESS_REQUEST (see: https://github.com/limine-bootloader/li ... ss-feature ) . If you make that request and compute the difference between virtual_base and physical_base (ie kernel_offset = virtual_base-physical_base) you can subtract kernel_offset from any address in the kernel address space (which would include the .bss section) to get the corresponding physical address. That physical address can then be used as the physical address for AHCI (ie: the physical addresses for PxFB and PxFBU registers).

I recently helped someone on Stackoverflow regarding computing a physical address from a virtual kernel address in Limine. The "C" code was here: https://github.com/baponkar/KeblaOS/blo ... nel.c#L105 . kernel_offset is computed and stored as a global variable that can then be subtracted from any kernel virtual address to yield a physical address.

Re: AHCI driver error on qemu

Posted: Sun Nov 17, 2024 9:38 am
by MikyBart
Thanks for your reply.

A1: No
A2: Yes
A3: My kernel currently sets up a GDT, IDT and interrupt handling including system calls (int 128).
I know the limine protocol but the manual is very limited on memory management.

I don't have a memory manager yet, neither physical nor virtual, these are things I'm currently studying.

Re: AHCI driver error on qemu

Posted: Sun Nov 17, 2024 10:02 am
by MichaelPetch
This assumes you are using Limine Boot Protocol.

Although you have no VMM, you do have virtual memory mappings provided by Limine. Without a physical memory manager at this point the easiest way is I suggested already. You will have to make a Limine request (LIMINE_KERNEL_ADDRESS_REQUEST) to retrieve the address of the kernel in virtual memory and the physical address (both part of the response). As I pointed out if you compute the difference (call it kernel_phys_virt_offset) between them (virtual_base-physical_base from the Limine response) you can then take any kernel virtual address and subtract that computed offset to obtain the physical address.

If you place the buffers in .bss, that becomes part of the kernel virtual address space. You would just take the virtual address of the buffers in the .bss section and subtract kernel_phys_virt_offset from them. Those will be the physical addresses in memory of the buffers. Those physical addresses can then be used for AHCI for the PxFB and PxFBU registers. This works because Limine has a guarantee that wherever it places the kernel in physical memory it is contiguous physical memory. It then maps that contiguous physical memory into the higher half.

If you had a physical memory manager you would request free physical page(s) and use addresses in those page(s) to use for the AHCI buffers.