OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Sep 20, 2019 5:15 am

All times are UTC - 6 hours




Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: How to w/r harddisk in pmode?
PostPosted: Thu Nov 23, 2006 7:00 pm 
Offline

Joined: Thu Nov 23, 2006 9:48 am
Posts: 3
Location: China
In real mode I can use int 13h to read harddisk.But in pmode,I can't use it any more,neither do I want to use it.

I have noticed the code in Linux 0.01 , they use in,out command to read sectors.
My question is : Without any initialization can I use in,out to access harddisk? Must I write PCI driver first ?Is it hard? Thanks~

Suppose I am using IDE diskdriver.

_________________
Enjoy Life~


Top
 Profile  
 
 Post subject: Re: How to w/r harddisk in pmode?
PostPosted: Thu Nov 23, 2006 9:52 pm 
Offline
Member
Member
User avatar

Joined: Fri Jan 27, 2006 12:00 am
Posts: 1444
raywill wrote:
In real mode I can use int 13h to read harddisk.But in pmode,I can't use it any more,neither do I want to use it.

I have noticed the code in Linux 0.01 , they use in,out command to read sectors.
My question is : Without any initialization can I use in,out to access harddisk? Must I write PCI driver first ?Is it hard? Thanks~

Suppose I am using IDE diskdriver.

To read/write to hdd is very easy, but it's the fat that will take more time, to get right.
Code:
;       Reading the harddisk using ports!
;       +-------------------------------+   by qark
;
;
;  This took me months to get working but I finally managed it.
;
;  This code only works for the 286+ so you must detect for 8088's somewhere
;  in your code.
;
;  Technical Information on the ports:
;      Port    Read/Write   Misc
;     ------  ------------ -------------------------------------------------
;       1f0       r/w       data register, the bytes are written/read here
;       1f1       r         error register  (look these values up yourself)
;       1f2       r/w       sector count, how many sectors to read/write
;       1f3       r/w       sector number, the actual sector wanted
;       1f4       r/w       cylinder low, cylinders is 0-1024
;       1f5       r/w       cylinder high, this makes up the rest of the 1024
;       1f6       r/w       drive/head
;                              bit 7 = 1
;                              bit 6 = 0
;                              bit 5 = 1
;                              bit 4 = 0  drive 0 select
;                                    = 1  drive 1 select
;                              bit 3-0    head select bits
;       1f7       r         status register
;                              bit 7 = 1  controller is executing a command
;                              bit 6 = 1  drive is ready
;                              bit 5 = 1  write fault
;                              bit 4 = 1  seek complete
;                              bit 3 = 1  sector buffer requires servicing
;                              bit 2 = 1  disk data read corrected
;                              bit 1 = 1  index - set to 1 each revolution
;                              bit 0 = 1  previous command ended in an error
;       1f7       w         command register
;                            commands:
;                              50h format track
;                              20h read sectors with retry
;                              21h read sectors without retry
;                              22h read long with retry
;                              23h read long without retry
;                              30h write sectors with retry
;                              31h write sectors without retry
;                              32h write long with retry
;                              33h write long without retry
;
;  Most of these should work on even non-IDE hard disks.
;  This code is for reading, the code for writing is the next article.



   mov     dx,1f6h         ;Drive and head port
   mov     al,0a0h         ;Drive 0, head 0
   out     dx,al

   mov     dx,1f2h         ;Sector count port
   mov     al,1            ;Read one sector
   out     dx,al

   mov     dx,1f3h         ;Sector number port
   mov     al,1            ;Read sector one
   out     dx,al

   mov     dx,1f4h         ;Cylinder low port
   mov     al,0            ;Cylinder 0
   out     dx,al

   mov     dx,1f5h         ;Cylinder high port
   mov     al,0            ;The rest of the cylinder 0
   out     dx,al

   mov     dx,1f7h         ;Command port
   mov     al,20h          ;Read with retry.
   out     dx,al
still_going:
   in      al,dx
   test    al,8            ;This means the sector buffer requires
            ;servicing.
   jz      still_going     ;Don't continue until the sector buffer
            ;is ready.

   mov     cx,512/2        ;One sector /2
   mov     di,offset buffer
   mov     dx,1f0h         ;Data port - data comes in and out of here.
   rep     insw

;   ------

   mov     ax,201h         ;Read using int13h then compare buffers.
   mov     dx,80h
   mov     cx,1
   mov     bx,offset buffer2
   int     13h

   mov     cx,512
   mov     si,offset buffer
   mov     di,offset buffer2
   repe    cmpsb
   jne     failure
   mov     ah,9
   mov     dx,offset readmsg
   int     21h
   jmp     good_exit
failure:
   mov     ah,9
   mov     dx,offset failmsg
   int     21h
good_exit:
   mov     ax,4c00h        ;Exit the program
   int     21h

   readmsg db      'The buffers match.  Hard disk read using ports.$'
   failmsg db      'The buffers do not match.$'

buffer  db      512 dup ('V')
buffer2 db      512 dup ('L')




;
;       Writing to the hard disk using the ports!     by qark
;       +---------------------------------------+
;
;  The only differences between reading and writing using the ports is
;  that 30h is sent to the command register, and instead of INSW you
;  OUTSW. 
;


   mov     dx,1f6h         ;Drive and head port
   mov     al,0a0h         ;Drive 0, head 0
   out     dx,al

   mov     dx,1f2h         ;Sector count port
   mov     al,1            ;Write one sector
   out     dx,al

   mov     dx,1f3h         ;Sector number port
   mov     al,1           ;Wrote to sector one
   out     dx,al

   mov     dx,1f4h         ;Cylinder low port
   mov     al,0            ;Cylinder 0
   out     dx,al

   mov     dx,1f5h         ;Cylinder high port
   mov     al,0            ;The rest of the cylinder 0
   out     dx,al

   mov     dx,1f7h         ;Command port
   mov     al,30h          ;Write with retry.
   out     dx,al
oogle:
   in      al,dx
   test    al,8            ;Wait for sector buffer ready.
   jz      oogle

   mov     cx,512/2        ;One sector /2
   mov     si,offset buffer
   mov     dx,1f0h         ;Data port - data comes in and out of here.
   rep     outsw           ;Send it.

;    ------------

   mov     ax,201h                 ;We'll read in sector 1 using
   mov     bx,offset buffer2       ;int13h and see if we are successful.
   mov     cx,1
   mov     dx,80h
   int     13h

   mov     cx,512
   mov     si,offset buffer
   mov     di,offset buffer2
   repe    cmpsb                   ;Compare the buffers.
   jne     failure

   mov     ah,9
   mov     dx,offset write_msg
   int     21h
   jmp     w_exit
failure:
   mov     ah,9
   mov     dx,offset fail
   int     21h

w_exit:
   mov     ax,4c00h        ;Exit the program
   int     21h

   write_msg       db      'Sector one written to using the ports, OH NO! there goes XP.$'
   fail            db      'Writing using ports failed.$'

buffer  db      512 dup ('A')
buffer2 db      512 dup ('D')

NOTE: THE ABOVE CODE WILL OVER WRITE YOUR MBR, so do not run with above settings.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 23, 2006 10:00 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 20, 2004 12:00 am
Posts: 376
Location: Wellesley, Ontario, Canada
Also note that (I believe) most/all modern HD drivers utilize DMA, rather then direct port IO.

I have yet to write an HD driver for ndk, though, so I have no insight on how this is done.

--Jeff


Top
 Profile  
 
 Post subject: Re: How to w/r harddisk in pmode?
PostPosted: Thu Nov 23, 2006 10:47 pm 
Offline

Joined: Thu Nov 23, 2006 9:48 am
Posts: 3
Location: China
So,according to the code,I don't need to init PCI first?Why?

Then another question is : HOW does the computer do this? Who have helped us to map those I/O port?

Lots thanks,Dex!
Dex wrote:
raywill wrote:
In real mode I can use int 13h to read harddisk.But in pmode,I can't use it any more,neither do I want to use it.

I have noticed the code in Linux 0.01 , they use in,out command to read sectors.
My question is : Without any initialization can I use in,out to access harddisk? Must I write PCI driver first ?Is it hard? Thanks~

Suppose I am using IDE diskdriver.

To read/write to hdd is very easy, but it's the fat that will take more time, to get right.
Code:
;       Reading the harddisk using ports!
;       +-------------------------------+   by qark
;
;
;  This took me months to get working but I finally managed it.
;
;  This code only works for the 286+ so you must detect for 8088's somewhere
;  in your code.
;
;  Technical Information on the ports:
;      Port    Read/Write   Misc
;     ------  ------------ -------------------------------------------------
;       1f0       r/w       data register, the bytes are written/read here
;       1f1       r         error register  (look these values up yourself)
;       1f2       r/w       sector count, how many sectors to read/write
;       1f3       r/w       sector number, the actual sector wanted
;       1f4       r/w       cylinder low, cylinders is 0-1024
;       1f5       r/w       cylinder high, this makes up the rest of the 1024
;       1f6       r/w       drive/head
;                              bit 7 = 1
;                              bit 6 = 0
;                              bit 5 = 1
;                              bit 4 = 0  drive 0 select
;                                    = 1  drive 1 select
;                              bit 3-0    head select bits
;       1f7       r         status register
;                              bit 7 = 1  controller is executing a command
;                              bit 6 = 1  drive is ready
;                              bit 5 = 1  write fault
;                              bit 4 = 1  seek complete
;                              bit 3 = 1  sector buffer requires servicing
;                              bit 2 = 1  disk data read corrected
;                              bit 1 = 1  index - set to 1 each revolution
;                              bit 0 = 1  previous command ended in an error
;       1f7       w         command register
;                            commands:
;                              50h format track
;                              20h read sectors with retry
;                              21h read sectors without retry
;                              22h read long with retry
;                              23h read long without retry
;                              30h write sectors with retry
;                              31h write sectors without retry
;                              32h write long with retry
;                              33h write long without retry
;
;  Most of these should work on even non-IDE hard disks.
;  This code is for reading, the code for writing is the next article.



   mov     dx,1f6h         ;Drive and head port
   mov     al,0a0h         ;Drive 0, head 0
   out     dx,al

   mov     dx,1f2h         ;Sector count port
   mov     al,1            ;Read one sector
   out     dx,al

   mov     dx,1f3h         ;Sector number port
   mov     al,1            ;Read sector one
   out     dx,al

...

NOTE: THE ABOVE CODE WILL OVER WRITE YOUR MBR, so do not run with above settings.

_________________
Enjoy Life~


Top
 Profile  
 
 Post subject: Re: How to w/r harddisk in pmode?
PostPosted: Thu Nov 23, 2006 11:48 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

raywill wrote:
So,according to the code,I don't need to init PCI first?Why?


For backwards compatibility purposes, the ATA/IDE controller is pre-configured by the BIOS to look and behave like a standard ISA ATA/IDE controller.

Also note that due to a series of brain-dead hardware designers (who assume that if a design is good enough for the next 5 minutes it will be good enough for the next 10 years), there's several different ways of transferring data to/from the disks, and several different ways of telling the disk which sector/s you want to access, most of which may or may not be supported by the hardware itself. This is a little worse because the controller and the disk drives are seperate - a disk can support features that the controller doesn't support, and a controller can support features that the disk/s don't.

This means to support the fastest possible disk transfer speed and all possible disk sizes you need to detect what the disk and controller support and implement code for each possibility.

It's also probable worth looking through the public domain code written by Hale Landis (available from this web site). This code doesn't support some advanced features (SMART, NCQ, drive locking, etc), but these things are easy to live without....


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 24, 2006 2:33 pm 
Offline
Member
Member
User avatar

Joined: Fri Nov 04, 2005 12:00 am
Posts: 381
Location: Serbia
Well, you must write PCI detection driver if you want to have more ATA/ATAPI controllers or to use UltraDMA.

I suggest you to visit www.ata-atapi.com . There's a very nice source code for PATA/PATAPI/SATA/SATAPI with support for UltraDMA device driver!


Top
 Profile  
 
 Post subject: Re: How to w/r harddisk in pmode?
PostPosted: Sun May 22, 2011 3:44 am 
Offline
Member
Member
User avatar

Joined: Mon May 16, 2011 2:05 pm
Posts: 32
Location: hanoi
great and neat code, Dex,
but is it possible to read/write more than 255 sectors?

as i see in your code AL is a byte value:
Code:
mov    dx,1f2h         ;Sector count port
mov    al,1            ;Read one sector
out    dx,al

_________________
I'm using AMD Sempron 140 Single core 2.7GHz


Top
 Profile  
 
 Post subject: Re: How to w/r harddisk in pmode?
PostPosted: Sun May 22, 2011 8:54 am 
Offline
Member
Member

Joined: Wed Oct 18, 2006 10:43 pm
Posts: 490
Location: Kansas City, KS, USA
Did you really need to bump a 5 year old thread?

To answer your question, try reading the specs. They're easy to find and explain everything you need to know. It's about time you do your own homework for once.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 9 guests


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 post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group