I'm trying to load my kernel from an optical drive, but my reading function is not working. I'm trying to read a sector in PIO mode based on http://wiki.osdev.org/ATAPI. After the command byte string is sent to the drive as 6 words it doesn't sends any interrupts at all. Interrupt lines 14 and 15 are enabled in the PIC (i'm able to read keyboard interrupts).
First step is detecting the device by reading its registers 0x1F2-0x1F5. I get 0x53, 0xAA, 0x00, 0x08 as a result instead of 0x01, 0x01, 0x14, 0xEB.
My code what does the detection:
Code: Select all
.global detecting_packet_device
.type detecting_packet_device, @function
detecting_packet_device:
push %ebp
mov %esp,%ebp
#call reset_atapi
inbyte $ATA_SECTOR_COUNT
and $0xff,%eax
push %eax
call printreg
push $10
call printchar
inbyte $ATA_ADDRESS1
and $0xff,%eax
push %eax
call printreg
push $10
call printchar
inbyte $ATA_ADDRESS2
and $0xff,%eax
push %eax
call printreg
push $10
call printchar
inbyte $ATA_ADDRESS3
and $0xff,%eax
push %eax
call printreg
push $10
call printchar
mov %ebp,%esp
pop %ebp
ret
My reading function (The part where the actual read would happen is not implemented now, when it was there it was just reading full 0s):
The function should read sector 0x10 - the firs non 0 sector.
Code: Select all
.equ ATA_DATA, 0x1F0
.equ ATA_FEATURES, 0x1F1
.equ ATA_SECTOR_COUNT, 0x1F2
.equ ATA_ADDRESS1, 0x1F3
.equ ATA_ADDRESS2, 0x1F4
.equ ATA_ADDRESS3, 0x1F5
.equ ATA_DRIVE_SELECT, 0x1F6
.equ ATA_COMMAND, 0x1F7
.equ ATA_DCR, 0x3F6
.global read_atapi
.type read_atapi, @function
read_atapi:
push %ebp
push %ebx
mov %esp,%ebp
#ATA_DRIVE_SLAVE & (1<<4) // 0xB0&(1<<4)
outbyte $0x10, $ATA_DRIVE_SELECT
wait_400_ns
outbyte $0x0, $ATA_FEATURES
#atapi sector size (2048) & 0xff
outbyte $0x0, $ATA_ADDRESS2
#atapi sector size (2048) >> 8
outbyte $0x8, $ATA_ADDRESS3
#ATA packet command
outbyte $0xA0, $ATA_COMMAND
wait_while_ide_is_busy:
inbyte $ATA_COMMAND
andb $0x80, %al
jnz wait_while_ide_is_busy
xor %eax, %eax
#while (!((status = inb (ATA_COMMAND (bus))) & 0x8) && !(status & 0x1))
wait_ide_to_be_ready:
inbyte $ATA_COMMAND
mov %eax, %ebx
andb $0x08, %bl
notb %bl
andb $0x01, %al
notb %al
cmpb $0x0, %bl
jz wait_ide_to_be_ready
cmpb $0x0, %al
jz wait_ide_to_be_ready
outword $0xa800, $ATA_DATA
outword $0x0000, $ATA_DATA
outword $0x0010, $ATA_DATA
outword $0x0000, $ATA_DATA
outword $0x0001, $ATA_DATA
outword $0x0000, $ATA_DATA
#jmp .
#inbyte $ATA_ADDRESS2
#inbyte $ATA_ADDRESS3
mov %ebp,%esp
pop %ebx
pop %ebp
ret
Code: Select all
.global StartOfIDT
StartOfIDT:
.rep 0x31
.word my_general_interrupt_handler
.word 8
.byte 0
.byte 0b10001111
.word 0
.endr
.word keyboard_interrupt
.word 8
.byte 0
.byte 0b10001110
.word 0
.rep 12
.word my_general_interrupt_handler
.word 8
.byte 0
.byte 0b10001111
.word 0
.endr
.word ide_interrupt_1
.word 8
.byte 0
.byte 0b10001110
.word 0
.word ide_interrupt_1
.word 8
.byte 0
.byte 0b10001110
.word 0
IDTend:
.global IDTdescriptor
IDTdescriptor:
.word 2047
.int StartOfIDT
.equ MASTER_PIC_COMMAND, 0x20
.equ MASTER_PIC_DATA, 0x21
.equ SLAVE_PIC_COMMAND, 0xa0
.equ SLAVE_PIC_DATA, 0xa1
.global Init_interrupts
.type Init_interrupts, @function
Init_interrupts:
pusha
lidt (IDTdescriptor)
xor %ecx,%ecx
#starting the initialization
mov $MASTER_PIC_COMMAND,%dx
mov $0x11,%al
out %al,%dx
call iowait
mov $SLAVE_PIC_COMMAND,%dx
mov $0x11,%al
out %al,%dx
call iowait
#providing the offset for the irqs
mov $0x30,%al
mov $MASTER_PIC_DATA,%dx
out %al,%dx
call iowait
mov $SLAVE_PIC_DATA,%dx
mov $0x38,%al
out %al,%dx
call iowait
#tell Master PIC that there is a slave PIC at IRQ2 (0000 0100)
mov $4,%al
mov $MASTER_PIC_DATA,%dx
out %al,%dx
call iowait
#tell Slave PIC its cascade identity (0000 0010)
mov $2,%al
mov $SLAVE_PIC_DATA,%dx
out %al,%dx
call iowait
#set up 8086/88 (MCS-80/85) mode for master and slave also
mov $MASTER_PIC_DATA,%dx
mov $0x01,%al
out %al,%dx
call iowait
mov $SLAVE_PIC_DATA,%dx
mov $0x01,%al
out %al,%dx
#masking the interrupts
#set requiered bit 0 to enable an interrupt
call iowait
mov $0xf9,%al
mov $MASTER_PIC_DATA,%dx
out %al,%dx
mov $0x3f,%al
mov $SLAVE_PIC_DATA,%dx
out %al,%dx
popa
sti
ret
Thank You in advance,
Andrej