The IDE/ATA Interface How can our mini-Operating System, executing in protected mode, access the hard disk? The EDD services • So far we have relied upon the Extended Disk Drive service-functions (available in real-mode via ‘int $0x13’) to perform any transfers of data between main memory and our computer system’s hard disk • But these service-functions in ROM-BIOS are designed to be executed in real-mode • Can we achieve their effects when PE=1? Persistent data storage • Any operating system we might design, no matter how minimal, would need to offer a way to write and to read ‘persistent data’, organized into some kind of ‘file system’ that is maintained on a secondary storage device, such as a hard disk or a diskette Hardware interfacing • Modern computer platforms are expected to provide a specially designed peripheral processor, the hard disk controller, which can be programmed by system software to carry out data-transfers between a disk and the computer’s primary memory • The programming interface for hard disk controllers continues to evolve, but a stable set of standard capabilities exists 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) • In your early experiments you will need to use great caution to avoid corrupting vital areas of these shared hard disks! 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 Platform-specific parameters • Although older PCs used some standard I/O port-addresses for communicating with their Disk Controllers, newer PCs like ours allow these port-addresses to be assigned dynamically during the system’s startup • To keep our demonstration-code as short and uncluttered as possible, we will ‘hardcode’ the port-numbers our machines use 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 • Older PCs had standard i/o port-numbers for communicating with the Disk Controller • But newer PCs assign these dynamically 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 Bus Master DMA • When reading… – Primary DMA Control – Primary DMA Status – Primary PRD Pointer • When writing… – Primary DMA Control – Primary DMA Status – Primary PRD Pointer INTEL ICH6 I/O Controller Hub Datasheet SATA Controller Registers Two I/O design-paradigms • PIO: Programmed I/O for ‘reading’ – The cpu outputs parameters to the controller – The cpu waits till the data becomes available – The cpu transfers the data into main memory • DMA: Direct Memory Access for ‘reading’ – The cpu outputs parameters to the controller – The cpu activates the DMA engine to begin – The cpu deactivates the DMA engine to end PIO 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 PIO 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 for you to transfer it into memory • Use a loop to input 256 words (one sector) from the Command Block’s Data register PIO overview (conclusion) • After you have transferred a sector, check the Controller Status to see if there were any errors (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 (cmd+7) 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 (cmd+6) 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 (cmd+1) 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 (ctl+2) 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 PIO demo: ‘ideload1.s’ • We have created a substitute boot-loader which implements the same functionality as our previous ‘quickload.s’ program • Its purpose is two-fold: – It shows how to read 16 disk sectors with PIO – It could easily be rewritten to be executed in protected-mode by an operating system Advantage of DMA • For a multiprogramming operating system that employs ‘timesharing’ to concurrently execute multiple tasks, there is an obvious advantage in ‘offloading’ the data-transfer step to a peripheral processor • It frees the CPU to do work on other tasks during the time-interval when the data is actually being transferred DMA Command register 7 6 5 4 3 2 1 0 0 0 0 0 Read/ Write 0 0 Start /Stop Legend: Start/Stop: 1 = Start DMA transfer; 0 = Stop DMA transfer Read/Write: 1 = Read to memory; 0 = Write from memory DMA Status register 7 6 5 4 3 2 1 0 PRDIS - - 0 0 INT ERR ACT Legend: ACT (DMA engine is currectly Active): 1 = yes; 0 = no ERR (The controller encountered an Error): 1=yes; 0=no INT (The controller generated an Interrupt: 1=yes; 0=no PRDIS: (PRD Interrupt Status): 1=active, 0=inactive Software clears these labeled bits by writing 1’s to them PRD Pointer register 31 0 Physical memory-address of the PRD Table (must be quadword aligned) Each PRD (Physical Region Descriptor) consists of these three fields: Base-address of the physical region E O T Reserved (0) Size of the region bytes 3..0 bytes 7..4 NOTE: The total size of the PRD Table cannot exceed 64KB DMA 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 • NOTE: This step is the same as for PIO DMA overview (continued) • Engage the DMA engine for writing to memory by outputting 0x08 to the DMA Command Port • Clear the labeled bits in the DMA Status register • Place the command’s parameters into the appropriate IDE Command Block registers • Put command-code in IDE Command register • Activate the DMA data-transfer by outputting 0x09 to the DMA Command register • Then wait until the DMA Status register indicates that the DMA data-transfer has been completed DMA algorithm (concluded) • Turn off the DMA engine by writing 0x08 to the DMA Command register (to clear ACT) • Clear the labeled bits in the DMA Status register (by writing ‘1’s to those bits) • Read the IDE Status register (to clear any interrupt from the IDE Controller), and if bit 0 is set (indicating some error-information is available), then read IDE Error register DMA demo: ‘ideload2.s’ • We also created a substitute boot-loader which implements the same functionality as our previous ‘quickload.s’ program, but uses DMA instead of PIO • Its purpose is two-fold: – It shows how to read 16 disk sectors via DMA – It could easily be rewritten to be executed in protected-mode by an operating system In-class exercise • Choose one of these demo-programs and use the ideas it contains to perform a disk read operation while in protected-mode • For example, write a program that reads the hard disk’s Master Boot Record (i.e., sector 0) and display its Partition Table