boot.asm
来自「GNU FreeDOS兼容MS DOS很好的东东.」· 汇编 代码 · 共 528 行 · 第 1/2 页
ASM
528 行
;; File:; boot.asm; Description:; DOS-C boot;; Copyright (c) 1997;; Svante Frey; All Rights Reserved;; This file is part of DOS-C.;; DOS-C is free software; you can redistribute it and/or; modify it under the terms of the GNU General Public License; as published by the Free Software Foundation; either version; 2, or (at your option) any later version.;; DOS-C is distributed in the hope that it will be useful, but; WITHOUT ANY WARRANTY; without even the implied warranty of; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See; the GNU General Public License for more details.;; You should have received a copy of the GNU General Public; License along with DOS-C; see the file COPYING. If not,; write to the Free Software Foundation, 675 Mass Ave,; Cambridge, MA 02139, USA.;;; +--------+ 1FE0:7E00; |BOOT SEC|; |RELOCATE|; |--------| 1FE0:7C00; | |; |--------| 1FE0:3000; | CLUSTER|; | LIST |; |--------| 1FE0:2000; | |; |--------| 0000:7E00; |BOOT SEC| overwritten by max 128k FAT buffer; |ORIGIN | and later by max 134k loaded kernel; |--------| 0000:7C00; | |; |--------|; |KERNEL | also used as max 128k FAT buffer; |LOADED | before kernel loading starts; |--------| 0060:0000; | |; +--------+;%define ISFAT12 1;%define ISFAT16 1segment .text%define BASE 0x7c00 org BASEEntry: jmp short real_start nop; bp is initialized to 7c00h%define bsOemName bp+0x03 ; OEM label%define bsBytesPerSec bp+0x0b ; bytes/sector%define bsSecPerClust bp+0x0d ; sectors/allocation unit%define bsResSectors bp+0x0e ; # reserved sectors%define bsFATs bp+0x10 ; # of fats%define bsRootDirEnts bp+0x11 ; # of root dir entries%define bsSectors bp+0x13 ; # sectors total in image%define bsMedia bp+0x15 ; media descrip: fd=2side9sec, etc...%define sectPerFat bp+0x16 ; # sectors in a fat%define sectPerTrack bp+0x18 ; # sectors/track%define nHeads bp+0x1a ; # heads%define nHidden bp+0x1c ; # hidden sectors%define nSectorHuge bp+0x20 ; # sectors if > 65536%define drive bp+0x24 ; drive number%define extBoot bp+0x26 ; extended boot signature%define volid bp+0x27%define vollabel bp+0x2b%define filesys bp+0x36%define LOADSEG 0x0060%define FATBUF 0x2000 ; offset of temporary buffer for FAT ; chain; Some extra variables;%define StoreSI bp+3h ;temp store; To save space, functions that are just called once are; implemented as macros instead. Four bytes are saved by; avoiding the call / ret instructions.; GETDRIVEPARMS: Calculate start of some disk areas.;%macro GETDRIVEPARMS 0 mov si, word [nHidden] mov di, word [nHidden+2] add si, word [bsResSectors] adc di, byte 0 ; DI:SI = first FAT sector mov word [fat_start], si mov word [fat_start+2], di mov al, [bsFATs] cbw mul word [sectPerFat] ; DX:AX = total number of FAT sectors add si, ax adc di, dx ; DI:SI = first root directory sector mov word [root_dir_start], si mov word [root_dir_start+2], di ; Calculate how many sectors the root directory occupies. mov bx, [bsBytesPerSec] mov cl, 5 ; divide BX by 32 shr bx, cl ; BX = directory entries per sector mov ax, [bsRootDirEnts] xor dx, dx div bx mov word [RootDirSecs], ax ; AX = sectors per root directory add si, ax adc di, byte 0 ; DI:SI = first data sector mov [data_start], si mov [data_start+2], di%endmacro;----------------------------------------------------------------------- times 0x3E-$+$$ db 0%define loadsegoff_60 bp+loadseg_off-Entry%define loadseg_60 bp+loadseg_seg-Entry;%define LBA_PACKET bp+0x42; db 10h ; size of packet; db 0 ; const; dw 1 ; number of sectors to read%define LBA_PACKET bp-0x40%define LBA_SIZE word [LBA_PACKET]%define LBA_SECNUM word [LBA_PACKET+2]%define LBA_OFF LBA_PACKET+4%define LBA_SEG LBA_PACKET+6%define LBA_SECTOR_0 word [LBA_PACKET+8 ]%define LBA_SECTOR_16 word [LBA_PACKET+10]%define LBA_SECTOR_32 word [LBA_PACKET+12]%define LBA_SECTOR_48 word [LBA_PACKET+14]%define PARAMS LBA_PACKET+0x10%define RootDirSecs PARAMS+0x0 ; # of sectors root dir uses%define fat_start PARAMS+0x2 ; first FAT sector%define root_dir_start PARAMS+0x6 ; first root directory sector%define data_start PARAMS+0x0a ; first data sector;-----------------------------------------------------------------------; ENTRY;-----------------------------------------------------------------------real_start: cli cld xor ax, ax mov ds, ax mov bp, 0x7c00 ; a reset should not be needed here; int 0x13 ; reset drive; int 0x12 ; get memory available in AX; mov ax, 0x01e0; mov cl, 6 ; move boot sector to higher memory; shl ax, cl; sub ax, 0x07e0 mov ax, 0x1FE0 mov es, ax mov si, bp mov di, bp mov cx, 0x0100 rep movsw jmp word 0x1FE0:contloadseg_off dw 0loadseg_seg dw LOADSEGcont: mov ds, ax mov ss, ax lea sp, [bp-0x60] sti;; Some BIOS don't pass drive number in DL, so don't use it if [drive] is known; cmp byte [drive], 0xff ; impossible number written by SYS jne dont_use_dl ; was SYS drive: other than A or B? mov [drive], dl ; yes, rely on BIOS drive number in DLdont_use_dl: ; no, rely on [drive] written by SYS mov LBA_SIZE, 10h mov LBA_SECNUM,1 ; initialise LBA packet constants call print db "FreeDOS",0 GETDRIVEPARMS; FINDFILE: Searches for the file in the root directory.;; Returns:; AX = first cluster of file ; First, read the whole root directory ; into the temporary buffer. mov ax, word [root_dir_start] mov dx, word [root_dir_start+2] mov di, word [RootDirSecs] les bx, [loadsegoff_60] ; es:bx = 60:0 call readDisk jc jmp_boot_error les di, [loadsegoff_60] ; es:di = 60:0 ; Search for KERNEL.SYS file name, and find start cluster.next_entry: mov cx, 11 mov si, filename push di repe cmpsb pop di mov ax, [es:di+0x1A]; get cluster number from directory entry je ffDone add di, byte 0x20 ; go to next directory entry cmp byte [es:di], 0 ; if the first byte of the name is 0, jnz next_entry ; there is no more files in the directory jc boot_error ; fail if not foundffDone: push ax ; store first cluster number; call print; db " FAT",0
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?