In CPU interpretation 1, we mentioned that one of the main functions of CPU is to control data interaction between devices. This naturally includes hard disks. All the data in the system is basically in the hard disk, so it is very important for the program to know how to read and write the hard disk, so let's first explore the legendary Pio mode.
To directly access data on a device, the CPU must address the device's storage space. The hard disk data is too big, and the cost of directly addressing the data line is too high. Therefore, a controller is designed to be added between this type of equipment and the bus. This controller has a small number of registers that can be accessed by the CPU, and this controller can control the hard drive to read and write data, so, the CPU reads and writes the entire hard disk by reading and writing a few Io registers in the hard disk controller. The CPU tells the disk controller which address to read the data. After reading the data, the disk controller puts it into the data register that can be accessed by the CPU and then transmits the data to the memory. This is indeed a good method.
First, we first find the distribution of the hard disk controller I/O port address, 0x170-0x177 IDE hard disk controller 1
0x1f0-0x1f7 IDE hard disk controller 0. The details are as follows:
Port Number read or write specific meaning
1 f0h read/write is used to transmit read/write data (the content is a byte of data being transferred)
1f1h read is used to read error codes
1f2h read/write: number of sectors to be read/written
1f3h
1f4h read/write is used to store the low 8-bit bytes of the read/write cylindrical disk.
1f5h read/write is used to store the high 2-bit bytes of the read/write cylindrical disk (the High 6-bit constant is 0)
1 f6h read/write is used to store the disk number and head number to be read/written.
7th-bit constant is 1
The 6th-bit constant is 0.
5th-bit constant is 1
0 represents the first hard disk. 1 represents the second hard disk.
3rd ~ 0 bits are used to store the head number to read/write
1f7h read is used to store the status after the read operation
7th-bit controller busy
6th-bit disk drive ready
5th-bit write error
The 4th-bit search is complete.
When the 3rd-bit value is 1, the slice buffer is not ready.
Whether the 2nd-bit disk data is correctly read
For a 1st-bit disk, set this field to 1 every week after conversion,
The command before 0th bits ends due to an error
Write this port as the command port to issue the specified command
Format the track for 50 h
Try to read the sector for 20 h
For 21 h, you do not need to verify whether the sector is ready and directly read the sector
For 22 h, try to read the long fan area (for the early hard disk, each fan may not be 512 bytes, but the value between 128 bytes and 1024)
For 23 h, you can directly read the long fan area without verifying whether the slice is ready.
Try to write a sector for 30 h
Write the sector directly for 31 h without verifying whether the sector is ready
Try to write a long fan area for 32 h
Write the long fan area directly for 33 H without verifying whether the slice is ready
Of course, after reading this table, you will find that this read/write port method is actually based on the hard disk read/write method of the head, cylinder, and sector, that is to say, you want to tell the hard disk controller which sector under which head of the hard disk is to be read, and then issue the READ command. The hard disk controller caches the content of the sector, then, the 16-bit data is put into a register (1f0h) in sequence, and the CPU can read the data through the IO command.
Let's look at another sample code:
MoV dx, 1f6h; disk number and head number to be read
MoV Al, 0a0h; disk 0, head 0
Out dx, Al
MoV dx, 1f2h; number of sectors to be read
MoV Al, 1; read a sector
Out dx, Al
MoV dx, 1f3h; fan ID to be read
MoV Al, 1; sector number 1
Out dx, Al
MoV dx, 1f4h; low 8 bits of the cylinder to be read
MoV Al, 0; cylindrical low 8 bit is 0
Out dx, Al
MoV dx, 1f5h; cylinder height 2 bits
MoV Al, 0; the cylinder height is 0 (through 1f4h and 1f5h ports, we can determine
; The number of the cylinder used for reading is 0)
Out dx, Al
MoV dx, 1f7h; command port
MoV Al, 20 h; try to read the sector
Out dx, Al
Still_going:
In Al, DX
Test Al, 8; is the slice buffer ready?
JZ still_going; if the slice buffer is not ready, it is redirected until it is ready.
MoV CX, 512/2; set the number of cycles (512/2 times)
MoV Di, offset Buffer
MoV dx, 1f0h; the data of one byte to be transmitted
Rep insw; transmit data
Have a sense of accomplishment. Everything is under control. In fact, we can directly call the INT 13 H interrupt in the BIOS to directly read and write the sector, but through the lower-layer code, we can have a deeper understanding of the computer architecture. Know how the CPU interacts with other devices.
Note the preceding command rep insw. Here we will explain it. The INS command can input a byte or word from the peripheral port indicated by dx to the memory specified by ES: Di. The input byte or word is determined by the attributes of the ES: di target operand, And the di value is modified based on the attributes of the Direction Flag DF and the target operand: If (DF) = 0, then di adds 1 (or 2); otherwise di minus 1 (or 2 ). Similar to INS commands, InSb and insw commands also input a byte or word from the peripheral port indicated by dx to the memory specified by ES: Di, the DI value is modified based on the type of the forward flag DF and string operation. Commands in the preceding three formats can be prefixed with rep to achieve continuous string operations.
. In this case, the content in the Cx register is the number of repeated operations.
Here we can see that the CPU reads the hard disk data not into the CPU, but into the memory, probably because there is no such space in the CPU to store the data in the hard disk, therefore, in the instruction design, it is directly placed in the memory, and considering the bandwidth limit, the disk's smallest data unit-sector must be divided into multiple times before it can be read into the memory, therefore, we designed commands like rep insw to improve efficiency. Each time the disk controller extracts one character long data from the data buffer of the sector and puts it into 1f0h (also known as the PIO data port) for the insw command to obtain it. It executes insw cyclically until the entire buffer zone is read.