X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=Boot486%2Fboot0.S;h=409a28a9126c5c83480298a5e2c260922f0f8c64;hb=HEAD;hp=21608cbc66d797064902c57826ca8fb215702b46;hpb=21efe406346aee850b1fe0f3050f10c28310f5bf;p=bmbb.git diff --git a/Boot486/boot0.S b/Boot486/boot0.S index 21608cb..409a28a 100644 --- a/Boot486/boot0.S +++ b/Boot486/boot0.S @@ -19,16 +19,17 @@ .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: