自制操作系统Antz day04——进入保护模式 (下) 实现内核并从硬盘载入 (3)

  LBA寄存器有LBA low,LBA mid,LBA high三个,它们三个都是8位,LBA  low寄存器用来存储28位地址的第0~7位,LBA mid用来存储28位的第8~15位,LBA high寄存器用来存储28位的第16~23位。那么剩下的四位呢? 这就是device寄存器的任务了。

  device寄存器是个杂项,它的宽度是八位,第四位是存储LBA的第24位~27位。结合上面的三个LBA寄存器,第四位用来指定通道上的主盘或从盘,0代表从,1代表主。第六位用来存储是否启用LBA方式,1代表LBA模式,0代表CHS模式。另外两位第五位和第七位是固定为1的,称为MBS位,可以不用注意。

  读硬盘时,端口0x1F7或0x177的寄存器叫Status,它是8位宽度的寄存器,用来给出硬盘的状态信息。第0位是ERR位,如果此位为1,表示命令出错了,具体原因可见Error寄存器。第三位data request位,如果此位为1,表示数据已经准备好了。第6位为DRDY,表示硬盘就绪。第七位是BSY位,表示硬盘是否繁忙。

  写硬盘时,端口0x1F7或0x177的寄存器叫Command,它和Status是同一个,此寄存器用来存储让硬盘执行的命令,把命令写入此寄存器,只要把命令写入此寄存器,硬盘就开始工作了。主要是以下三个命令:

    1)identify : 0xEC    硬盘识别

    2)read sector : 0x20   即读扇区

    3)  write sector : 0x30   即写扇区

自制操作系统Antz day04——进入保护模式 (下) 实现内核并从硬盘载入

 

 

2. 控制硬盘步骤

  有的指令直接往command寄存器中写就可以了,有的还需要feature寄存器中写入参数。最主要的就是command寄存器一定要最后写,因为一旦command寄存器被写入后,硬盘就开始干活了。关于操作步骤如下:

  1)先选择通道,往该通道的sector count寄存器中写入带操作的扇区数。

  2)往该通道上的三个LBA寄存器写入扇区起始地址的低24位。

  3)往device寄存器中写入LBA地址的24~27位,并置第六位为1,使其为LBA模式,设置第4位,选择操作的硬盘(主从)。

  4)往该通道上的额command寄存器中写入操作命令。

  5)读取该通道上的status寄存器,判断硬盘工作是否完成

  6)如果以上步骤是读硬盘,进入下一个步骤。否则,完工

  7)将硬盘数据读出

3. 使用硬盘

  MBR即将改造成可以读取硬盘,那么我们的内核加载就有了方法。所以我们要学会从另一个程序中完成初始化环境并加载内核,这个程序叫做loader,loader放在第二个扇区,地址之前已经讲过了0x500~0x7BFF区域中。

1 %include "boot.inc" 2 SECTION MBR vstart=0x7c00 3 mov ax,cs 4 mov ds,ax 5 mov es,ax 6 mov ss,ax 7 mov fs,ax 8 mov sp,0x7c00 9 mov ax,0xb800 10 mov gs,ax 11 12 mov ax,0x600 13 mov bx,0x700 14 mov cx,0 15 mov dx,0x1010 16 int 0x10 17 18 mov byte [gs:0x00],'A' 19 mov byte [gs:0x01],0xA4 20 21 mov byte [gs:0x02],'n' 22 mov byte [gs:0x03],0x13 23 24 mov byte [gs:0x04],'t' 25 mov byte [gs:0x05],0x52 26 27 mov byte [gs:0x06],'z' 28 mov byte [gs:0x07],0xB1 29 30 mov byte [gs:0x08],' ' 31 mov byte [gs:0x09],0xCC 32 33 mov byte [gs:0x0A],'U' 34 mov byte [gs:0x0B],0x2B 35 36 mov byte [gs:0x0C],'h' 37 mov byte [gs:0x0D],0x6D 38 39 mov byte [gs:0x0E],'l' 40 mov byte [gs:0x0F],0x7E 41 42 mov byte [gs:0x10],' ' 43 mov byte [gs:0x11],0x49 44 45 mov byte [gs:0x12],'K' 46 mov byte [gs:0x13],0xE5 47 48 mov byte [gs:0x14],'o' 49 mov byte [gs:0x15],0x8A 50 51 mov byte [gs:0x16],'n' 52 mov byte [gs:0x17],0x96 53 54 mov byte [gs:0x18],'e' 55 mov byte [gs:0x19],0x68 56 57 mov eax,LOADER_START_SECTOR 58 mov bx,LOADER_BASE_ADDR 59 mov cx,1 60 call rd_disk_m_16 61 62 jmp LOADER_BASE_ADDR 63 64 rd_disk_m_16: 65 66 mov esi,eax 67 mov di,cx 68 mov dx,0x1f2 69 mov al,cl 70 out dx,al 71 72 mov eax,esi 73 74 mov dx,0x1f3 75 out dx,al 76 77 mov cl,8 78 shr eax,cl 79 mov dx,0x1f4 80 out dx,al 81 82 shr eax,cl 83 mov dx,0x1f5 84 out dx,al 85 86 shr eax,cl 87 and al,0x0f 88 or al,0xe0 89 mov dx,0x1f6 90 out dx,al 91 92 mov dx,0x1f7 93 mov al,0x20 94 out dx,al 95 96 not_ready: 97 nop 98 in al,dx 99 and al,0x88 100 101 cmp al,0x08 102 jnz not_ready 103 104 mov ax,di 105 mov dx,256 106 mul dx 107 mov cx,ax 108 109 mov dx,0x1f0 110 111 go_on_read: 112 in ax,dx 113 mov [bx],ax 114 add bx,2 115 loop go_on_read 116 ret 117 118 times 510-($-$$) db 0 119 db 0x55,0xaa

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyyxf.html