操作系统的引导 boot.asm
2017-09-05 19:02 仁者无敌68 阅读(385) 评论(0) 收藏 举报.model tiny ;小内存模式 .386p ;支持386指令 .code ;代码段 start: ;下面的跳转指令主要作用是把cs设置为0x07c0 db 0eah dw go dw 7c0h ;软盘固定参数 bpbOEM db "My OS " bpbBytesPerSector DW 512 bpbSectorsPerCluster DB 1 bpbReservedSectors DW 1 bpbNumberOfFATs DB 2 bpbRootEntries DW 224 bpbTotalSectors DW 2880 bpbMedia DB 0f0h ;; 0xF1 bpbSectorsPerFAT DW 9 bpbSectorsPerTrack DW 18 bpbHeadsPerCylinder DW 2 bpbHiddenSectors DD 0 bpbTotalSectorsBig DD 0 bsDriveNumber DB 0 bsUnused DB 0 bsExtBootSignature DB 029h bsSerialNumber DD 0a0a1a2a3h bsVolumeLabel DB "MOS FLOPPY ",0 bsFileSystem DB "FAT12 ",0 go: mov ax,06000h mov sp,ax ;设置堆栈 mov ax,900h ;读取根目录到9000h位置 mov es,ax xor bx,bx ;第19扇区存储了根目录 mov ch,0 ;柱面 mov dh,1 ;头 mov cl,2 ;扇区 mov ah,2 ;功能2,读磁盘 mov al,14 ;读取扇区数目,根目录大小为14个扇区,这是固定值 mov dl,0 ;从软盘读取 int 13h mov ax,0b80h mov es,ax xor bx,bx mov ch,0 mov dh,0 mov cl,2 ;从第2扇区读,fat起始扇区 mov ah,2 mov al,9 ;总共读9个扇区,整个fat表 mov dl,0 int 13h ; 解压FAT mov ax,0b80h mov ds,ax mov ax,0ca0h mov es,ax mov di,0;buffer mov si,0;fatstart mov cx,3*512 de_fat: xor ax,ax mov al,byte ptr [si] mov ah,byte ptr [si+1] and ah,0fh stosw xor ax,ax mov ax,WORD ptr [si+1] shr ax,1 shr ax,1 shr ax,1 shr ax,1 and ah,0fh stosw add si,3 loop de_fat ;在根目录中查找文件 mov ax,07c0h mov ds,ax mov es,ax mov dx,9000h-7c00h findfile: mov di,dx cld mov cx,11 lea si,kn repz cmpsb jz L1 ;找到了文件 jnz L2 ;没找到,继续 L1: ;加载文件,33扇区为数据起始扇区,1扇区启动分区,18扇区fat表,14扇区根目录 add dx,1ah ; 1a处存放了起始簇 mov si,dx mov ax,07c0h mov ds,ax mov es,ax mov ax, WORD ptr [si] ;取文件第一簇 push ax ;然后读文件内容 ;数据起始地址是4200h,对应第2簇,所以第0簇应该是,4200h-400h =3e00h,扇区为3e00h/200h = 31 ;打算加载到0x90000,512K这个地方,内核还剩余512K-32K = 480K mov WORD ptr [buffer],9000h call readsector add WORD ptr [buffer],20h ;读完了第一簇 ;每次读完,di自动加200h ;读簇内容 pop si ;mov si,WORD ptr cu read_cu: shl si,1 mov ax,0ca0h mov ds,ax mov ax,WORD ptr [si] push ax cmp ax,0fffh je load_ok ;读取ax为起始扇区的内容 call readsector pop si add WORD ptr [buffer],20h jmp read_cu load_ok: mov ax,13h int 10h db 0eah dw 0 dw 9000h jmp $ L2: add dx,32 cmp dx,14*512 jb findfile load_failure: jmp $ ;函数功能,读指定扇区内容到指定内存 ;逻辑扇区和CHS的转换关系 ; C = ( 19 / 18 ) / 2 = 0;柱面 ; H = ( 19 / 18 ) % 2 = 1 ;磁头 ; S = ( 19 % 18 ) + 1 = 2;扇区 readsector: pusha add ax,31 mov WORD ptr ds:[log_sec],ax mov bx,36 xor dx,dx div bx mov BYTE ptr [cyl],al mov ax,WORD ptr [log_sec] mov bx,18 xor dx,dx div bx xor dx,dx mov bx,2 div bx mov BYTE ptr [head],dl mov ax,WORD ptr [log_sec] mov bx,18 xor dx,dx div bx inc dl mov BYTE ptr [sec],dl mov ax,WORD ptr [buffer] mov es,ax xor bx,bx mov ch,BYTE ptr [cyl] ;c mov dh,BYTE ptr [head] ;h mov cl,BYTE ptr [sec] ;s mov ah,2 ;function :read mov al,1 ;sector to read mov dl,0 ; 软驱a int 13h popa ret DispStr: mov ax,BootMsg mov bp,ax mov cx,end_BootMsg-BootMsg mov ax,01301h mov bx,000ch mov dl,0 int 10h ret BootMsg: db "can't find kernel",0 end_BootMsg: buffer: dw 0 log_sec: dw 0 cyl: db 0 head: db 0 sec: db 0 kn: db 'SETUP EXE',0 org 510 dw 0aa55h end start
此文件加载了根木目到0x9000,此后setup可以在根目录中查找kernel文件,并加载内核
浙公网安备 33010602011771号