主题:有没有谁有系统的引导程序的啊?
danenal
[专家分:0] 发布于 2005-12-06 17:40:00
我需要一个系统的引导程序,最好加上详细的注释和程序说时,有没有谁能帮帮我啊?
回复列表 (共9个回复)
沙发
erping [专家分:3660] 发布于 2005-12-06 18:03:00
;
; 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.
;
; $Logfile: C:/dos-c/src/boot/boot.asv $
;
; $Header: C:/dos-c/src/boot/boot.asv 1.5 10 Jan 1997 4:58:06 patv $
;
; $Log: C:/dos-c/src/boot/boot.asv $
;
; Rev 1.5 10 Jan 1997 4:58:06 patv
; Corrected copyright
;
; Rev 1.4 10 Jan 1997 4:52:50 patv
; Re-written to support C drive and eliminate restrictions on IPL.SYS
;
; Rev 1.3 29 Aug 1996 13:06:50 patv
; Bug fixes for v0.91b
;
; Rev 1.2 01 Sep 1995 17:56:44 patv
; First GPL release.
;
; Rev 1.1 30 Jul 1995 20:37:38 patv
; Initialized stack before use.
;
; Rev 1.0 02 Jul 1995 10:57:52 patv
; Initial revision.
;
板凳
erping [专家分:3660] 发布于 2005-12-06 18:03:00
page 60,132
title DOS-C boot
IFDEF DEBUG
TEXT SEGMENT WORD PUBLIC 'TEXT'
TEXT ENDS
LOAD SEGMENT PARA PUBLIC 'LOAD'
LOAD ENDS
TEXT SEGMENT WORD PUBLIC 'TEXT'
ASSUME CS:TEXT, DS:TEXT
LOAD SEGMENT PARA PUBLIC 'LOAD'
org 0
loadBuffer dw 32767 dup (?)
LOAD ENDS
ELSE
TEXT SEGMENT WORD PUBLIC 'TEXT'
ASSUME CS:TEXT, DS:TEXT
ENDIF
IFDEF DEBUG
mov dl, BOOTDRIVE
jmp Entry
BASE equ 7c00h
ELSE
BASE equ 0
ENDIF
org BASE
Entry: jmp real_start
; bp is initialized to 7c00h
oem equ [bp+3]
bytesPerSector equ [bp+0bh]
sectPerCluster equ [bp+0dh]
resSectors equ [bp+0eh]
nFats equ [bp+10h]
nRootDir equ [bp+11h]
nSectors equ [bp+13h]
MID equ [bp+15h]
sectPerFat equ [bp+16h]
sectPerTrack equ [bp+18h]
nHeads equ [bp+1ah]
nHidden equ [bp+1ch]
nSectorHuge equ [bp+20h]
drive equ [bp+24h]
extBoot equ [bp+26h]
volid equ [bp+27h]
vollabel equ [bp+2bh]
filesys equ [bp+36h]
IFDEF DEBUG
db 'FreeDOS '
dw 512 ; bytes/sector
db 2 ; sectors/allocation unit
dw 1 ; # reserved sectors
db 2 ; # of fats
dw 112 ; # of root directories
dw 720 ; # sectors total in image
db 0fdh ; media descrip: fd=2side9sec, etc...
dw 2 ; # sectors in a fat
dw 9 ; # sectors/track
dw 2 ; # heads
dd 0 ; # hidden sectors
dd 0 ; # sectors if > 65536
db 00h ; drive number
db 00h
db 29h ; extended boot signature
dd 0
db 'DOS-C BOOT '
db 'FAT12 '
LOADSEG equ seg LOAD
ELSE
LOADSEG equ 2000h
ENDIF
FATBUF equ 4000h ; offset of temporary buffer for FAT
; chain
RETRYCOUNT equ 5 ; number of retries on disk errors
; Some extra variables that are created on the stack frame
fat_start equ [bp-4] ; first FAT sector
root_dir_start equ [bp-8] ; first root directory sector
data_start equ [bp-12] ; first data sector
; To save space, functions that are just called once are
; implemented as macros instead. Four bytes are saved by
; avoiding the call / ret instructions.
3 楼
erping [专家分:3660] 发布于 2005-12-06 18:04:00
; FINDFILE: Searches for the file in the root directory.
;
; Returns:
;
; If file not found: CF set
;
; If file found: CF clear
; AX = first cluster of file
FINDFILE MACRO
; First, read the whole root directory
; into the temporary buffer.
mov ax, word ptr root_dir_start
mov dx, word ptr root_dir_start+2
mov di, nRootDir
xor bx, bx
mov es, tempbuf
call readDisk
jc ffDone
xor di, di
next_entry: mov cx, 11
mov si, offset filename+7c00h
push di
repe cmpsb
pop di
mov ax, es:[di][1ah] ; get cluster number from directory entry
clc
je ffDone
add di, 20h ; go to next directory entry
cmp byte ptr es:[di], 0 ; if the first byte of the name is 0,
jnz next_entry ; there is no more files in the directory
stc
ffDone:
ENDM
; GETDRIVEPARMS: Calculate start of some disk areas.
GETDRIVEPARMS MACRO
mov si, word ptr nHidden
mov di, word ptr nHidden+2
add si, word ptr resSectors
adc di, 0 ; DI:SI = first FAT sector
mov word ptr fat_start, si
mov word ptr fat_start+2, di
mov al, nFats
xor ah, ah
mul word ptr sectPerFat ; DX:AX = total number of FAT sectors
add si, ax
adc di, dx ; DI:SI = first root directory sector
mov word ptr root_dir_start, si
mov word ptr root_dir_start+2, di
; Calculate how many sectors the root directory occupies.
mov bx, bytesPerSector
mov cl, 5 ; divide BX by 32
shr bx, cl ; BX = directory entries per sector
mov ax, nRootDir
xor dx, dx
div bx
mov nRootDir, ax ; AX = sectors per root directory
add si, ax
adc di, 0 ; DI:SI = first data sector
mov data_start, si
mov data_start+2, di
ENDM
4 楼
erping [专家分:3660] 发布于 2005-12-06 18:04:00
; GETFATCHAIN:
;
; Reads the FAT chain and stores it in a temporary buffer in the first
; 64 kb. The FAT chain is stored an array of 16-bit cluster numbers,
; ending with 0.
;
; The file must fit in conventional memory, so it can't be larger than
; 640 kb. The sector size must be at least 512 bytes, so the FAT chain
; can't be larger than around 3 kb.
;
; Call with: AX = first cluster in chain
;
; Returns: CF clear on success, set on error
GETFATCHAIN MACRO
push ax ; store first cluster number
; Load the complete FAT into memory. The FAT can't be larger
; than 128 kb, so it should fit in the temporary buffer.
mov es, tempbuf
xor bx, bx
mov di, sectPerFat
mov ax, word ptr fat_start
mov dx, word ptr fat_start+2
call readDisk
pop ax ; restore first cluster number
jc boot_error
; Set ES:DI to the temporary storage for the FAT chain.
push ds
push es
pop ds
pop es
mov di, FATBUF
next_clust: stosw ; store cluster number
mov si, ax ; SI = cluster number
cmp byte ptr extBoot, 29h
jne fat_12
cmp byte ptr filesys[4], '6' ; check for FAT-16 system
je fat_16
; This is a FAT-12 disk.
fat_12: add si, si ; multiply cluster number by 3...
add si, ax
shr si, 1 ; ...and divide by 2
lodsw
; If the cluster number was even, the cluster value is now in
; bits 0-11 of AX. If the cluster number was odd, the cluster
; value is in bits 4-15, and must be shifted right 4 bits. If
; the number was odd, CF was set in the last shift instruction.
jnc fat_even
mov cl, 4
shr ax, cl ; shift the cluster number
fat_even: and ah, 0fh ; mask off the highest 4 bits
cmp ax, 0fffh ; check for EOF
jmp short next_test
; This is a FAT-16 disk. The maximal size of a 16-bit FAT
; is 128 kb, so it may not fit within a single 64 kb segment.
fat_16: mov dx, tempbuf
add si, si ; multiply cluster number by two
jnc first_half ; if overflow...
add dh, 10h ; ...add 64 kb to segment value
first_half: mov ds, dx ; DS:SI = pointer to next cluster
lodsw ; AX = next cluster
cmp ax, 0fff8h ; >= FFF8 = 16-bit EOF
next_test: jb next_clust ; continue if not EOF
finished: ; Mark end of FAT chain with 0, so we have a single
; EOF marker for both FAT-12 and FAT-16 systems.
xor ax, ax
stosw
fatError:
ENDM
5 楼
erping [专家分:3660] 发布于 2005-12-06 18:05:00
; loadFile: Loads the file into memory, one cluster at a time.
loadFile MACRO
mov es, tempbuf ; set ES:BX to load address
xor bx, bx
mov si, FATBUF ; set DS:SI to the FAT chain
push cs
pop ds
next_cluster: lodsw ; AX = next cluster to read
or ax, ax ; if EOF...
je boot_success ; ...boot was successful
dec ax ; cluster numbers start with 2
dec ax
mov di, word ptr sectPerCluster
and di, 0ffh ; DI = sectors per cluster
mul di
add ax, data_start
adc dx, data_start+2 ; DX:AX = first sector to read
call readDisk
jnc next_cluster
ENDM
org BASE+3eh
tempbuf equ [bp+3eh]
load_seg dw LOADSEG
real_start: cli
cld
mov ax, cs
mov ss, ax ; initialize stack
mov bp, 7c00h
lea sp, [bp-20h]
sti
mov es, ax
mov ds, ax
mov drive, dl ; BIOS passes drive number in DL
GETDRIVEPARMS
FINDFILE ; locate file in root directory
jc boot_error ; fail if not found
GETFATCHAIN ; read FAT chain
LOADFILE ; load file (jumps to boot_sucess if successful)
boot_error: mov cx, ERRMSGLEN
mov si, offset errmsg+7c00h
next_char: lodsb ; print error message
mov ah, 0eh
xor bh, bh
int 10h
loop next_char
xor ah, ah
int 16h ; wait for keystroke
int 19h ; invoke bootstrap loader
boot_success: mov dl, drive
db 0eah ; far jump to LOADSEG:0000
dw 0
dw LOADSEG
6 楼
erping [专家分:3660] 发布于 2005-12-06 18:06:00
readDisk proc
push si
read_next: push dx
push ax
;
; translate sector number to BIOS parameters
;
;
; abs = sector offset in track
; + head * sectPerTrack offset in cylinder
; + track * sectPerTrack * nHeads offset in platter
;
; t1 = abs / sectPerTrack (ax has t1)
; sector = abs mod sectPerTrack (cx has sector)
;
div word ptr sectPerTrack
mov cx, dx
;
; t1 = head + track * nHeads
;
; track = t1 / nHeads (ax has track)
; head = t1 mod nHeads (dl has head)
;
xor dx, dx
div word ptr nHeads
; the following manipulations are necessary in order to
; properly place parameters into registers.
; ch = cylinder number low 8 bits
; cl = 7-6: cylinder high two bits
; 5-0: sector
mov dh, dl ; save head into dh for bios
ror ah, 1 ; move track high bits into
ror ah, 1 ; bits 7-6 (assumes top = 0)
xchg al, ah ; swap for later
mov dl, byte ptr sectPerTrack
sub dl, cl
inc cl ; sector offset from 1
or cx, ax ; merge cylinder into sector
mov al, dl ; al has # of sectors left
; Calculate how many sectors can be transfered in this read
; due to dma boundary conditions.
push dx
mov si, di ; temp register save
; this computes remaining bytes because of modulo 65536
; nature of dma boundary condition
mov ax, bx ; get offset pointer
neg ax ; and convert to bytes
jz ax_min_1 ; started at seg:0, skip ahead
xor dx, dx ; convert to sectors
div word ptr bytesPerSector
cmp ax, di ; check remainder vs. asked
jb ax_min_1 ; less, skip ahead
mov si, ax ; transfer only what we can
ax_min_1: pop dx
; Check that request sectors do not exceed track boundary
mov si, sectPerTrack
inc si
mov ax, cx ; get the sector/cyl byte
and ax, 03fh ; and mask out sector
sub si, ax ; si has how many we can read
mov ax, di
cmp si, di ; see if asked <= available
jge ax_min_2
mov ax, si ; get what can be xfered
7 楼
erping [专家分:3660] 发布于 2005-12-06 18:06:00
ax_min_2: mov si, RETRYCOUNT
mov ah, 2
mov dl, drive
retry: push ax
int 13h
pop ax
jnc read_ok
push ax
xor ax, ax ; reset the drive
int 13h
pop ax
dec si
jnz retry
stc
pop ax
pop dx
pop si
ret
read_next_jmp: jmp short read_next
read_ok: xor ah, ah
mov si, ax ; AX = SI = number of sectors read
mul word ptr bytesPerSector ; AX = number of bytes read
add bx, ax ; add number of bytes read to BX
jnc no_incr_es ; if overflow...
mov ax, es
add ah, 10h ; ...add 1000h to ES
mov es, ax
no_incr_es: pop ax
pop dx ; DX:AX = last sector number
add ax, si
adc dx, 0 ; DX:AX = next sector to read
sub di, si ; if there is anything left to read,
jg read_next_jmp ; continue
clc
pop si
ret
readDisk endp
errmsg db "Boot error"
ERRMSGLEN equ $ - errmsg
filename db "IPL SYS"
org BASE+01feh
sign dw 0aa55h
TEXT ENDS
end
8 楼
jinyuxlc [专家分:120] 发布于 2005-12-13 12:38:00
我真是服了,二楼的这么厉害,我看过很多你的回帖了
9 楼
erping [专家分:3660] 发布于 2005-12-13 12:52:00
呵呵
这个可不是我写的
我来回复