All pastes #745409 Raw Edit

Unbenannt

public text v1 · immutable
·published 2007-10-22 11:44 UTC
rendered paste body
;*********************************************************
; RootOS - Bootloader / A20
; Author: Simon Wollwage a.k.a. rootnode
;*********************************************************

%ifndef __A20_INCLUDED_
%define __A20_INCLUDED_

bits 16

global _enable_a20

_enable_a20:
    pusha
    cli
    mov  cx, 5
    
    .enable_a20_start:
    
        .kbrd_cntrl_wait:
            xor  ax, ax
            in   al, 64h
            bt   ax, 1
            jc   .kbrd_cntrl_wait
            
            mov  al, 0dfh
            out  64h, al
        
        .kbrd_cntrl_wait_2:
            xor  ax, ax
            in   al, 64h
            bt   ax, 1
            jc   .kbrd_cntrl_wait_2
            
        .kbrd_cntrl_get_state:
            xor  ax, ax
            in   al, 60h
            
            bt   ax, 1
            jc   .enable_a20_success
            
            loop .enable_a20_start
            
            jmp  .enable_a20_fail
            
    .enable_a20_success:
        popa
        xor  eax, eax
        ret
        
    .enable_a20_fail:
        popa
        mov  eax, -1
        ret
        
%endif
       
;*********************************************************
; RootOS - Bootloader / Global Descriptor Table
; Author: Simon Wollwage a.k.a. rootnode
;*********************************************************

%ifndef __GDT_INC_F458AD93BB62943A_INCLUDED_
%define __GDT_INC_F458AD93BB62943A_INCLUDED_

bits 16

install_gdt:
    cli
    pusha
    lgdt [toc]
    sti
    popa
    ret
    
gdt_data: 
	dd 0            ; null descriptor
	dd 0 

; gdt code:                                    
	dw 0FFFFh       ; limit low
	dw 0            ; base low
	db 0            ; base middle
	db 10011010b    ; access
	db 11001111b    ; granularity
	db 0            ; base high

; gdt data:	                                ; data descriptor
	dw 0FFFFh       ; limit low (Same as code)10:56 AM 7/8/2007
	dw 0            ; base low
	db 0            ; base middle
	db 10010010b    ; access
	db 11001111b    ; granularity
	db 0            ; base high

end_of_gdt:
toc: 
	dw end_of_gdt - gdt_data - 1 	; limit (Size of GDT)
	dd gdt_data 			        ; base of GDT
    
%endif

;*********************************************************
; RootOS - Bootloader / Input-/Output routines
; Author: Simon Wollwage a.k.a. rootnode
;*********************************************************

%ifndef __STDIO_INC_F458AD93BB62943A_INCLUDED_
%define __STDIO_INC_F458AD93BB62943A_INCLUDED_

;*********************************************************
; Output routines for 16 bit unprotected mode
bits 16

puts16:
    pusha
    .loop_16:
        lodsb
        or      al, al
        jz      puts16_done
        mov     ah, 0eh
        int     10h
        jmp     .loop_16
puts16_done:
    popa
    ret

;*********************************************************
; Output routines for 32 bit PMode
bits 32

%define VIDMEM      0xB8000
%define COLS        80
%define LINES       25
;%define CHAR_ATTRIB 31 ; blue/white
%define CHAR_ATTRIB 10

_cur_x db 0
_cur_y db 0

putch32:
    pusha
    mov  edi, VIDMEM
    
        ;*********************************************************
        ; Retrieve position
        xor  eax, eax
    
        mov  ecx, COLS * 2
        mov  al, byte [_cur_y]
        mul  ecx
        push eax
    
        mov  al, byte [_cur_x]
        mov  cl, 2
        mul  cl
        pop  ecx
        add  eax, ecx
        xor  ecx, ecx
        add  edi, eax
    
        ;*********************************************************
        ; Search for newline
        cmp  bl, 0x0A
        je   .row
    
        mov  dl, bl
        mov  dh, CHAR_ATTRIB
        mov  word [edi], dx
    
        inc  byte [_cur_x]
        ;cmp  byte [_cur_x], COLS
        ;je   .row
        jmp  .done
        
    .row:
        mov  byte [_cur_x], 0
        inc  byte [_cur_y]
        
    .done:
        popa
        ret
        
bits 32
        
puts32:
    pusha
    push ebx
    pop  edi
    
    .loop:
        mov  bl, byte [edi]
        cmp  bl, 0
        je   .done
        
        call putch32
        
    .next:
        inc  edi
        jmp  .loop
        
    .done:
        mov  bh, byte [_cur_y]
        mov  bl, byte [_cur_x]
        call mov_cur
        popa
        ret
        
mov_cur:
    pusha
    
    xor  eax, eax
    mov  ecx, COLS
    mov  al, bh
    mul  ecx
    add  al, bl
    mov  ebx, eax
    
    mov  al, 0x0F
    mov  dx, 0x03D4
    out  dx, al
    
    mov  al, bl
    mov  dx, 0x03D5
    out  dx, al
    
    xor  eax, eax
    mov  al, 0x0E
    mov  dx, 0x03D4
    out  dx, al
    
    mov  al, bh
    mov  dx, 0x03D5
    out  dx, al
    
    popa
    ret
    
bits 32
    
space db '                                                                                ', 0x0A,  0
    
clrscr32:
    pusha
    mov  byte [_cur_x], 0
    mov  byte [_cur_y], 0
    
    mov  ecx, LINES
    
    .loop:
        lea  ebx, [space]
        call puts32
        loopz .loop
        
        mov  byte [_cur_x], 0
        mov  byte [_cur_y], 0
        
        popa
        ret
    
%endif

;*********************************************************
; RootOS - Bootloader / Stage 1
; Author: Simon Wollwage a.k.a. rootnode
;*********************************************************
;*********************************************************
; Since we are running on x86, we have to start in 
; 16 bit mode
bits    16

;*********************************************************
; Set the origin to the beginning of the bootloader memory section
; Beginning of sector 1
org     0

;*********************************************************
; Jump over the definitions directly to the loader
start: jmp main
	
;*********************************************************
; fill up to have 512 bytes in size
; TIMES 0Bh - $ + Start db 0

;*********************************************************
bpbOEM                  db "RootOS  "       ;  This member must be exactly 8 bytes
;*********************************************************
; some constants for a FAT File System
bpbBytesPerSector:      dw 512
bpbSectorsPerCluster:   db 1
bpbReservedSectors:     dw 1
bpbNumberOfFATs:        db 2
bpbRootEntries:         dw 224
bpbTotalSectors:        dw 2880
bpbMeda:                db 0xF0
bpbSectorsPerFAT:       dw 9
bpbSectorsPerTrack:     dw 18
bpbHeadsPerCylinder:    dw 2
bpbHiddenSectors:       dd 0
bpbTotalSectorsBig:     dd 0
bsDriveNumber:          db 0
bsUnused:               db 0
bsExtBootSignature:     db 0x29
bsSerialNumber:         dd 0xA0A1A2A3
bsVolumeLabel:          db "MOS FLOPPY "
bsFileSystem:           db "FAT12   "

print: 
    lodsb
    or      al, al
    jz      printdone
    mov     ah, 0eh
    int     10h
    jmp     print
printdone:
    ret
    
absoluteSector  db 0x00
absoluteHead    db 0x00
absoluteTrack   db 0x00

;*********************************************************
; Converts CHS to LBA
Cluster2LBA:
    sub  ax, 0x0002
    xor  cx, cx
    mov  cl, BYTE [bpbSectorsPerCluster]
    mul  cx
    add  ax, WORD [dataSector]
    ret
    
;*********************************************************
; Converts LBA to CHS
lba2chs:
    xor  dx, dx
    div  WORD [bpbSectorsPerTrack]
    inc  dl
    mov  BYTE [absoluteSector], dl
    xor  dx, dx
    div  WORD [bpbHeadsPerCylinder]
    mov  BYTE [absoluteHead], dl
    mov  BYTE [absoluteTrack], al
    ret

;*********************************************************
; Read sectors    
readsectors:
    .main
        mov di, 0x0005                  ; Allow at most five error retries
    .sectorloop
        push ax
        push bx
        push cx
        call lba2chs                    ; convert first sector to LBA format
        mov  ah, 0x02                   ; BIOS read sector
        mov  al, 0x01                   ; read sector
        mov  ch, BYTE [absoluteTrack]   ; get track
        mov  cl, BYTE [absoluteSector]  ; get sector
        mov  dh, BYTE [absoluteHead]    ; get head
        mov  dl, BYTE [bsDriveNumber]   ; get drive
        int  0x13                       ; call bios
        jnc  .success                   ; test for errors
        xor  ax, ax                     ; reset the disk
        int  0x13                       ; call bios
        dec  di                         ; dec error count
        pop  cx                         ; restore registers
        pop  bx                         ;  "
        pop  ax                         ;  "
        jnz  .sectorloop                ; read again
        int  0x18
    .success
        mov  si, sProgress
        call print
        pop  cx
        pop  bx
        pop  ax
        add  bx, WORD [bpbBytesPerSector]
        inc  ax
        loop .main
        ret

;*********************************************************
; Bootloader Entry point
main:
    cli                 ; turn off interrupts
    mov  ax, 0x07C0
    mov  ds, ax
    mov  es, ax
    mov  fs, ax
    mov  gs, ax
    
    
    ;*********************************************************
    ; Create the stack
    mov  ax, 0x0000
    mov  ss, ax
    mov  sp, 0xFFFF
    sti                 ; turn on interrupts
    
    ;*********************************************************
    ; Display loading screen
    mov  si, sLoadingMessage
    call print
    
    ;*********************************************************
    ; Load root directory descritpr table
load_root:
    xor  cx, cx
    xor  dx, dx
    mov  ax, 0x0020
    mul  WORD [bpbRootEntries]
    div  WORD [bpbBytesPerSector]
    xchg ax, cx
    
    mov  al, BYTE [bpbNumberOfFATs]
    mul  WORD [bpbSectorsPerFAT]
    add  ax, WORD [bpbReservedSectors]
    mov  WORD [dataSector], ax
    add  WORD [dataSector], cx
    
    mov  bx, 0x0200
    call readsectors
    
    ;*********************************************************
    ; Find stage 2 loader
    
    mov  cx, WORD [bpbRootEntries]
    mov  di, 0x0200
    
    .loop:
        push cx
        mov  cx, 0x000B
        mov  si, ImageName
        push di
    rep cmpsb
        pop  di
        je   load_fat
        pop  cx
        add  di, 0x0020
        loop .loop
        jmp  failure
        
    load_fat:
        mov  si, sCLRF
        call print
        mov  dx, WORD [di + 0x001A]
        mov  WORD [cluster], dx
        
        xor  ax, ax
        mov  al, BYTE [bpbNumberOfFATs]
        mul  WORD [bpbSectorsPerFAT]
        mov  cx, ax
        
        mov  ax, WORD [bpbReservedSectors]
        
        mov  bx, 0x0200
        call readsectors
        
        mov  si, sCLRF
        call print
        
        mov  ax, 0x0050
        mov  es, ax
        mov  bx, 0x0000
        push bx
        
    ;*********************************************************
    ; Load stage 2
    load_image:
        mov  ax, WORD [cluster]
        pop  bx
        call Cluster2LBA
        xor  cx, cx
        mov  cl, BYTE [bpbSectorsPerCluster]
        call readsectors
        push bx
        
    ;*********************************************************
    ; Process to next cluster
        mov  ax, WORD [cluster]
        mov  cx, ax
        mov  dx, ax
        shr  dx, 0x0001
        add  cx, dx
        mov  bx, 0x0200
        add  bx, cx
        mov  dx, WORD [bx]
        test ax, 0x0001
        jnz  .odd_cluster
        
    .even_cluster:
        and  dx, 0000111111111111b
        jmp  .done
        
    .odd_cluster:
        shr  dx, 0x0004
        
    .done:
        mov  WORD [cluster], dx
        cmp  dx, 0x0FF0
        jb   load_image
        
    done:
        mov  si, sCLRF
        call print
        push WORD 0x0050
        push WORD 0x0000
        retf
    
    failure:
        mov  si, sFailure
        call print
        mov  ah, 0x00
        int  0x16
        int  0x19

dataSector      dw 0x0000
cluster         dw 0x0000
ImageName       db "STAGE2  SYS"
sLoadingMessage db 0x0D, 0x0A, "Loading boot image ", 0x0D, 0x0A, 0x00
sCLRF           db 0x0D, 0x0A, 0x00
sProgress       db "*", 0x00
sFailure        db 0x0D, 0x0A, "ERROR: Please press any key to reboot", 0x00        
	
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; fill up the rest of the 512 byte
times 510 - ($-$$) db 0

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; This signature is needed!
; Without it, the BIOS won't recognize us as a bootloader
dw 0xAA55