DEADSOFTWARE

boot0: generate memory map for first 1Mb with older method
[bmbb.git] / Boot486 / boot0.S
index 21608cbc66d797064902c57826ca8fb215702b46..409a28a9126c5c83480298a5e2c260922f0f8c64 100644 (file)
 .set BootDiskDxAdr, 0x7e06
 .set BootDiskCxAdr, 0x7e08
 .set MemoryMapAdr, 0x7e0A
-.set ImageBase, 0x1000000
+.set ImageBase, 0x100000
+
+_start:
 
 # =========================================================================== #
-# Stage 1
+# Setup canonical %cs:%eip, segment registers %ds, %es, %fs, %gs, %ss and
+# stack %sp
 # =========================================================================== #
 
 .code16
-_start:
-stage1:
-# 1. Setup canonical %cs:%eip, segment registers %ds, %es, %fs, %gs, %ss and stack %sp
+
        cli
        ljmp $0x0, $canonized_label; canonized_label:
        xor %ax, %ax
@@ -40,51 +41,181 @@ stage1:
        mov $STACK1, %sp
 
        mov %dx, BootDiskAdr
-       call mapmem
 
-# 2. Enable A20 gate
-       call enable_A20
-       sti
+# =========================================================================== #
+# Make memory map for kernel
+# =========================================================================== #
+
+       pusha
+       movl $0, MemoryMapAdr
+       xor %ebx, %ebx
+       mov $(MemoryMapAdr + 4), %di
+
+mapmem_loop:
+       mov $0xe820, %eax
+       mov $20, %ecx
+       mov $0x0534D4150, %edx
+       int $0x15
+       jc mapmem_method_88
+       cmp %edx, %eax
+       jne mapmem_method_88
+       cmp $0, %ebx
+       je mapmem_done
+       add $20, %di
+       incl MemoryMapAdr
+       jmp mapmem_loop
+
+mapmem_method_88:
+       #####
+       ### function:
+       ###   int 0x15 + %ah = 0x88
+       ### input:
+       ###   none
+       ### output:
+       ###   cf clear:
+       ###     %ax = available memory starting at 0x100000 in KB
+       ###   cf set:
+       ###     %ah = error code
+       ### note:
+       ###   some bioses do not clear cf, do it manually
+       #####
+
+       movl $3,        (MemoryMapAdr + 0)  # num
+       xor %eax, %eax
+       mov $1, %ebx
+       # free low memory
+       movl %eax,      (MemoryMapAdr + 4)  # base (low)
+       movl %eax,      (MemoryMapAdr + 8)  # base (high)
+       movl $0x080000, (MemoryMapAdr + 12) # len (low)
+       movl %eax,      (MemoryMapAdr + 16) # len (high)
+       movl %ebx,      (MemoryMapAdr + 20) # type
+       # reserved harware memory
+       movl $0x080000, (MemoryMapAdr + 24) # base (low)
+       movl %eax,      (MemoryMapAdr + 28) # base (high)
+       movl $0x080000, (MemoryMapAdr + 32) # len (low)
+       movl %eax,      (MemoryMapAdr + 36) # len (high)
+       movl %eax,      (MemoryMapAdr + 40) # type
+       # free high memory
+       movl $0x100000, (MemoryMapAdr + 44) # base (low)
+       movl %eax,      (MemoryMapAdr + 48) # base (high)
+       #movl $0x700000, (MemoryMapAdr + 52) # len (low)
+       movl %eax,      (MemoryMapAdr + 56) # len (high)
+       movl %ebx,      (MemoryMapAdr + 60) # type
+
+       clc
+       mov $0x88, %ah
+       int $0x15
+       jc mapmem_failed
+       test %ax, %ax
+       je mapmem_failed
+       movzx %ax, %eax
+       shl $10, %eax
+       movl %eax, (MemoryMapAdr + 52) # len (low)
+       jmp mapmem_done
+
+mapmem_failed:
+       mov $msg_mapmem_failed, %si
+       call print
+       hlt
+
+mapmem_done:
+       popa
+
+# =========================================================================== #
+# Enable A20 Line
+# =========================================================================== #
+
+enableA20:
+       xor %cx, %cx
+enableA20_1:
+       inc %cx
+       jz enableA20_3
+       in $0x64, %al
+       test $0x2, %al
+       jnz enableA20_1
+       mov $0xd1, %al
+       out %al, $0x64
+enableA20_2:
+       in $0x64, %al
+       test $0x2, %al
+       jnz enableA20_2
+       mov $0xdf, %al
+       out %al, $0x60
+enableA20_3:
 
-# 3. Reset disk controller (%dl and %dh initialized by bios) and read Kernel into buffer
+# =========================================================================== #
+# Reset disk controller (%dl and %dh initialized by bios) and read Kernel
+# into buffer
+# =========================================================================== #
+       sti
        movl $(kernel_code_end - kernel_code_start), KernelSizeAdr
 
-       stage1__read:
-               mov current_sector, %ax
-               add $1, %ax
-               call lba2chs
+stage1__read:
+       mov current_sector, %ax
+       add $1, %ax
+       call lba2chs
 
-               mov current_sector, %ax
-               shl $5, %ax
-               add $(BUFFER / 16), %ax
-               mov %ax, %es
-               call readsectors
+       mov current_sector, %ax
+       shl $5, %ax
+       add $(BUFFER / 16), %ax
+       mov %ax, %es
 
-               mov current_sector, %ax
-               add $READBLOCKS, %ax
-               mov %ax, current_sector
-               cmp $((kernel_code_end - kernel_code_start + 511) / 512), %ax
-               jl stage1__read
+readsectors:
+       # %cx = Cylider+Sector; %es = 64k buf
+        xor %ah, %ah
+        int $0x13
 
-# 4. Disable interrupts and load GDT
-       mov $msg_protected_mode, %si
+        xor %bx, %bx
+        mov $0x2, %ah
+        mov $READBLOCKS, %al
+       clc
+        int $0x13
+
+        jnc readsectors__success
+
+       /* zero if sectors not readed */
+       or %ah, %ah
+       jnz readsectors__success
+
+       mov $msg_kernel_read_failed, %si
        call print
+       #cli
+       hlt
+readsectors__success:
+
+       mov current_sector, %ax
+       add $READBLOCKS, %ax
+       mov %ax, current_sector
+       cmp $((kernel_code_end - kernel_code_start + 511) / 512), %ax
+       jl stage1__read
        cli
+
+# =========================================================================== #
+# Load GDT
+# =========================================================================== #
+       mov $msg_protected_mode, %si
+       call print
        lgdt gdt_info
 
-# 5. Switch to protected mode
+# =========================================================================== #
+# Switch to protected mode
+# =========================================================================== #
        mov %cr0, %eax
        or $1, %al
        mov %eax, %cr0
        jmp $8, $stage2
 
 # =========================================================================== #
-# Stage 2
+# 32 bit stage begins
 # =========================================================================== #
 
 .code32
+
 stage2:
-# 6. Setup data segments %ds, %es, %fs, %gs  and stack %sp
+
+# =========================================================================== #
+# Setup data segments %ds, %es, %fs, %gs and stack %sp
+# =========================================================================== #
        mov $16, %ax
        mov %ax, %ds
        mov %ax, %ss
@@ -92,7 +223,11 @@ stage2:
        mov %ax, %fs
        mov %ax, %gs
        mov $STACK2, %sp
-# 7. Copy Kernel from buffer
+
+# =========================================================================== #
+# Copy Kernel from buffer
+# =========================================================================== #
+
        xor %eax, %eax
        stage2_copy_loop:
                mov BUFFER(%eax), %bh
@@ -100,9 +235,16 @@ stage2:
                inc %eax
                cmp $(kernel_code_end - kernel_code_start), %eax
                jne stage2_copy_loop
-# 8. Exec Kernel
+
+# =========================================================================== #
+# Jump to Kernel code (never returns)
+# =========================================================================== #
+
        jmp ImageBase
 
+# =========================================================================== #
+# ================================ routines ================================= #
+# =========================================================================== #
 
 # =========================================================================== #
 # Print asciiz string
@@ -123,38 +265,6 @@ print:
                popa
                ret
 
-# =========================================================================== #
-# Make memory map for kernel
-# =========================================================================== #
-
-.code16
-mapmem:
-       pusha
-       movl $0, MemoryMapAdr
-       xor %ebx, %ebx
-       mov $(MemoryMapAdr + 4), %di
-       mapmem__loop:
-               mov $0xe820, %eax
-               mov $20, %ecx
-               mov $0x0534D4150, %edx
-               int $0x15
-               jc mapmem__failed
-               cmp %edx, %eax
-               jne mapmem__failed
-               cmp $0, %ebx
-               je mapmem__done
-               add $20, %di
-               incl MemoryMapAdr
-               jmp mapmem__loop
-       mapmem__done:
-               popa
-               ret # <============
-       mapmem__failed:
-               mov $msg_mapmem_failed, %si
-               call print
-               cli
-               hlt
-
 # =========================================================================== #
 # Convert LBA to CHS
 #   input: %ax = LBA %dl = disk
@@ -177,7 +287,6 @@ lba2chs:
        jnc lba2chs__success
                mov $msg_chs_error, %si
                call print
-               cli
                hlt
        lba2chs__success:
                mov %dx, BootDiskDxAdr
@@ -232,192 +341,13 @@ lba2chs:
 #      pop %es
        ret
 
-# =========================================================================== #
-# Read sectors to buffer
-#   input: %cx = Cylider+Sector; %es = 64k buf
-# =========================================================================== #
-
-.code16
-readsectors:
-        xor %ah, %ah
-        int $0x13
-
-        xor %bx, %bx
-        mov $0x2, %ah
-        mov $READBLOCKS, %al
-       clc
-        int $0x13
-
-        jnc readsectors__success
-
-       /* zero if sectors not readed */
-       or %ah, %ah
-       jnz readsectors__success
-
-       mov $msg_kernel_read_failed, %si
-       call print
-       cli
-       hlt
-
-readsectors__success:
-       ret
-
-# =========================================================================== #
-# Check that A20 Gate is enabled
-#   output: set zero flag if disabled
-#   restore: %ds %es
-# =========================================================================== #
-
-.code16
-check_A20:
-       push %ds
-       push %es
-#      push %ax
-#      push %di
-#      push %si
-
-       xor %ax, %ax
-       mov %ax, %es
-
-       not %ax
-       mov %ax, %ds
-
-       mov $0x0500, %di
-       mov $0x0510, %si
-
-       mov %es:0(%di), %al
-       push %ax
-
-       mov %ds:0(%si), %al
-       push %ax
-
-       movb $0x00, %es:0(%di)
-       movb $0xff, %ds:0(%si)
-
-       cmpb $0xff, %es:0(%di)
-
-       pop %ax
-       mov %es:0(%di), %al
-
-       pop %ax
-       mov %es:0(%di), %al
-
-       mov $0, %ax
-
-       je check_A20__exit
-
-       mov $1, %ax
-
-check_A20__exit:
-#      pop %si
-#      pop %di
-#      pop %ax
-       pop %es
-       pop %ds
-       or %al, %al
-       ret
-
-# =========================================================================== #
-# Enable A20 Gate
-# =========================================================================== #
-
-enable_A20:
-       /* First check */
-       call check_A20
-       jnz enable_A20__success
-
-       /* BIOS method */
-       mov $0x2401, %ax
-       int $0x15
-
-       call check_A20
-       jnz enable_A20__success
-
-       /* Keyboard method 1 */
-       mov $0xd0, %al
-       out %al, $0x64
-
-       call check_A20
-       jnz enable_A20__success
-
-       /* Keyboard method 2 */
-/*
-#      cli
-       
-       call enable_A20__wait1
-       mov $0xad, %al
-       out %al, $0x64
-
-       call enable_A20__wait1
-       mov $0xd0, %al
-       out %al, $0x64
-
-       enable_A20__wait2:
-       in $0x64, %al
-       test $1, %al
-       jz enable_A20__wait2
-
-       in $0x60, %al
-       push %eax
-
-       call enable_A20__wait1
-       mov $0xd1, %al
-       out %al, $0x64
-
-       call enable_A20__wait1
-       pop %eax
-       or $2, %al
-       out %al, $0x64
-
-       call enable_A20__wait1
-       mov $0xae, %al
-       out %al, $0x64
-
-       call enable_A20__wait1
-#      sti
-
-#      call check_A20
-#      jnz enable_A20__success
-*/
-
-       /* Control port A method */
-       mov $1, %al
-       out %al, $0x92
-
-       call check_A20
-       jnz enable_A20__success
-
-       /* Fast method */
-       in $0xee, %al
-
-       call check_A20
-       jnz enable_A20__success
-
-       mov $msg_a20_failed, %si
-       call print
-#      cli
-#      hlt
-
-enable_A20__success:
-       ret
-
-/*
-enable_A20__wait1:
-       in $0x64, %al
-       test $2, %al
-       jnz enable_A20__wait1
-       ret
-*/
-
 # =========================================================================== #
 # =========================================================================== #
 # =========================================================================== #
 
 msg_mapmem_failed: .asciz "1"
-msg_a20_failed: .asciz "2"
 msg_chs_error: .asciz "3"
 msg_kernel_read_failed: .asciz "4"
-
 msg_protected_mode: .asciz ">5"
 
 current_sector: