https://github.com/benwei/bos
以下是bootldr.s
;*********************************************; bootldr.s ;  - Bootloader for loading MYOS.BIN;; Modify the source from ; Operating Systems Development Tutorial;*********************************************bits 16      ; we are in 16 bit real modeorg  0     ; we will set regisers laterstart: jmp main     ; jump to start of bootloader;*********************************************; BIOS Parameter Block;*********************************************; BPB Begins 3 bytes from start. We do a far jump, which is 3 bytes in size.; If you use a short jump, add a "nop" after it to offset the 3rd byte.bpbOEM   db "My OS   "bpbBytesPerSector:   DW 512bpbSectorsPerCluster:  DB 1bpbReservedSectors:  DW 1bpbNumberOfFATs:  DB 2bpbRootEntries:  DW 224bpbTotalSectors:  DW 2880bpbMedia:   DB 0xf0  ;; 0xF1bpbSectorsPerFAT:  DW 9bpbSectorsPerTrack:  DW 18bpbHeadsPerCylinder:  DW 2bpbHiddenSectors:  DD 0bpbTotalSectorsBig:     DD 0bsDriveNumber:          DB 0bsUnused:   DB 0bsExtBootSignature:  DB 0x29bsSerialNumber:         DD 0xa0a1a2a3bsVolumeLabel:          DB "BOS FLOPPY "bsFileSystem:          DB "FAT12   ";************************************************;; Prints a string; DS=>SI: 0 terminated string;************************************************;Print:lodsb    ; load next byte from string from SI to ALor al, al   ; Does AL=0?jz PrintDone  ; Yep, null terminator found-bail outmov ah, 0eh   ; Nope-Print the characterint 10hjmp Print   ; Repeat until null terminator foundPrintDone:ret    ; we are done, so returnabsoluteSector db 0x00absoluteHead   db 0x00absoluteTrack  db 0x00;************************************************;; Convert CHS to LBA; LBA = (cluster - 2) * sectors per cluster;************************************************;ClusterLBA:          sub     ax, 0x0002                          ; zero base cluster number          xor     cx, cx          mov     cl, BYTE [bpbSectorsPerCluster]     ; convert byte to word          mul     cx          add     ax, WORD [datasector]               ; base data sector          ret;************************************************;; Convert LBA to CHS; AX=>LBA Address to convert;; absolute sector = (logical sector / sectors per track) + 1; absolute head   = (logical sector / sectors per track) MOD number of heads; absolute track  = logical sector / (sectors per track * number of heads);;************************************************;LBACHS:          xor     dx, dx                              ; prepare dx:ax for operation          div     WORD [bpbSectorsPerTrack]           ; calculate          inc     dl                                  ; adjust for sector 0          mov     BYTE [absoluteSector], dl          xor     dx, dx                              ; prepare dx:ax for operation          div     WORD [bpbHeadsPerCylinder]          ; calculate          mov     BYTE [absoluteHead], dl          mov     BYTE [absoluteTrack], al          ret;************************************************;; Reads a series of sectors; CX=>Number of sectors to read; AX=>Starting sector; ES:BX=>Buffer to read to;************************************************;ReadSectors:     .MAIN:          mov     di, 0x0005                          ; five retries for error     .SECTORLOOP:          push    ax          push    bx          push    cx          call    LBACHS                              ; convert starting sector to CHS          mov     ah, 0x02                            ; BIOS read sector          mov     al, 0x01                            ; read one sector          mov     ch, BYTE [absoluteTrack]            ; track          mov     cl, BYTE [absoluteSector]           ; sector          mov     dh, BYTE [absoluteHead]             ; head          mov     dl, BYTE [bsDriveNumber]            ; drive          int     0x13                                ; invoke BIOS          jnc     .SUCCESS                            ; test for read error          xor     ax, ax                              ; BIOS reset disk          int     0x13                                ; invoke BIOS          dec     di                                  ; decrement error counter          pop     cx          pop     bx          pop     ax          jnz     .SECTORLOOP                         ; attempt to read again          int     0x18     .SUCCESS:          mov     si, msgProgress          call    Print          pop     cx          pop     bx          pop     ax          add     bx, WORD [bpbBytesPerSector]        ; queue next buffer          inc     ax                                  ; queue next sector          loop    .MAIN                               ; read next sector          ret;*********************************************; Bootloader Entry Point;*********************************************main:     ;----------------------------------------------------     ; code located at 0000:7C00, adjust segment registers     ;----------------------------------------------------               cli      ; disable interrupts          mov     ax, 0x07C0    ; setup registers to point to our segment          mov     ds, ax          mov     es, ax          mov     fs, ax          mov     gs, ax     ;----------------------------------------------------     ; create stack     ;----------------------------------------------------               mov     ax, 0x0000    ; set the stack          mov     ss, ax          mov     sp, 0xFFFF          sti      ; restore interrupts     ;----------------------------------------------------     ; Display loading message     ;----------------------------------------------------               mov     si, msgLoading          call    Print               ;----------------------------------------------------     ; Load root directory table     ;----------------------------------------------------     LOAD_ROOT:          ; compute size of root directory and store in "cx"               xor     cx, cx          xor     dx, dx          mov     ax, 0x0020                           ; 32 byte directory entry          mul     WORD [bpbRootEntries]                ; total size of directory (ax = 0x0020 * 224)          div     WORD [bpbBytesPerSector]             ; sectors used by directory (ax = 0x0020 * 224 / 512)          xchg    ax, cx                               ; swap(ax, cx) cx=14               ; compute location of root directory and store in "ax"               mov     al, BYTE [bpbNumberOfFATs]            ; number of FATs (2, ax = 2)          mul     WORD [bpbSectorsPerFAT]               ; sectors used by FATs (9, ax = 18)          add     ax, WORD [bpbReservedSectors]         ; adjust for bootsector(1, ax = 19)          mov     WORD [datasector], ax                 ; base of root directory([datasector] = 19)          add     WORD [datasector], cx   ; [datasector] = 19 + 14 = 33               ; read root directory into memory (7C00:0200)               mov     bx, 0x0200                            ; copy root dir above bootcode          call    ReadSectors     ;----------------------------------------------------     ; Find stage 2     ;----------------------------------------------------     ; browse root directory for binary image          mov     cx, WORD [bpbRootEntries]             ; load loop counter          mov     di, 0x0200                            ; locate first root entry     .LOOP:          push    cx          mov     cx, 0x000B                            ; eleven character name          mov     si, ImageName                         ; image name to find          push    di     rep  cmpsb                                         ; test for entry match          pop     di          je      LOAD_FAT          pop     cx          add     di, 0x0020                            ; queue next directory entry          loop    .LOOP          jmp     FAILURE     ;----------------------------------------------------     ; Load FAT     ;----------------------------------------------------     LOAD_FAT:          ; save starting cluster of boot image               mov     dx, WORD [di + 0x001A]          mov     WORD [cluster], dx                  ; file first cluster               ; compute size of FAT and store in "cx"               xor     ax, ax          mov     al, BYTE [bpbNumberOfFATs]          ; number of FATs          mul     WORD [bpbSectorsPerFAT]             ; sectors used by FATs          mov     cx, axmul     WORD [bpbBytesPerSector]       ; fatsize = sectors used by FATS * bpbBytesPerSector (512)mov   WORD [fatsize], ax     ; compute location of FAT and store in "ax"          mov     ax, WORD [bpbReservedSectors]       ; adjust for bootsector               ; read FAT into memory (7C00:0200)          mov     bx, 0x0200                          ; copy FAT above bootcode          call    ReadSectors     ; read image file into memory (0050:0000)               mov     ax, 0x0050          mov     es, ax                              ; destination for image          mov     bx, 0x0000                          ; destination for image          push    bx     ;----------------------------------------------------     ; Load Stage 2     ;----------------------------------------------------     LOAD_IMAGE:               mov     ax, WORD [cluster]                  ; cluster to read          pop     bx                                  ; buffer to read into          call    ClusterLBA                          ; convert cluster to LBA          xor     cx, cx          mov     cl, BYTE [bpbSectorsPerCluster]     ; sectors to read          call    ReadSectors          push    bx               ; compute next cluster               mov     ax, WORD [cluster]                  ; identify current cluster          mov     cx, ax                              ; copy current cluster          mov     dx, ax                              ; copy current cluster          shr     dx, 0x0001                          ; divide by two          add     cx, dx                              ; sum for (3/2)          mov     bx, 0x0200                          ; location of FAT in memory          add     bx, cx                              ; index into FAT          mov     dx, WORD [bx]                       ; read two bytes from FAT          test    ax, 0x0001          jnz     .ODD_CLUSTER               .EVEN_CLUSTER:               and     dx, 0000111111111111b               ; take low twelve bits         jmp     .DONE              .ODD_CLUSTER:               shr     dx, 0x0004                          ; take high twelve bits               .DONE:               mov     WORD [cluster], dx                  ; store new cluster          cmp     dx, 0x0FF0                          ; test for end of file          jb      LOAD_IMAGE               DONE:mov   ax, 0x1000mov     es, axmov     cx, 2    ; read 32 sectorsmov   ax, 19   ; starting sectormov     bx, 0    ; to 0x10000          call    ReadSectors%if 0; backup the FAT    ; ESmov   cx, word [fatsize]mov   si, 0x0200mov   ax, 0x1000mov     es, axmov   di, 0 .loopfatmove:lodsbstosbloop .loopfatmovemov     di, 0mov   ax, word [fatsize]stosw%endif          mov     si, msgCRLF          call    Print          push    WORD 0x0050          push    WORD 0x0000          retf               FAILURE:               mov     si, msgFailure          call    Print          mov     ah, 0x00          int     0x16                                ; await keypress          int     0x19                                ; warm boot computer     fatsize  dw 0x0000     datasector  dw 0x0000     cluster     dw 0x0000     ImageName   db "MYOS    BIN"     msgLoading  db 0x0D, 0x0A, "Loading Boot Image ", 0x00     msgCRLF     db 0x0D, 0x0A, 0x00     msgProgress db ".", 0x00     msgFailure  db 0x0D, 0x0A, "MISSING OS. Hit Any Key to Reboot", 0x0D, 0x0A, 0x00               TIMES 510-($-$$) DB 0          DW 0xAA55 
沒有留言:
張貼留言