📄 boot.asm
字号:
;
; boot.asm
;
; All rights reserved
;
; MPL--mmmmpl@126.com
; 2007.9.21
;
; Compile with nasm, write to first sector of a floppy for boot
; a PC,and you can see tip message..., have fun.
;
[org 7c00h]
; ---------------------------------------------------------------
; disk description
jmp short start ; 3 bytes to e.g. jump
nop
db "MMMMBoot" ; 8 byte label / OemId
dw 512 ; bytes per sector
db 1 ; sectors per cluster
dw 1 ; size of the bootloader, in sectors
db 2 ; number of copies of the FAT
dw 224 ; number of entries in Root-Dir
dw 2880 ; 16-bit number of sectors
db 0xf0 ; media descriptor
dw 9 ; number of sectors per FAT
dw 18 ; sectors per track
dw 2 ; number of heads
dd 0 ; number of hidden sectors
dd 0 ; 32-bit number of sectors
db 0 ; bios drive number
db 0 ; reserved
db 0x29 ; extended boot signature
dd 0 ; volume ID
db "NO NAME " ; volume label
db "FAT12 " ; filesystem type
; ---------------------------------------------------------------
print_io_error:
call print
jmp $
; print zero-terminated string (without formatting)
; ds:si = string
; es:di = position on screen
print:
;(dh,dl)=(x,y) position
;ah=color
;ds:si=String address
push es
push ax
;destination EA and seg
push dx
and dx, 00ffh
mov ax, 160
mul dx
pop dx
shr dx, 08h
add ax, dx
mov di, ax
mov ax, 0b800h
mov es, ax
;source EA and seg
pop ax
cld
pr:
lodsb
or al, al
jz prEnd
stosw
jmp pr
prEnd:
pop es
ret
;----------------------------------------------------------
;loader start here
start:
mov ax, 0003h
int 10h ;setup display mode 80*25 char mode
mov ax, 00h
mov ds, ax
mov ss, ax ;ss=0000h
mov sp, 7000h ;sp=7000h
mov ah, 00h
mov dl, byte [bootdev]
int 13h ;reset disks
;---------------------------------------
;read FAT at
mov ax, FATBUFSEG
mov es, ax
mov bx, FATBUF ;1100:0000h
mov ax, 01h ;FAT start from 01(logical) sector
load_FAT:
push ax
xor dx, dx
mov si, 18
div si
mov cl, dl
inc cl ; sector (19 % 18 + 1)
xor dx, dx
mov si, 02h
div si
mov ch, al ; track ((19 / 18) / 2)
mov dh, dl ; head ((19 / 18) % 2)
mov dl, byte [bootdev] ; dl = device, but that's still correct
mov ax, 0201h ; read from disk
int 13h
pop ax
jc print_io_error ; out of range crap :(
add bx, 512
inc ax
cmp ax, 9
jbe load_FAT
;----------------------------------------------
;load rootdir:
mov ax, ROOTDIRSEG
mov es, ax
mov bx, ROOTDIR ;1300:0000h
mov ax, 19 ;rootdir start from 19(logical) sector
load_rootdir:
push ax
xor dx, dx
mov si, 18
div si
mov cl, dl
inc cl ; sector (19 % 18 + 1)
xor dx, dx
mov si, 02h
div si
mov ch, al ; track ((19 / 18) / 2)
mov dh, dl ; head ((19 / 18) % 2)
mov dl, byte [bootdev] ; dl = device, but that's still correct
mov ax, 0201h ; read from disk
int 13h
pop ax
jc print_io_error ; out of range crap :(
add bx, 512
inc ax
cmp ax, 32
jbe load_rootdir
;---------------------------------------
;find file
mov ax, ROOTDIRSEG
mov es, ax
mov bx, ROOTDIR ; ax = pointer to current dir-entry
find_start: ;find the kernel.bin
mov di, bx ; point si to current filename
mov si, filename ; point di to the filename we need
mov cx, 11 ; compare max 11 bytes 8 filename + 3 extendName
cld
repe cmpsb
je found_file
add bx, 32 ; done yet?
cmp bx, ROOTDIR+224*32
jne find_start
; print error and halt
mov si, file_not_found
mov dx, 0002h
mov ah, 0ch
call print
jmp $
found_file: ;kernel.bin be found
;save cluster
mov ax, ROOTDIRSEG
mov ds, ax
mov dx, word [bx+26] ; load cluster of file from the directory entry
mov ax, 0000h
mov ds, ax
mov word [cluster], dx ;26~27 is the start cluster number of the file
;decode FAT
mov cx, 512*(9/3) ; number of entries in the fat.
mov ax, FATBUFSEG
mov ds, ax
mov si, FATBUF
mov ax, FATDECODEDSEG
mov es, ax
mov di, FATDECODED
fat_decode_loop: ; load dword, split into two pieces of 12 bits, and discard last byte
lodsd ; load dword
dec si ; need only 3 bytes
mov ebx, eax
and eax, 0fffh ; mask
stosw
mov eax, ebx
shr eax, 12
and eax, 0fffh ; shift & mask
stosw
loop fat_decode_loop
;----------------------------------------
;load file:
;es:bx = buffer
;ds:si = decoded fat buffer
;rest is for temporary usage only
;prepare buffer:1000:0000h
mov ax, SETUPSEG
mov es, ax
mov bx, SETUPOFF
mov ax, 0000h
mov ds, ax
mov ax, word [cluster]
load_loop:
push bx
; calculate next cluster
mov si, ax
shl si, 01h
mov dx, FATDECODEDSEG
mov ds, dx
mov cx, word [FATDECODED+si]
mov dx, 0000h
mov ds, dx
mov word [cluster], cx
; calculate track, head and sector
add ax, 31 ; ax = logical sector
xor dx, dx
mov di, 18
div di
mov cl, dl
inc cl ; cl = sector = (logical % 18 + 1)
xor dx, dx
mov di, 02h
div di
mov ch, al ; ch = track = ((logical / 18) / 2)
mov dh, dl ; dh = head = ((logical / 18) % 2)
mov dl, byte [bootdev]
;read data
mov ax, 0201h
int 13h
jc print_io_error ; out of range crap :(
pop bx
add bx, 512
; done?
mov ax, word [cluster]
cmp ax, 0ff7h
jb load_loop
mov si, load_setup_ok
mov dx, 0000h
mov ah, 0ch
call print
push SETUPSEG
push SETUPOFF
retf
;--------------------------------------
;constant address
SETUPSEG equ 1000h
SETUPOFF equ 0000h ;setup.asm will be loaded at here.
FATBUFSEG equ 1100h
FATBUF equ 0000h ;11000h-12fffh,location of FAT loading
ROOTDIRSEG equ 1300h
ROOTDIR equ 0000h ;13000h-14fffh,location of directory table loading
FATDECODEDSEG equ 1500h
FATDECODED equ 0000h ;15000h-16fffh,FAT will be decoded at here
;--------------------------------------
;filename
filename db 'SETUP',20h,20h,20h,'BIN' ;setup.bin,we must found it and load.
;message
file_not_found db "no SETUP.",00h ;setup.bin have not found.
load_setup_ok db "Load setup OK.",00h ;setup.bin be loaded into memory.
;two variables
bootdev db 00h
cluster dw 00h
;--------------------------------------
times 510-($-$$) db 00h ; align at 510 bytes
; boot signature
dw 0aa55h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -