flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Read/Write to disk, keyboard, mouse, PM to RM and back, etc.

Author
Thread Post new topic Reply to topic
c.j.gowett



Joined: 31 Dec 2013
Posts: 12
c.j.gowett 13 Jan 2014, 02:35
Hello everyone Very Happy
I am trying to read and write to the disk in protected mode using I/O ports.
I have looked and looked online for a port listing inside and out and all I found is Ralf's Interrupt List package. I looked there and didn't find what port to input for where to put the data in memory once its loaded, going by what I saw. I noticed everything else such as sector, cylinder, head/drive, etc. I'm just confused on how to implement it in assembly code.

I am also looking to find out how to do mouse and keyboard inputs so I can do GUI applications in my will-be operating system. I already know how to switch to protected mode and perform graphic operations without interrupts so I am good there. Switching back to real mode was giving me issues. Interrupts in general I know how to do, its just the list of ports and how to do ports in general is what is giving me issues. If I can get the basics working, then I will be pleased with what I am doing.

If someone could implement it for me as an example in assembly code, it would be greatly appreciated. I really want to jump start my operating system to do basic things such as, well, just basic operating system stuff. An overview of how to do in/out ports would help as well.

I know that I am asking for a lot, but I would also be willing to help others based on what I know currently on assembly.


Last edited by c.j.gowett on 14 Jan 2014, 13:11; edited 1 time in total
Post 13 Jan 2014, 02:35
View user's profile Send private message Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC 13 Jan 2014, 10:03
first of all; it's critical to remember that if you want to access the drive (the controller usually) directly then you'll need to consider the different cases.

1) Legacy Port Addesses:
only relevant for Emulators/VMs including VMware, VirtualBox (fuck vbox, their implementation of the ATA spec is wrong), and QEMU. I use VMware almost exclusively.

2) Contemporary Drivers
implement a driver for each class/type of controller. possibly EVERY device model.

that said; the safest way to access the disk is with a PCI Enumerator. the PCI Configuration Space provides the port addresses after you've detected a hard drive controller. just be aware that the port layout in Config Space is dependent on the class of device.

FYI: VMware and vbox both report their legacy devices within PCI configuration space. therefore if you write a PCI Enumerator you'll end up supporting the legacy (virtual) device as well.

you can detect a controller with the following code (note: vbox doesn't implement readable LBA registers (per the ATA spec)). there are 4 port addresses, one of which is 0x1F0. I don't recall the other 3. my Operating System includes a PCI Enumerator so I haven't needed to remember them.
Code:
        mov edx, ATA.LBA1+ATA.Port;0x1F0
        in al, dx
            
            mov ebx, eax
                
                not al
                mov ah, al
                out dx, al
                in al, dx
                cmp ah, al;compare the value written to the value read (after write).
                
            mov eax, ebx
            
        out dx, al
        jne .fail.detect; if they're not equal then a controller isn't present at this legacy address.    
detecting an actual disk on the controller involves issuing a READ ID command after you've successfully detected a controller. the following code is how you issue a command to a controller. this code is taken from my Operating System. I also have an LBA48 IssueCommand that I can post if you like.

the input, rax, has the format:
RAX[07:00]: temporary data region. this is where the "stall" code writes "in al,dx" data to.
RAX[15:08]: Features Register
RAX[23:16]: Sector Count. the number of 512byte blocks involved (if it's a data transfer operation). this is zero based. 0 will transfer 1 sector. 1 will transfer 2 sectors, etc.
RAX[51:24]: LBA28 Address. (note: the 4 high order bits are part of the Device Register!)
RAX[55:52]: top 4 bits of Device Register (usually 0xE to select the "Master" device on the ATA ribbon cable)
RAX[63:56]: the ATA Command to be issued. writing this register triggers an interrupt if they're enabled.
Code:
        
        mov edx, 7 + ATA.Base;reading this port gives the Status. writing the same port results in a Command Issue.
        mov ecx, 1000;place some obnoxiously large countdowm value here.
            
            @@:
            
                dec ecx;stall until the device is ready for a command
                jz  @f
                
                in al, dx
                test al, ATA.Status.BSY + ATA.Status.DRQ
                
            jnz @b
        
            
            ;write the Device Register first.
            ror rax, 8*6
            dec edx
            out  dx, al
            
            rol rax, 8*6-8;restore to the Features Register.
            add edx, -5
            out  dx, al
            
            shr rax, 8;Sector Count
            inc edx
            out  dx, al
            
            shr rax, 8;LBA Low
            inc edx
            out  dx, al
            
            shr rax, 8;LBA Mid
            inc edx
            out  dx, al
            
            shr rax, 8;LBA High
            inc edx
            out  dx, al
            
            shr rax, 8+8;Command Register...  Skip over the Device Register as it's already been written.
            add edx, 2
            out  dx, al;WARNING: this instruction catalyzes an interrupt if they're enabled.
            
        ret
@@:
;place code here to report the error.    


how you go from there depends on the command you've issued. a READ_SECTORS command, for example, will trigger an interrupt when each sector is ready to be read using the ports. you read the data then wait until the next interrupt if you're reading multiple sectors (there is a READ_MULTIPLE command but it's a bit more complicated). a WRITE_SETORS command requires a bit more work after issuing the command. the code presented here works for the Legacy ports as well as ports provided from PCI Config Space for the Native PCI controller type. using a Native PCI controller allows you access to the DMA versions of the Commands. testing my OS on my hardware gives roughly 30MB/s and 60MB/s for my laptop/desktop configs. I highly recommend supporting DMA as it's considerably faster.

as to the other devices on your wish list you can find information on all of them by searching the web.

- Stefan

_________________
byte me.
Post 13 Jan 2014, 10:03
View user's profile Send private message Visit poster's website Reply with quote
sid123



Joined: 30 Jul 2013
Posts: 339
Location: Asia, Singapore
sid123 13 Jan 2014, 11:29
Yo,
Adding some points, no code though Razz
Well for keyboard and mouse INTs are unfortunately needed under PM,
You will retrieve a byte from the port, print it, but how would you print another
char if you receive another byte, well using loops will make the printing forever,
so you need an interrupt request or colloquially an IRQ that needs to be only fired when you press a key, IRQ 1 is for keyboard, similarly in the case of mouse the IRQ needs to be fired when something happens to the mouse (correct me if I went wrong), I guess PS/2 mouse IRQ is at IRQ 12.
As for mouse and keyboard you have two choices :
Legacy PS/2
USB
Well PS/2 is BS, and USB rocks for an end user, and most PCs today have a USB keyboard, but USB
is not something that can be made in one day, in fact it takes some months or so even for an experienced programmer to write a "proper" USB Stack, but don't worry we've something called PS/2 Emulation, in which the firmware (I guess) emulates a USB mouse as a PS/2 mouse/keyboard.
PS/2 is fairly easy, here's an example of a PS/2 Driver in C (note you need INTs activated)
http://forum.osdev.org/viewtopic.php?t=10247
Well for Disk I/O check this example for a floppy driver :
http://bos.asmhackers.net/docs/floppy/docs/floppy_tutorial.txt
Plus tell us whether you want all sorts of Memory Protection, Rings and other
Protected BS or you're just using PMode to access 4GB RAM,
Well if you don't want all that there is something called unREAL mode,
In which all BIOS INTs are accessible plus you've access to full 4GB of memory.
Cheers,
sid123

_________________
"Those who can make you believe in absurdities can make you commit atrocities" -- Voltaire https://github.com/Benderx2/R3X
XD
Post 13 Jan 2014, 11:29
View user's profile Send private message Reply with quote
c.j.gowett



Joined: 31 Dec 2013
Posts: 12
c.j.gowett 14 Jan 2014, 04:38
Isn't the rax register 64-bit mode? I am using 32-bit Protected Mode. I just want to be able to read and write to the disk using i/o ports. Is there any straight source code that is able to do that? A reference sheet of what data goes where would help me a lot. I am able to take direct source code and modify it to my needs. I should have mentioned this before that I am currently using a flash drive to boot my OS. I want to eventually move to a hard drive so I am going to need code for reading from and writing to a hard disk as well.

I would like to be able to get the code for keyboard and mouse input for my OS. If I can get the hard disk, mouse, and keyboard to work, then I am golden. If it is possible, source code that I can easily understand (i know it sounds like i'm asking for too much) would help a bunch.

I have tried unreal mode but had no luck on it; couldn't get it to work. I saw on OSDev Wiki there's two different ones, Big and Huge unreal mode. One is code up to 64k and the other is more but doesn't automatically save the high 16 bits of EIP. If this is not true, then what is it? If I could get the code to go from Protected Mode to Real Mode and back, let me know.
Thanks Very Happy
Post 14 Jan 2014, 04:38
View user's profile Send private message Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC 15 Jan 2014, 04:00
Quote:
Isn't the rax register 64-bit mode?

why yes it is Very Happy . the sequence for issuing a command is more complex in 32bit code (how complex depends on your capacity as a developer). my code is showing you the process, which is what's important to learning. btw; if you really think my code is bad then prepare for worse 'cuz that's where it's going.

Quote:
I just want to be able to read and write to the disk using i/o ports. Is there any straight source code that is able to do that?

no Evil or Very Mad . nothing is so simple (if you want to steal someone elses library then go elsewhere). you should be more concerned with reading and writing the disk correctly.

by the way; the PS/2 keyboard is a simpler device to program.

-Stefan

_________________
byte me.
Post 15 Jan 2014, 04:00
View user's profile Send private message Visit poster's website Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 15 Jan 2014, 19:17
As a point of reference I suggest you look at the ATA(PI) 6 specification [1] for legacy IO and behavior - this is also present on the newer AHCI controllers, which normally provide a PCI bridge and/or direct support for ATA commands. The AHCI specification [2] (this is sometimes called SATA but includes SCSI and others) is also freely available for more information.

Both should be present on the PCI bus, which will give you IO bases (though typically the legacy controllers use 0x170 and 0x1F0 ranges so this is used as a shortcut) via the PCI configuration information.

I've attached snippets from my boot sector/loader stages that do this (note read-only but you can swap the the command and rep insw instructions for writing)

Hope that helps

[1] http://www.t13.org/documents/UploadedDocuments/project/d1410r3b-ATA-ATAPI-6.pdf

[2] http://www.intel.com/content/www/us/en/io/serial-ata/ahci.html


Description: Example of 16 & 32 bit ATA/ATAPI using IDE LBA48 PIO
Download
Filename: ata.zip
Filesize: 5.96 KB
Downloaded: 556 Time(s)

Post 15 Jan 2014, 19:17
View user's profile Send private message Reply with quote
c.j.gowett



Joined: 31 Dec 2013
Posts: 12
c.j.gowett 15 Jan 2014, 22:54
Quote:
Quote:
I just want to be able to read and write to the disk using i/o ports. Is there any straight source code that is able to do that?

Quote:
no Evil or Very Mad . nothing is so simple (if you want to steal someone elses library then go elsewhere). you should be more concerned with reading and writing the disk correctly.

by the way; the PS/2 keyboard is a simpler device to program.

-Stefan


I'm not a person who steals Sad All I wanted to look at was some reference and then rewrite it completely in my own implementation. I don't think that's stealing. If it is then I need to relearn my words. xD
Post 15 Jan 2014, 22:54
View user's profile Send private message Reply with quote
sid123



Joined: 30 Jul 2013
Posts: 339
Location: Asia, Singapore
sid123 16 Jan 2014, 07:35
Hmm...
Can you tell us, what your OS is in it's current state,
Did you get the IRQs and Keyboard working? If not I suggest reading
Bkerndev tutorials and get them working atleast.
Since your OS seems to be in it's early stage I suggest you move to Long Mode (64-bit)
Post 16 Jan 2014, 07:35
View user's profile Send private message Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC 16 Jan 2014, 13:12
sid123: I don't think CJs OS exists at all. also, I agree with you on the Long Mode recommendation.

CJ: I highly recommend the long mode boot example written by Tomasz. it's on this page http://flatassembler.net/examples.php (entering long mode: http://flatassembler.net/examples/longmode.zip). it also proves how simple the legacy keyboard is to program. of course, it is written for entering Long Mode.

- Stefan.

_________________
byte me.
Post 16 Jan 2014, 13:12
View user's profile Send private message Visit poster's website Reply with quote
c.j.gowett



Joined: 31 Dec 2013
Posts: 12
c.j.gowett 16 Jan 2014, 20:07
The OS kind of exists and kind of doesn't. I have many different implementations of it and they're all scattered around. I'm working on a file system and other essentials to an operating system. I don't want to be one of those other sounding idiots that's simply begs. I am not trying to be that person, I just wanted to ask for help on something I am very enthusiastic on. I ask for help with purpose, mainly to want to help others with issues I was having. What I did was to get different components working so I know what works and what doesn't. The purpose was to avoid directly writing the operating system and run into a million problems to the point it becomes unbearable to program in because the code is a mess.

I will try 64-bit mode and look at the hard disk controller implementation that BAiC posted. Is using a flash drive a different controller because it is a different component of the machine?
Post 16 Jan 2014, 20:07
View user's profile Send private message Reply with quote
BAiC



Joined: 22 Mar 2011
Posts: 272
Location: California
BAiC 17 Jan 2014, 08:09
Quote:
Is using a flash drive a different controller because it is a different component of the machine?

you'll need a USB stack to get any serious use out of a flash drive. floppy emulators are sketchy.

_________________
byte me.
Post 17 Jan 2014, 08:09
View user's profile Send private message Visit poster's website Reply with quote
sid123



Joined: 30 Jul 2013
Posts: 339
Location: Asia, Singapore
sid123 17 Jan 2014, 12:56
I think all of your problems called be solved by looking at a BIOS's source code like SeaBIOS, you can convert them to work under 32-bit/64 bit, BIOS's have USB drivers, (that's how I think PS/2 and floppy
emulation is possible), Disk Drivers, Keyboard Drivers, PCI etc.
Post 17 Jan 2014, 12:56
View user's profile Send private message Reply with quote
c.j.gowett



Joined: 31 Dec 2013
Posts: 12
c.j.gowett 18 Jan 2014, 22:52
Ok, thank you Very Happy If I have any more questions, I will post them here. have a nice day Smile
Post 18 Jan 2014, 22:52
View user's profile Send private message Reply with quote
c.j.gowett



Joined: 31 Dec 2013
Posts: 12
c.j.gowett 11 Mar 2014, 03:22
I decided for now I am developing in 16-bit real mode. I think I should learn the basics before I try to jump into anything big. Probably the best thing for now.
Post 11 Mar 2014, 03:22
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.