fernlader2/src/nbp.S

91 lines
2.7 KiB
ArmAsm
Raw Normal View History

2026-02-18 10:40:02 +01:00
// vim: ft=gas:et:sw=12:ts=12:sts=12
.include "src/mode.S"
.global _start
.text
.code16
// _start: entry point
_start: cli
cld
mov %ss, %ax
mov %ax, %cs:real_ss
xor %eax, %eax
mov %es, %ax
shl $4, %eax
movzwl %bx, %ebx
add %eax, %ebx
mov %ebx, %cs:PXENV
xor %eax, %eax
xor %ebx, %ebx
mov %sp, %bx
mov %ss:6(%bx), %ax
mov %ss:4(%bx), %bx
shl $4, %eax
add %eax, %ebx
mov %ebx, %cs:exPXE
2026-02-18 10:40:02 +01:00
mov %sp, %bp
xor %ax, %ax
mov %ax, %ds
mov %ax, %es
// initialize our own BSS section
mov $_bss_start, %di
mov $_bss_end, %cx
sub %di, %cx
xor %al, %al
rep stosb
2026-02-18 10:40:02 +01:00
// a20_enable: Allow use of 'high' (>1Mb) memory
a20_enable: // Of all the ways to toggle A20, we only try the Fast A20 Gate.
// This is known to cause problems on some ancient systems,
// but as our bootloader exclusively runs on 64-bit machines,
// we should not run into any of those systems.
// Modern machines apparently don't even have the A20 line anymore.
inb $0x92, %al
or $2, %al
outb %al, $0x92
// prot_enter: Set up GDT, switch into 32-bit protected mode.
2026-02-18 13:40:19 +01:00
prot_enter: lgdt GDT_PTR
2026-02-18 10:40:02 +01:00
PROT
PROT32
.code32
jmp main
.data
.global PXENV
PXENV: .long 0
.global exPXE
exPXE: .long 0
2026-02-18 10:40:02 +01:00
.global real_ss
real_ss: .word 0
.global GDT
GDT: // entry 0: null descriptor
.space 8, 0
// entry 1: 16-bit code segment
.byte 0xFF, 0xFF, 0, 0, 0, 0b10011010, 0x8F, 0
// entry 2: 16-bit data segment
.byte 0xFF, 0xFF, 0, 0, 0, 0b10010010, 0x8F, 0
// entry 3: 32-bit code segment
.byte 0xFF, 0xFF, 0, 0, 0, 0b10011010, 0xCF, 0
// entry 4: 32-bit data segment
.byte 0xFF, 0xFF, 0, 0, 0, 0b10010010, 0xCF, 0
// TODO: 32-bit TSS
.set GDT_SIZE, . - GDT
GDT_PTR: .word GDT_SIZE - 1
.word GDT
.word 0, 0, 0