Loading more than 54 sectors [SOLVED]

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
ehenkes
Member
Member
Posts: 124
Joined: Mon Mar 23, 2009 3:15 am
Location: Germany
Contact:

Re: Loading more than 54 sectors [SOLVED]

Post by ehenkes »

For comparison. Currently, I use this bootstrap loader and A20Gate & PM switch:

bootloader:

Code: Select all

org 0x7C00  ; set up start address of bootloader

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; setup a stack and segment regs ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    xor ax, ax
    mov ds, ax
    mov es, ax
    mov ss, ax
    mov sp, ax

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; read kernel from floppy disk ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    mov [bootdrive], dl ; boot drive stored by BIOS in DL.
                        ; we save it to [bootdrive] to play for safety.

load_kernel:
    xor ax, ax         ; mov ax, 0  => function "reset"
    int 0x13         
    jc load_kernel     ; trouble? try again

    mov bx, 0x8000     ; set up start address of kernel

    ; set parameters for reading function
    ; 8-bit-wise for better overview
    mov dl,[bootdrive] ; select boot drive
    mov al, 59         ; read n sectors
    mov ch,  0         ; cylinder = 0
    mov cl,  2         ; sector   = 2
    mov dh,  0         ; head     = 0
    mov ah,  2         ; function "read" 
    int 0x13         
    jc load_kernel     ; trouble? try again

    ; show loading message
    mov si,loadmsg
    call print_string
    call Waitingloop

;;;;;;;;;;;;;
; A20-Gate  ;
;;;;;;;;;;;;;	

    in  al, 0x92      ; switch A20 gate via fast A20 port 92
    cmp al, 0xff      ; if it reads 0xFF, nothing's implemented on this port
    je .no_fast_A20
   
    or  al, 2         ; set A20_Gate_Bit (bit 1)
    and al, ~1        ; clear INIT_NOW bit (don't reset pc...)
    out 0x92, al
    jmp .A20_done
   
.no_fast_A20:         ; no fast shortcut -> use the slow kbc...
    call empty_8042 
   
    mov al, 0xD1      ; kbc command: write to output port
    out 0x64, al
    call empty_8042
   
    mov al, 0xDF      ; writing this to kbc output port enables A20
    out 0x60, al
    call empty_8042

.A20_done:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Load GDT, switch to PM, and jump to kernel ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;		
	
    cli               ; clear interrupts
    lgdt [gdtr]       ; load GDT via GDTR (defined in file "gtd.inc")	

    mov eax, cr0      ; switch-over to Protected Mode
    or  eax, 1        ; set bit 0 of CR0 register
    mov cr0, eax      ;	

    jmp 0x8:0x8000    ; this is a 16-bit-FAR-Jmp, but CS is loaded with "index" 8 in GDT 
                      ; hence, the code will be interpreted as 32 bit from here on
					  ; the address can be found in the linker script (phys)

;;;;;;;;;
; Calls ;
;;;;;;;;;
 
print_string:
    mov ah, 0x0E      ; VGA BIOS fnct. 0x0E: teletype
.loop:   
    lodsb             ; grab a byte from SI
    test al, al       ; NUL?
    jz .done          ; if the result is zero, get out
    int 0x10          ; otherwise, print out the character!
    jmp .loop
.done:
    ret

empty_8042:
    call Waitingloop
    in al, 0x64
    cmp al, 0xff      ; ... no real kbc at all?
    je .done
   
    test al, 1        ; something in input buffer?
    jz .no_output
    call Waitingloop
    in al, 0x60       ; yes: read buffer
    jmp empty_8042    ; and try again
   
.no_output:
    test al, 2        ; command buffer empty?
    jnz empty_8042    ; no: we can't send anything new till it's empty
.done:
    ret

Waitingloop:                   
    mov cx,0xFFFF
.loop_start:
    dec cx     
    jnz .loop_start
    ret       
 	
;;;;;;;;;;;;
; Includes ;
;;;;;;;;;;;;

    %include "gdt.inc"
	
;;;;;;;;
; data ;
;;;;;;;;

    bootdrive db 0    ; boot drive
    loadmsg db "bootloader message: loading kernel ...",13,10,0
    
    times 510-($-$$) hlt
    db 0x55
    db 0xAA
assembler-kernel:

Code: Select all

[Bits 32]
section .text          ; ld needs that for coff format

[global KernelStart]
KernelStart:
    mov    ax, 0x10
    mov    ds, ax      ; data descriptor --> data, stack and extra segment
    mov    ss, ax           
    mov    es, ax
    xor    eax, eax    ; null desriptor --> FS and GS
    mov    fs, ax
    mov    gs, ax
    mov    esp, 0x200000 ; set stack below 2 MB limit

[extern _main]         ; entry point in ckernel.c
    call _main ; ->-> C-Kernel
    jmp $
madeofstaples
Member
Member
Posts: 204
Joined: Thu Apr 12, 2007 8:15 am
Location: Michigan

Re: Loading more than 54 sectors [SOLVED]

Post by madeofstaples »

ehenkes wrote:For comparison. Currently, I use this bootstrap loader and A20Gate & PM switch:

bootloader:

Code: Select all

...
;;;;;;;;;;;;;
; A20-Gate  ;
;;;;;;;;;;;;;	

    in  al, 0x92      ; switch A20 gate via fast A20 port 92
    cmp al, 0xff      ; if it reads 0xFF, nothing's implemented on this port
    je .no_fast_A20
...
! You should ask the BIOS if Fast A20 is available before attempting to use it (Int 15/AX=2403h).

You should also check if the A20 line is even disabled in the first place.
Some people are offended by the verifiable truth; such people tend to remain blissfully unencumbered by fact.
If you are one of these people, my posts may cause considerable discomfort. Read at your own risk.
Post Reply