The ATA/IDE Interface Can we write a character-mode

advertisement
The ATA/IDE Interface
Can we write a character-mode
device driver for the hard disk?
Persistent data storage
• Our ‘dram.c’ module implemented a Linux
driver for the processor’s physical memory
• That primary storage was ‘volatile’ – all its
data disappears when power is turned off
• But secondary storage, provided by disks,
is ‘persistent’ – the data is preserved even
when the power supply gets interrupted
Hardware interfacing
• To gain experience with writing drivers for
actual hardware, we propose to construct
a character-mode device driver, similar to
our ‘dram.c’ module, which will allow us to
read and write to a portion of the hard disk
• This will acquaint us – at an elementary
level -- with many of the key issues that
hardware interfacing typically involves
A few cautions
• Our classroom and laboratory computers
are shared by many users who are taking
various computer sciences courses
• Writing to the hard disk in a careless way
can do damage to the operating systems
(making a machine completely unusable)
• Our first job will be to discover what areas
on our hard disk can be safely modified
Fixed-Size ‘blocks’
• All data-transfers to and from the hard disk
are comprised of fixed-size blocks called
‘sectors’ (whose size equals 512 bytes)
• On modern hard disks, these sectors are
identified by sector-numbers starting at 0
• This scheme for addressing disk sectors is
known as Logical Block Addressing (LBA)
• So the hard disk is just an array of sectors
Visualizing the hard disk
A large array of 512-byte disk sectors
0 1 2 3 …..
Disk storage-capacity (in bytes) = (total number of sectors) x (512 bytes/sector)
Disk Partitions
• The total storage-area of the hard disk is
usually subdivided into non-overlapping
regions called ‘disk partitions’
Partition #1
Partition #2
Partition #3
unused
Master Boot Record
• A small area at the beginning of the disk is
dedicated to ‘managing’ the disk partitions
0
1
2
…
MBR
partition #1
• In particular, sector number 0 is known as
the Master Boot Record (very important!)
Format of the MBR
• The MBR is subdivided into three areas:
– The bootstrap loader program
– The ‘partition table’ data-structure
– The MBR signature (i.e., 0x55, 0xAA)
512
bytes
Bootstrap Loader
(446 bytes)
Partition Table (64 bytes)
signature (2 bytes)
‘Safe’ areas
• If our hard disk contains ‘unused’ sectors,
then we could safely modify their contents
• Or if our hard disk contains a partition that
nobody currently uses, then we could just
take over its sectors for our own purposes
-- at least during this current semester
• So we need to look at the ‘partition table’
to find out if any ‘safe areas’ are available
‘Reading’ the MBR
• To get the hard disk’s Partition Table, we
must ‘read’ the entire Master Boot Record
• (We ignore the boot-loader and signature)
• But we will need to understand the format
of the data stored in that Partition Table
• And we will need to know how to devise a
privileged code-fragment that can transfer
the MBR (sector 0) from disk to memory
Partition Table Entries
• The MBR is an array containing four datastructures (called ‘partition table entries’):
16
bytes
S
T
A
T
U
S
T
Y
P
E
Starting sector
ID-number
Partition length
(in sectors)
Some fields contain ‘obsolete’ information
TYPE-ID
• Each partition-table entry has a TYPE-ID
– TYPE-ID is 0x07 for a ‘Windows’ partition
– TYPE-ID is 0x83 for our ‘Linux’ partition
– TYPE-ID is 0x00 when the entry is ‘unused’
• You can find a list of TYPE-ID numbers
posted on the internet (see our website)
• Our hard disks have a ‘Minix’ partition that
nobody is using during Spring semester
How can we read the MBR?
• Our device-driver must send a command
to the Hard Disk Controller, together with
command-parameters that specify which
disk sector we want to read (i.e., sector 0)
• But we can’t issue a fresh command if the
controller is still busy processing an earlier
command (e.g., issued by the OS kernel)
• So we also need to get controller ‘status’
The ATA/IDE Interface
• All communication between our driver and
the Hard Disk Controller is performed with
‘in’ and ‘out’ instructions that refer to ports
• PCs have standard i/o port-numbers for
communicating with the Disk Controller
• Altogether twelve registers are involved,
using nine different I/O Port-Numbers
Command Block registers
• When reading…
–
–
–
–
–
–
–
–
Data
Error
Sector Count
LBA Low
LBA Mid
LBA High
Device
Status
• When writing…
–
–
–
–
–
–
–
–
Data
Features
Sector Count
LBA Low
LBA Mid
LBA High
Device
Command
Control Block Registers
• When reading…
• When writing…
– Alternate Status
– Device Control
INCRITS
InterNational Committee on Information Technology Standards
Committee T-13
Algorithm overview
• First select the device to read from:
– Wait until the controller is not busy and does
not have any data that it wants to transfer
– Write to Command Block’s Device register to
select the disk to send the command to
– Wait until the controller indicates that it is
ready to receive your new command
Overview (continued)
• Place the command’s parameters into the
appropriate Command Block registers
• Put command-code in Command register
• Then wait until the controller indicates that
it has read the requested sector’s data and
is ready to transfer it to your device driver
• Use a loop to input 256 words (one sector)
from the Command Block’s Data register
Overview (conclusion)
• After your driver has transferred a sector,
check the Controller Status to see if there
was any error (if so read the Error register)
• To implement this algorithm, we need to
look at the meaning of some individual bits
in the Status register (and Error register)
Status register (port 0x1F7)
7
6
5
BSY
DRDY
DF
4
3
DRQ
2
1
0
ERR
Legend:
BSY (Device still Busy with prior command): 1=yes, 0=no
DRDY (Device is Ready for a new command): 1=yes, 0=no
DF (Device Fault – command cannot finish): 1=yes, 0=no
DRQ (Data-transfer is currently Requested): 1=yes, 0=no
ERR (Error information is in Error Register): 1 = yes, 0=no
Device register (0x1F6)
7
6
5
4
1
LBA
(=1)
1
DEV
(0/1)
3
2
1
0
Sector-ID[ 27..24 ]
Legend:
LBA (Logical Block Addressing): 1=yes, 0=no
DEV (Device selection): 1=slave, 0=master
Sector-ID: Most significant 4-bits of 28-bit Sector-Address
Error register (0x1F1)
7
6
5
4
3
2
1
UNC
MC
IDNF
MCR
ABRT
NM
Legend:
UNC (Data error was UnCorrectable): 1=yes, 0=no
MC (Media was Changed): 1=yes, 0=no
IDNF (ID Not Found): 1=yes, 0=no
MCR (Media Change was Requested): 1=yes, 0=no
ABRT (Command was Aborted): 1 = yes, 0=no
NM (No Media was present): 1=yes, 0=no
0
Device Control register (0x3F6)
7
6
5
4
3
2
1
0
HOB
0
0
0
0
SRST
nIEN
0
Legend:
HOB (High-Order Byte): 1=yes, 0=no
SRST (Software Reset requested): 1=yes, 0=no
nIEN (negate Interrupt Enabled): 1=yes, 0=no
NOTE: The HOB-bit is unimplemented on our machines; it is
for large-capacity disks that require 44-bit sector-addresses
Demo module: ‘mbr.c’
• We have created a miniature device-driver
which implements read-only access to our
hard disk’s Master Boot Record (sector 0)
• Its purpose is two-fold:
– It shows how you can read a disk sector
– It lets you find out where the ‘minix’ partition
begins and ends on our disk (the ‘safe’ area)
In-Class Exercise
• Compile and install the ‘mbr.c’ driver
• Then write an application program that a
user can execute to open the ‘/dev/hd’
device-file, seek to the proper offset, read
the 64-byte Partition Table data-structure,
and display its four Partition Table Entries
on the screen (in hexadecimal format)
• Identify the TYPE-ID of each partition, and
see where the ‘minix’ area starts and ends
Download