fireshadow4126 wrote:I've been attempting to add device driver support to my OS
....
But when I call hd_install(), it hangs at the while loop forever.
....but to get a filesystem working, I would need a hard-disk driver working, which leads back to the beginning of my problem.
...
Thanks in advance!
You are doing this :
Code: Select all
void send_command(unsigned int number, unsigned int flags)
{
switch (number)
{
case ATA_IDENTIFY:
{
....
....
unsigned char status = inportb(ATA_COMMAND(controller));
if (status == 0)
{
puts("Drive does not exist.");
}
unsigned char st[32] = { '\0' };
while ((status = inportb(ATA_COMMAND(controller))) & (1 << ATA_BSY))
{
;
}
}
}
}
Your problem is this one (where it loops for ever):
Code: Select all
while ((status = inportb(ATA_COMMAND(controller))) & (1 << ATA_BSY))
{
;
}
pooling forever the status will HANG UP if there is no hard disk installed at that ide slot !
while ((status = inportb(ATA_COMMAND(controller))) & (1 << ATA_BSY)) { ; };
if there's a CD/DVD drive your statement will loop for ever (or for no drive)!
Do this
and before sending CMD:
int i=10000; while ((inportb(ATA_COMMAND(controller))!=0x50)&&(i>0)) { i--; };
^^0x50 (wait until drive not BSY)
(after sending CMD):
i=10000; while ((inportb(ATA_COMMAND(controller))!=0x58)&&(i>0)) { i--; };
^^0x58 (wait until data RDY)
And also (!) you should check status BEFORE you want to send CMD to drive, but again, don't
loop for ever (!)
SO :
Code: Select all
...
...
...
...
...
int i;
unsigned char selector = (flags & (1 << ATA_SLAVE)) ? 0xB0 : 0xA0;
unsigned char controller = (flags & (1 << ATA_CONTROLLER)) ? PRIMARY_BASE : SECONDARY_BASE;
i=10000;
while ((inportb(ATA_COMMAND(controller))!=0x50)&&(i>0)) { i--; };
outportb(ATA_DRIVE(controller), selector);
outportb(ATA_SECTOR_COUNT(controller), 0);
outportb(ATA_SECTOR_NUM(controller), 0);
outportb(ATA_CYLINDER_LOW(controller), 0);
outportb(ATA_CYLINDER_HI(controller), 0);
outportb(ATA_COMMAND(controller), 0xEC);
unsigned char status = inportb(ATA_COMMAND(controller));
if (status == 0)
{
puts("Drive does not exist.");
}
unsigned char st[32] = { '\0' };
i=10000;
while ((inportb(ATA_COMMAND(controller))!=0x58)&&(i>0)) { i--; };
...
...
...
...
...
send_command(ATA_IDENTIFY, (1 << ATA_CONTROLLER));
asm {
mov dx,0x1f0 // or 0x170 or what ever ... (you chage this with your consts/var...)
mov edi,[pointer_to_your_data_structure]
mov ecx,255
cld
rep insw // finally read :)
}
//(if it returns "trash" it means no HD at that position (try another IDE slot, MASTER/SLAVE) )
here's how I do it :
(if it returns "trash" it means no HD at that position (try another IDE slot, MASTER/SLAVE) )
Code: Select all
Type ide_prop Field=1 'This record is returned BY IDE when IDETIFY drive command is send to 0x1f7/0x177.
id1 As UShort '0
cylinders As UShort '1
id2 As UShort '2
heads As UShort '3
id3(1 To 2) As UShort '4
sect_per_track As UShort '6
id4(1 To 3) As UShort '7->9
serial_number As String * ((19-10+1)*2) '10 -> 19
controller_type As Ushort '20
controller_buffer_size As Ushort '21 -> realsize = (dword) bufsize*512
ecc_transferred As UShort '22
controller_number As String * ((26-23+1)*2) '23->26
model_number As String*((46-27+1)*2) '27->46
num_sect_per_int As ushort '47
dword_trasfer_flag As UShort '48
End Type
'ide=ide slot number (0/1) ; typ = (master=0)/(slave=1)
Function get_ide_info(ide As Integer,typ As Integer,buf As ide_prop Ptr) As Integer
Dim As Integer i
Dim As UShort ptr dd=callocate(256*2)
dim as ubyte w
Dim As Any Ptr p
If ide = 0 Then
w = (&h0a+cast(ubyte,typ))*&h10+&h40
p = dd
Asm
push ax
push dx
push ecx
mov ecx,10000
mov dx,&h1f7
_redo_f1:
mov dx,&H1f1
in al,dx
mov dx,&H1f7
in al,dx
dec ecx
jecxz _ok_time_to_go_OUT
in al,dx
cmp al,&h50 '{wait until controller not busy}
jne _redo_f1
_ok_time_to_go_OUT: ':))
mov al,[w]
mov dx,&h1f6
Out dx,al
mov al,&hec
mov dx,&h1f7
Out dx,al
mov ecx,10000
_redo_f2:
mov dx,&H1f1
in al,dx
mov dx,&H1f7
in al,dx
dec ecx
jecxz _OK_now_realy_is_time_to_END
in al,dx
cmp al,&h58 ' {wait for data ready} :))
jne _redo_f2
jmp short teora3
_OK_now_realy_is_time_to_END:
pop ecx
pop dx
pop ax
end asm
function=0
exit function
asm
teora3:
mov dx,&h1f0
mov edi,[p]
mov ecx,255
cld
push edi
rep insw ' finally read :)
pop edi
pop ecx
pop dx
pop ax
End asm
movsb1(dd,buf,SizeOf(ide_prop)) ':))
Function = 1
dealloc2 @dd
ElseIf ide=1 Then
w = (&h0a+cast(ubyte,typ))*&h10+&h40
p = dd
Asm
push ax
push dx
push ecx
mov ecx,10000
_redo_f12:
mov dx,&H171
in al,dx
mov dx,&H177
in al,dx
dec ecx
jecxz _ok_time_to_go_OUT2
in al,dx
cmp al,&h50 '{wait until controller not busy}
jne _redo_f12
_ok_time_to_go_OUT2: ':))
mov al,[w]
mov dx,&h176
Out dx,al
mov al,&hec
mov dx,&h177
Out dx,al
mov ecx,10000
_redo_f22:
mov dx,&H171
in al,dx
mov dx,&H177
in al,dx
dec ecx
jecxz _OK_now_realy_is_time_to_END2
in al,dx
cmp al,&h58 ' {wait for data ready} :))
jne _redo_f22
jmp short teora4
_OK_now_realy_is_time_to_END2:
pop ecx
pop dx
pop ax
end asm
function=0
exit function
asm
teora4:
mov dx,&h170
mov edi,[p]
mov ecx,255
cld
push edi
rep insw ' finally read :)
pop edi
pop ecx
pop dx
pop ax
End asm
movsb1(dd,buf,SizeOf(ide_prop)) ':))
Function = 1
dealloc2 @dd
endif
End function
best regards ...
happy codeing ...
(don't worry ! I've obtained this after a long an painfull time ...my full project is at :http//filesystemd.sourceforge.net)