回 帖 发 新 帖 刷新版面

主题:有没有谁有系统的引导程序的啊?

我需要一个系统的引导程序,最好加上详细的注释和程序说时,有没有谁能帮帮我啊?

回复列表 (共9个回复)

沙发

;
; 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.
;

板凳

        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 楼

;    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 楼

;    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 楼


;    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 楼

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 楼


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 楼

我真是服了,二楼的这么厉害,我看过很多你的回帖了

9 楼

呵呵
这个可不是我写的

我来回复

您尚未登录,请登录后再回复。点此登录或注册