From aaae5582f88ff457c956ea6cd21835db1c7f4bf1 Mon Sep 17 00:00:00 2001 From: DeaDDooMER Date: Sun, 9 Aug 2020 19:09:04 +0300 Subject: [PATCH] boot0: generate memory map for first 1Mb with older method --- Boot486/boot0.S | 330 +++++++++++++++++++++++++----------------------- 1 file changed, 172 insertions(+), 158 deletions(-) diff --git a/Boot486/boot0.S b/Boot486/boot0.S index efc93c9..409a28a 100644 --- a/Boot486/boot0.S +++ b/Boot486/boot0.S @@ -21,15 +21,15 @@ .set MemoryMapAdr, 0x7e0A .set ImageBase, 0x100000 +_start: + # =========================================================================== # -# Stage 1 +# Setup canonical %cs:%eip, segment registers %ds, %es, %fs, %gs, %ss and +# stack %sp # =========================================================================== # -_start: - .code16 -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 @@ -41,51 +41,181 @@ stage1: mov $STACK1, %sp mov %dx, BootDiskAdr - call mapmem - sti -# 2. Enable A20 gate - call enableA20 +# =========================================================================== # +# 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 + +readsectors: + # %cx = Cylider+Sector; %es = 64k buf + xor %ah, %ah + int $0x13 - mov current_sector, %ax - shl $5, %ax - add $(BUFFER / 16), %ax - mov %ax, %es - call readsectors + xor %bx, %bx + mov $0x2, %ah + mov $READBLOCKS, %al + clc + int $0x13 - mov current_sector, %ax - add $READBLOCKS, %ax - mov %ax, current_sector - cmp $((kernel_code_end - kernel_code_start + 511) / 512), %ax - jl stage1__read + jnc readsectors__success -# 4. Disable interrupts and load GDT - mov $msg_protected_mode, %si + /* 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 @@ -93,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 @@ -101,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 @@ -124,75 +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_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 $1, (MemoryMapAdr + 0) # num - movl $0x100000, (MemoryMapAdr + 4) # base (low) - movl $0, (MemoryMapAdr + 8) # base (high) - movl $0, (MemoryMapAdr + 12) # len (low) - movl $0, (MemoryMapAdr + 16) # len (high) - movl $1, (MemoryMapAdr + 20) # 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 + 12) # len (low) - #jmp mapmem_done - -mapmem_done: - popa - ret # <============ - -mapmem_failed: - mov $msg_mapmem_failed, %si - call print - cli - hlt - # =========================================================================== # # Convert LBA to CHS # input: %ax = LBA %dl = disk @@ -215,7 +287,6 @@ lba2chs: jnc lba2chs__success mov $msg_chs_error, %si call print - cli hlt lba2chs__success: mov %dx, BootDiskDxAdr @@ -270,63 +341,6 @@ 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 - -# =========================================================================== # -# Enable A20 Line -# =========================================================================== # - -.code16 - -enableA20: - cli - 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: - sti - ret - # =========================================================================== # # =========================================================================== # # =========================================================================== # -- 2.29.2