flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Device driver FDC in virtual or protected mode

Goto page 1, 2, 3  Next
Author
Thread Post new topic Reply to topic
neo-92



Joined: 26 Feb 2014
Posts: 25
neo-92
Hi all, i'm new of the forum, i create a device driver for FDC through ports with DMA, but i try to execute in virtual mode and don't work Sad, only works in real mode. To a few words it is as if i execute the interrupt 0x13 but directly with memory. alternatively, how can i fix it without drop back to realmode? Thanks. Smile
Post 11 Jul 2014, 22:37
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
It is easier for people to help you if you post your code.
Post 11 Jul 2014, 22:46
View user's profile Send private message Visit poster's website Reply with quote
neo-92



Joined: 26 Feb 2014
Posts: 25
neo-92
Of course, i'm sorry, here it:
Code:
org 7c00h

use16

jmp 0:rmode

rmode:
mov ax,0
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0fffeh
cli
lgdt[gdt]
mov eax,cr4
or al,1
mov cr4,eax
mov eax,cr0
or al,1
mov cr0,eax
jmp gdt_code-gdt_table:pmode

vm86:
sti
mov al,6
out 0ah,al
mov al,0ffh
out 0ch,al
mov al,[start]
out 4,al
mov al,0
out 4,al
mov al,0ffh
out 0ch,al
out 5,al
mov al,1
out 5,al
mov al,0
out 81h,al
mov al,2
out 0ah,al
mov dx,3f2h
mov al,1ch
out dx,al
call readmsr
mov dx,3f5h
mov al,66h
out dx,al
mov al,0
out dx,al
mov al,0
out dx,al
mov al,0
out dx,al
mov al,2
out dx,al
mov al,2
out dx,al
mov al,18
out dx,al
mov al,27
out dx,al
mov al,0ffh
out dx,al
jmp $

readmsr:
mov dx,3f4h
in al,dx
and al,0c0h
cmp al,80h
jne readmsr
ret

use32

pmode:
mov ax,gdt_data-gdt_table
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov esp,9fffch
mov al,0f0h
out 60h,al
mov al,0
out 60h,al
scan:
in al,60h
cmp al,1ch
jne scan
mov ax,18h
ltr ax
push 0
push 0
push 0
push 0
push 0
push 0fffeh
push 20000h
push 0
push vm86
iret

gdt:
dw gdt_end-gdt_table-1
dd gdt_table

gdt_table:
dd 0
dd 0

gdt_code:
dw 0ffffh
dw 0
db 0
db 9ah
db 0cfh
db 0

gdt_data:
dw 0ffffh
dw 0
db 0
db 92h
db 0cfh
db 0

tss_sel:
dw 0ffffh
dw 0
db 0
db 89h
db 8fh
db 0

gdt_end:

times 510-($-$$) db 0
dw 0aa55h

use16

start:
mov di,0b800h
mov es,di
mov di,0
mov byte[es:di],41h
mov byte[es:di+1],7
jmp $

times 510-($-start) db 0
    

Thanks.
Post 11 Jul 2014, 22:54
View user's profile Send private message Reply with quote
shutdownall



Joined: 02 Apr 2010
Posts: 518
Location: Munich
shutdownall
As far as I know, the BIOS int 13h is available in real mode only.
When you switch to protected mode you have to set the IDT (interrupt description table) same way you do it for the GDT. I am not sure but I think the BIOS interrupts can not be used directly in protected mode.

http://wiki.osdev.org/Interrupt_Descriptor_Table
Post 11 Jul 2014, 23:25
View user's profile Send private message Send e-mail Reply with quote
neo-92



Joined: 26 Feb 2014
Posts: 25
neo-92
I don't want to execute the interrupt 0x13, but use the ports FDC through DMA hardware. Already done in virtual mode 8086 but reads the second sector without jumping to the [seg:off]-[ES:BX], what can it be? Confused
Post 12 Jul 2014, 21:09
View user's profile Send private message Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC
you have to make alot of assumptions about the hardware to use it in the way you are. I wrote a fully functional Floppy Driver within Long Mode if you're interested. my driver uses the legacy DMA controller and interrupts. it doesn't poll the hardware. it does, however, implement a timeout function to handle a hardware failure.

-Stefan

_________________
byte me.
Post 13 Jul 2014, 04:12
View user's profile Send private message Visit poster's website Reply with quote
neo-92



Joined: 26 Feb 2014
Posts: 25
neo-92
Hi Stefan, i send you a PM on the argument. See you soon. Wink
Post 13 Jul 2014, 22:25
View user's profile Send private message Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC
it's pretty old, but the version of the floppy code on my site (the www link at the bottom of my posts) is the same code as my latest version. it's included in my OS "Mathis".

the driver code is in Mathis/ORB.Floppy.asm. each of the STRUCs represent one command to be issued to the hardware such as "ReadCyl" which reads one entire cylinder (on a cylinder boundary using CHS addressing).

-Stefan

_________________
byte me.
Post 14 Jul 2014, 00:18
View user's profile Send private message Visit poster's website Reply with quote
neo-92



Joined: 26 Feb 2014
Posts: 25
neo-92
Why the DMA don't work in virtual mode 8086?
Post 15 Jul 2014, 11:06
View user's profile Send private message Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC
I don't use v86 so I can't help with the mode itself. why don't you just use protected mode? you appeared to be ok with it earlier. the following website has some detail on v86:
http://wiki.osdev.org/Virtual_8086_Mode
Post 15 Jul 2014, 13:32
View user's profile Send private message Visit poster's website Reply with quote
neo-92



Joined: 26 Feb 2014
Posts: 25
neo-92
Of course, i'd read. But also in protected mode DMA ports do not work...
Post 15 Jul 2014, 13:45
View user's profile Send private message Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC
DMA ports do work in 32-bit Protected Mode. you simply need interrupt handlers for whatever hardware you intend to use in Protected Mode. the interrupt handler your using in Real Mode (the binary) is all but guaranteed to fail within Pm. the Interrupt Vector Table no longer functions in Protected Mode: it becomes the Interrupt Descriptor Table (severely different format than the IVT).
Post 15 Jul 2014, 14:20
View user's profile Send private message Visit poster's website Reply with quote
neo-92



Joined: 26 Feb 2014
Posts: 25
neo-92
Hi Stefan, i initialize the IDT in this so:
Code:
org 7c00h

use16

cli
lgdt[gdt]
lidt[idt]
mov eax,cr0
or al,1
mov cr0,eax
jmp code32-table1:kernel

use32

kernel:
mov ax,data32-table1
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov esp,9fffch
mov eax,isr_fdc
mov [table2+49*8],ax
mov word[table2+49*8+2],code32-table1
mov word[table2+49*8+4],8e00h
shr eax,16
mov [table2+49*8+6],ax
int 49
jmp $

isr_fdc:
cli
pushad
call fdc
popad
sti
iret

fdc:
mov dx,3f2h
mov al,1ch
out dx,al
mov al,6
out 0ah,al
mov al,0ffh
out 0ch,al
mov al,[start]
out 4,al
mov al,0
out 4,al
mov al,0ffh
out 0ch,al
out 5,al
mov al,1
out 5,al
mov al,0
out 81h,al
mov al,2
out 0ah,al
mov dx,3f5h
mov al,66h
out dx,al
mov al,0
out dx,al
mov al,0
out dx,al
mov al,0
out dx,al
mov al,2
out dx,al
mov al,2
out dx,al
mov al,18
out dx,al
mov al,27
out dx,al
mov al,0ffh
out dx,al
ret

gdt:
dw end_gdt-table1-1
dd table1

table1:
dq 0

code32:
dw 0ffffh
dw 0
db 0
db 9ah
db 0cfh
db 0

data32:
dw 0ffffh
dw 0
db 0
db 92h
db 0cfh
db 0

end_gdt:

idt:
dw end_idt-(50*8)-1
dd table2

table2:
dd 50*2

end_idt:

times 510-($-$$) db 0
dw 0aa55h

use32

start:
mov byte[0b8000h+2],42h
ret

times 510-($-start) db 0
    

The interrupt 49 does it work, but why the address '[start]' isn't transferred to the DMA?
Post 18 Jul 2014, 21:52
View user's profile Send private message Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC
I don't have the structure of the DMA code sequence memorized so I can't read it off hand and tell you if your code is correct. I use a function. that said, you're loading the DMA with code, rather than an address somewhere (it looks like you want to write the code section to disk), on line 48:
Code:
mov al,[start]    

should be:
Code:
mov al, start and 255    

when you write the address you need to send 3 bytes (lowest order byte is sent first). you then write 2 bytes for the length (again, lowest order byte first).

-Stefan

_________________
byte me.
Post 20 Jul 2014, 13:35
View user's profile Send private message Visit poster's website Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC
pardon my incomplete statement at the end of my last post: when you write the Address bytes, you write the first 2 bytes to the SAME I/O address. when you write the final byte of the address (the "page" address) you write it to a distinct (different) I/O address. also, when you write the Count word (2 bytes) you write both bytes to a distinct address. The order is as follows:

Mask Register (disable the device while programming it).
Clear Flip Flop Register (writing anything will initialize the flip flop).
Mode Register
Address Register (low byte)
Address Register (middle byte)
Page Register (the high byte)
Count Register (low byte)
Count Register (high byte)
Mask Register (enable the device once more).

you then program the Floppy Controller to perform an operation that is inline with whatever value you wrote to the Mode Register.

also, it looks like your missing a port write within the DMA section.

as for issuing writes to the Floppy: that, to my knowledge, requires a wait loop to ensure the floppy controller is ready for each byte (you don't have one). that code section is considerably more complicated in general because you need the CHS address. BTW; my code does an LBA->CHS conversion before issuing the command.

one last thing: when I said you need an Interrupt Service Routine within Protected Mode I was referring to a routine that handles the response from Hardware (when the operation is complete). you don't need to implement the procedure within an ISR: you can use a regular 'call' instruction code sequence. that said, your method won't stop the driver from working.

-Stefan

_________________
byte me.
Post 20 Jul 2014, 14:04
View user's profile Send private message Visit poster's website Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC
I modified my "IssueCommand" function for PM. this should work just fine:

Code:
    Floppy.iobase = 0x3F0
    Floppy.IssueCommand:
        
        cld
        lea esi,[esp+4+1]
        mov ecx, 10000;my original code benchmarked the bus to generate a timeout value.
        mov edx, Floppy.iobase+5
        
        movzx ebx, byte [esp+4];grab the length. it's usually 9 bytes.
        xor eax, eax
       .loop:
            
            dec edx
            @@:
                
                dec ecx
                jz  @f
                
                in  al, dx
                and eax, 11000000b
                cmp eax, 10000000b
                
            jne @b
            
            inc edx
            lodsb
            out dx, al
            
        dec  ebx
        jnz .loop
        
    ret 12
    align 2
        @@: jmp $; write your own error handler.    


call it like this:
Code:
    Floppy.Head     = 0
    Floppy.Cylinder = 0
    Floppy.Sector   = 2
        
    push 0xFF1B
    push 0x12020000 + Floppy.Head + Floppy.Sector shl 8
    push Floppy.Cylinder shl 24 + Floppy.Head shl 18 + 11000110b*256 + 9
    call Floppy.IssueCommand    

the constants show you where each piece of data goes. this example is targetting Head 0, Cylinder 0, and Sector 2. the procedure cleans up the stack. the Floppy Command being issued is a ReadSector Command.

-Stefan

edit: "mzx" is an EQUate for the "movzx" instruction. also, I neglected to modify the timeout counter (ecx) as my original code used a benchmarking procedure to determine the counter/timeout rather than an arbitrary number.

_________________
byte me.


Last edited by BAiC on 21 Jul 2014, 14:43; edited 2 times in total
Post 20 Jul 2014, 14:40
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
I think the "Floppy.Sector shl 40" could cause a problem in 32-bit mode.

Also what happens if the length is greater than 11 bytes?
Post 20 Jul 2014, 14:44
View user's profile Send private message Visit poster's website Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC
revolution: yeah.. apparently I modified my post moments after you starting reading it. it was a mod of my Long Mode code that I forgot to change.

Quote:
Also what happens if the length is greater than 11 bytes?

garbage data gets written to the floppy controller. it doesn't modify the source data (it doesn't write to the stack) so it won't corrupt the stack.

revolution: do you know any Floppy commands that use more than 11 bytes? the function exists to support a driver, not to support application code so it only needs to consider the valid commands.
Post 20 Jul 2014, 14:49
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
BAiC wrote:
it doesn't modify the source data (it doesn't write to the stack) so it won't corrupt the stack.
It is just that you have a stdcall type function with a fixed 12 bytes on the stack begin popped by the callee. Perhaps it would make more sense to pass in a pointer to a buffer (which can be on the stack) and have the caller release the stack afterwards. That way your function can be more flexible and not force the caller to always allocate exactly 12 bytes.
Post 20 Jul 2014, 20:59
View user's profile Send private message Visit poster's website Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC
no.
Post 21 Jul 2014, 11:54
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.