Re: Reading the disk with AHCI.
Posted: Fri Feb 19, 2021 1:45 pm
With the updated printf function this is the output I get (also pointer CR2):
The Place to Start for Operating System Developers
http://f.osdev.org/
Code: Select all
cmdheader[i].prdtl = 1;
Code: Select all
cmdtable->prdt_entry[0].dba = (uint32_t)address;
cmdtable->prdt_entry[0].dbau = (address>>32);
cmdtable->prdt_entry[0].dbc = (count * 512) - 1;
cmdtable->prdt_entry[0].i = 1;
foliagecanine wrote:Have you tried taking out the AHCI read sector call?
yup, it is exactly the read call that directly causes the crush.Bonfra wrote:It's never a total win... I get a page fault on the real hardware if I try to execute this code.
The fun thing is that it is thrown when I call the sata_read function, not when I init the devices
thanks for the advice, your code is also easier to read. sadly it still causes the pagefault / general protectionfoliagecanine wrote: One other thing...
I've found the Wiki's code to read the disk to be somewhat unreliable (overwrites memory after the buffer).
Here's something similar to what I use (line numbers based on last git commit):
Those CS and SS values are very obviously wrong. You need to spend some time debugging your exception handler. I notice that the stack is aligned wrong when you make this function call.Bonfra wrote:Technically my handler dumps a good portion of the stack, I've run it a few times but for some reasons, I always get one of these two screens with empty stack (if I manually raise the interrupt the stack is full of data):
That is some awful inline assembly. Try this instead:Bonfra wrote:I've added this bit of code to the handler to print the content of CR2:
Code: Select all
asm volatile( "mov %0, cr2" : "=r"(cr2) );
Hmm ok, that call can happen in two circumstances, a normal interrupt or what I called a special interrupt, for the normal it could cause some problems around here and the special one could be around here I could fine dome problems since I edit the content of the stack with the RSP register. Thank's I'll let you know how it goesOctocontrabass wrote: Those CS and SS values are very obviously wrong. You need to spend some time debugging your exception handler. I notice that the stack is aligned wrong when you make this function call.
I always forget how to use this syntax, thanks.Octocontrabass wrote: That is some awful inline assembly. Try this instead:Code: Select all
asm volatile( "mov %0, cr2" : "=r"(cr2) );
No, the stack is misaligned the same way for both kinds of interrupt. You should fix the stack alignment in the shared code path. (For example, you could subtract 16 instead of 8 from RSP here.)Bonfra wrote:Hmm ok, that call can happen in two circumstances, a normal interrupt or what I called a special interrupt, for the normal interrupt I don't think that there is a problem but maybe around here I could fine dome problems since I edit the RSP register.
to prevent other errors I've also added 16 instead of 8 here but now whenever I hit a key I get a division by zero. I've also changed all the other code between of these two operations that involve rsp but it is still a division by zeroOctocontrabass wrote: No, the stack is misaligned the same way for both kinds of interrupt. You should fix the stack alignment in the shared code path. (For example, you could subtract 16 instead of 8 from RSP here.)
Code: Select all
mov rax, [rsp + 8 * 16]
Code: Select all
mov rax, [rsp + 8 * 18]
Yes, I also changed line 63 fromOctocontrabass wrote: ...And I see you edited your post as I was replying.
Code: Select all
lea rdi, [rsp + 8] ; skip the MXCSR register.
Code: Select all
lea rdi, [rsp + 16] ; skip the MXCSR register.
The INT instruction doesn't push an error code, so your stack frame will definitely be wrong if that's how you test it. Try something like this:Bonfra wrote:Oddly enough if I raise the exception manually with asm("int 0xe") I get the CS and SS registers right (0x10 and 0x08) but if let it happen naturally without forcing it I still get the wrong values.
Code: Select all
uint8_t temp = *(volatile uint8_t *)0xfedcba9876543210;
Oh.Octocontrabass wrote:The INT instruction doesn't push an error code, so your stack frame will definitely be wrong if that's how you test it.
Bingo, wrong values everywhere but why?Octocontrabass wrote: Try something like this:This will cause #GP with an error code of 0. Pick a canonical address that isn't mapped to cause #PF instead.Code: Select all
uint8_t temp = *(volatile uint8_t *)0xfedcba9876543210;
Code: Select all
int x = 0;
int y = 7 / x;