硬盘IDE(integrate device electronics)的读取方式一chs (柱面,磁头,扇区)二:LBA(logicblockaddress)它是为了适应硬盘容量的快速生成出现的;
下面介绍在LBA的模式下的PIO(program IO)来实现对磁盘的读取操作;
主板有两个iDE通道,每个通道可挂载两个硬盘:访问第一个通道的第一个硬盘的扇区使用IO地址寄存器(0x1f0,0x1f1,0x1f2,0x1f3,0x1f4,0x1f5,0x1f6,0x1f7);访问第二个通道的硬盘的扇区使用的是(0x170-0x17f);
具体选取通道的主从硬盘由IO的第六个寄存器来决定!
0x1f0 :读数据,当0x1f7不为忙状态时,可以读!
0x1f2 :每次读扇区的数目(最小是1);
0x1f3 :如果是LBA模式就是了LBA参数的0-7位(相当于扇区)
0x1f4 :如果是LBA模式就是了LBA参数的8-15位(相当于柱面)
0x1f5 :如果是LBA模式就是了LBA参数的16-23位(相当于柱面)
0x1f6 :(第七位必须1,第六位1为LBA模式0为chs模式,第五位必须1,第四位是0为主盘1为从盘,3-0位是LBA的参数27-24位)
0x1f7 :状态命令寄存器,操作时先给命令,在读取,如果不是忙状态的话就从0x1f0读取数据
#include"x86.h"
#include"type.h"
#incude"elf.h"
#define CRTPORT 0x3d4
#define LPTPORT 0x378
#define BACKSPACE 0x100
#define SECTSIZE 512
static ushort *crt = (ushort*)0xb8000;
void readseg(uint ,uint ,uint);
bootmain(void)
{
int pos;
struct elfhdr*elf;
struct prohdr*ph,eph;
void (*entry)();
outb(CRTPORT, 14);
pos = inb(CRTPORT+1) << 8;
outb(CRTPORT, 15);
pos |= inb(CRTPORT+1);
crt[pos++] = ('A'&0xff) | 0x0700;
elf=(struct*elfhdr)0x10000;
readseg((uint)elf,8*SECTSIZE,0);
if(elf->magic!=elf_MAGIC)
goto bad;
ph=(struct proghdr*)((uchar*)ph+ph->offset);
for(ph=;ph<eph;ph++)
readsect(ph->va,ph->memsz,ph->offset);
entry=
entry();
wait();
outb(0x1f2,1);
outb(0x1f3,offset);
outb(0x1f4,offset>>8);
outb(0x1f5,offset>>16);
outb(0x1f6,offset>>24);
outb(0x1f7,0x20);
wait()
insb(0x1f0,,);
}