I'm trying to write a simple ATA driver using PIO. I've written out code to run the IDENTIFY command, however when I run it I get a General Protection Fault.
Bochs says:
Code: Select all
fetch_raw_descriptor: GDT: index (a7) 14 > limit (17)
This is where the error occurs in the code:
Code: Select all
outb(0x1F6,0xA0);
outb(0x1F2,0);
outb(0x1F3,0);
outb(0x1F4,0);
outb(0x1F5,0);
outb(0x1F7,0xEC); // Causes the GPF
Here's some of the code for my GDT:
Code: Select all
#define GDT_ENTRIES 3
typedef struct {
uint16_t limit_l;
uint16_t base_l;
uint8_t base_m;
uint8_t type;
uint8_t gran;
uint8_t base_h;
} __attribute__((packed)) gdt_entry;
typedef struct {
uint16_t limit;
uint32_t base;
} __attribute__((packed)) gdt_pointer;
gdt_pointer gp;
gdt_entry gdt[GDT_ENTRIES];
void gdt_set_entry(uint16_t n,uint32_t base,uint32_t limit,uint8_t type,uint8_t gran){
gdt[n].base_l=base & 0xFFFF;
gdt[n].base_m=(base>>16) & 0x00FF;
gdt[n].base_h=(base>>24) & 0x00FF;
gdt[n].limit_l=limit & 0xFFFF;
gdt[n].gran =(limit>>16) & 0x000F;
gdt[n].gran |= gran & 0x00F0;
gdt[n].type = type;
}
extern void gdt_load();
void GDT_init(void){
gp.limit=sizeof(gdt_entry)*GDT_ENTRIES-1;
gp.base =(uint32_t)&gdt;
gdt_set_entry(0,0,0x00000000,0x00,0x00);
gdt_set_entry(1,0,0xFFFFFFFF,0x9A,0xCF);
gdt_set_entry(2,0,0xFFFFFFFF,0x92,0xCF);
gdt_load();
}
Code: Select all
global gdt_load
extern gp
gdt_load:
lgdt [gp]
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:.flush
.flush:
ret