summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0686428)
raw | patch | inline | side by side (parent: 0686428)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sun, 9 Aug 2020 16:09:04 +0000 (19:09 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Sun, 9 Aug 2020 16:09:04 +0000 (19:09 +0300) |
Boot486/boot0.S | patch | blob | history |
diff --git a/Boot486/boot0.S b/Boot486/boot0.S
index efc93c93af85ff4de898bc4409353cf0df509c57..409a28a9126c5c83480298a5e2c260922f0f8c64 100644 (file)
--- a/Boot486/boot0.S
+++ b/Boot486/boot0.S
.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
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
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
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
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
jnc lba2chs__success
mov $msg_chs_error, %si
call print
- cli
hlt
lba2chs__success:
mov %dx, BootDiskDxAdr
# 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
-
# =========================================================================== #
# =========================================================================== #
# =========================================================================== #