orion_old/kernel/arch/i386/boot.S

194 lines
3.9 KiB
ArmAsm

# Declare constants for the multiboot header.
.set ALIGN, 1<<0 # align loaded modules on page boundaries
.set MEMINFO, 1<<1 # provide memory map
.set FLAGS, ALIGN | MEMINFO # this is the Multiboot 'flag' field
.set MAGIC, 0x1BADB002 # 'magic number' lets bootloader find the header
.set CHECKSUM, -(MAGIC + FLAGS) # checksum of above, to prove we are multiboot
# Declare a header as in the Multiboot Standard.
.section .multiboot
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
# Reserve a stack for the initial thread.
.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
# The kernel entry point.
.section .text
.global _start
.type _start, @function
_start:
movl $stack_top, %esp
# Call the global constructors.
call _init
# Call early kernel (init GDT, IDT and other)
call kernel_early_main
# Transfer control to the main kernel.
call kernel_main
# Hang if kernel_main unexpectedly returns.
cli
1: hlt
jmp 1b
.size _start, . - _start
.global gdt_flush
gdt_flush:
mov 0x4(%esp),%eax
lgdt (%eax)
mov $0x10,%ax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
mov %ax,%gs
mov %ax,%ss
jmp $0x8,$.flush
.flush:
ret
// IDT
.global idt_flush
idt_flush:
mov 0x4(%esp),%eax
lidt (%eax)
ret
// Interrupt Service Routine
.macro ISR_NOERRCODE num
.global isr\num
isr\num:
cli
push $0x0
push $0x\num
jmp isr_common_stub
.endm
.macro ISR_ERRCODE num
.global isr\num
isr\num:
cli
push $0x\num
jmp isr_common_stub
.endm
// This macro creates a stub for an IRQ - the first parameter is
// the IRQ number, the second is the ISR number it is remapped to.
.macro IRQ num to
.global irq\num
irq\num:
cli
push $0x0
push $0x\to
jmp irq_common_stub
.endm
ISR_NOERRCODE 0 // Divide by sero
ISR_NOERRCODE 1 // Debug
ISR_NOERRCODE 2 // Non-maskable Interrupt
ISR_NOERRCODE 3 // Breakpoint
ISR_NOERRCODE 4 // Overflow
ISR_NOERRCODE 5 // Bound Range Exceeded
ISR_NOERRCODE 6 // Invalid Opcode
ISR_NOERRCODE 7 // Device Not Avalible
ISR_ERRCODE 8 // Double Fault
ISR_NOERRCODE 9 // Coprocessor Segment Overrun
ISR_ERRCODE 10 // Invalid TSS
ISR_ERRCODE 11
ISR_ERRCODE 12
ISR_ERRCODE 13
ISR_ERRCODE 14
ISR_NOERRCODE 15
ISR_NOERRCODE 16
ISR_ERRCODE 17
ISR_NOERRCODE 18
ISR_NOERRCODE 19
ISR_NOERRCODE 20
ISR_NOERRCODE 21
ISR_NOERRCODE 22
ISR_NOERRCODE 23
ISR_NOERRCODE 24
ISR_NOERRCODE 25
ISR_NOERRCODE 26
ISR_NOERRCODE 27
ISR_NOERRCODE 28
ISR_NOERRCODE 29
ISR_ERRCODE 30
ISR_NOERRCODE 31
IRQ 0, 32
IRQ 1, 33
IRQ 2, 34
IRQ 3, 35
IRQ 4, 36
IRQ 5, 37
IRQ 6, 38
IRQ 7, 39
IRQ 8, 40
IRQ 9, 41
IRQ 10, 42
IRQ 11, 43
IRQ 12, 44
IRQ 13, 45
IRQ 14, 46
IRQ 15, 47
isr_common_stub:
pusha
mov %ds,%ax
push %eax
mov $0x10,%ax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
mov %ax,%gs
call isr_handler
pop %eax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
mov %ax,%gs
popa
add $0x8,%esp
sti
iret
//This is our common IRQ stub. It saves the processor state, sets
//up for kernel mode segments, calls the C-level fault handler,
//and finally restores the stack frame.
irq_common_stub:
pusha //Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov %ds, %ax //Lower 16-bits of eax = ds.
push %eax //save the data segment descriptor
mov $0x10, %ax //load the kernel data segment descriptor
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
call irq_handler
pop %ebx //reload the original data segment descriptor
mov %bx, %ds
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
popa //Pops edi,esi,ebp...
add $0x8, %esp //Cleans up the pushed error code and pushed ISR number
sti
iret