metalsvm/arch/x86/kernel/entry.asm
stefan a6a9617775 - add the libc "newlib" and their support into MetalSVM
- programs could be load as module by the bootloader Grub



git-svn-id: http://svn.lfbs.rwth-aachen.de/svn/scc/trunk/MetalSVM@95 315a16e6-25f9-4109-90ae-ca3045a26c18
2010-08-17 09:59:29 +00:00

691 lines
16 KiB
NASM

;
; Copyright 2010 Stefan Lankes, Chair for Operating Systems,
; RWTH Aachen University
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; This file is part of metalsvm.
; This is the kernel's entry point. We could either call main here,
; or we can use this to setup the stack or other nice stuff, like
; perhaps setting up the GDT and segments. Please note that interrupts
; are disabled at this point: More on interrupts later!
[BITS 32]
; We use a special name to map this section at the begin of our kernel
; => Multiboot needs its magic number at the begin of the kernel
SECTION multiboot
global start
start:
mov esp, _sys_stack ; This points the stack to our new stack area
jmp stublet
; This part MUST be 4byte aligned, so we solve that issue using 'ALIGN 4'
ALIGN 4
mboot:
; Multiboot macros to make a few lines later more readable
MULTIBOOT_PAGE_ALIGN equ 1<<0
MULTIBOOT_MEMORY_INFO equ 1<<1
MULTIBOOT_AOUT_KLUDGE equ 1<<16
MULTIBOOT_HEADER_MAGIC equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO | MULTIBOOT_AOUT_KLUDGE
MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
EXTERN code, bss, end
; This is the GRUB Multiboot header. A boot signature
dd MULTIBOOT_HEADER_MAGIC
dd MULTIBOOT_HEADER_FLAGS
dd MULTIBOOT_CHECKSUM
; AOUT kludge - must be physical addresses. Make a note of these:
; The linker script fills in the data for these ones!
dd mboot
dd code
dd bss
dd end
dd start
stublet:
; interpret multiboot information
extern multiboot_init
push ebx
call multiboot_init
pop ebp
; This is an endless loop here. Make a note of this: Later on, we
; will insert an 'extern _main', followed by 'call _main', right
; before the 'jmp $'.
extern main
call main
jmp $
; This will set up our new segment registers. We need to do
; something special in order to set CS. We do what is called a
; far jump. A jump that includes a segment as well as an offset.
; This is declared in C as 'extern void gdt_flush();'
global gdt_flush
extern gp
gdt_flush:
lgdt [gp]
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:flush2
flush2:
ret
; Loads the IDT defined in '_idtp' into the processor.
; This is declared in C as 'extern void idt_load();'
global idt_load
extern idtp
idt_load:
lidt [idtp]
ret
; In just a few pages in this tutorial, we will add our Interrupt
; Service Routines (ISRs) right here!
global isr0
global isr1
global isr2
global isr3
global isr4
global isr5
global isr6
global isr7
global isr8
global isr9
global isr10
global isr11
global isr12
global isr13
global isr14
global isr15
global isr16
global isr17
global isr18
global isr19
global isr20
global isr21
global isr22
global isr23
global isr24
global isr25
global isr26
global isr27
global isr28
global isr29
global isr30
global isr31
global isrsyscall
; 0: Divide By Zero Exception
isr0:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 0
jmp isr_common_stub
; 1: Debug Exception
isr1:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 1
jmp isr_common_stub
; 2: Non Maskable Interrupt Exception
isr2:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 2
jmp isr_common_stub
; 3: Int 3 Exception
isr3:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 3
jmp isr_common_stub
; 4: INTO Exception
isr4:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 4
jmp isr_common_stub
; 5: Out of Bounds Exception
isr5:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 5
jmp isr_common_stub
; 6: Invalid Opcode Exception
isr6:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 6
jmp isr_common_stub
; 7: Coprocessor Not Available Exception
isr7:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 7
jmp isr_common_stub
; 8: Double Fault Exception (With Error Code!)
isr8:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 8
jmp isr_common_stub
; 9: Coprocessor Segment Overrun Exception
isr9:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 9
jmp isr_common_stub
; 10: Bad TSS Exception (With Error Code!)
isr10:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 10
jmp isr_common_stub
; 11: Segment Not Present Exception (With Error Code!)
isr11:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 11
jmp isr_common_stub
; 12: Stack Fault Exception (With Error Code!)
isr12:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 12
jmp isr_common_stub
; 13: General Protection Fault Exception (With Error Code!)
isr13:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 13
jmp isr_common_stub
; 14: Page Fault Exception (With Error Code!)
isr14:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 14
jmp isr_common_stub
; 15: Reserved Exception
isr15:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 15
jmp isr_common_stub
; 16: Floating Point Exception
isr16:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 16
jmp isr_common_stub
; 17: Alignment Check Exception
isr17:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 17
jmp isr_common_stub
; 18: Machine Check Exception
isr18:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 18
jmp isr_common_stub
; 19: Reserved
isr19:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 19
jmp isr_common_stub
; 20: Reserved
isr20:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 20
jmp isr_common_stub
; 21: Reserved
isr21:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 21
jmp isr_common_stub
; 22: Reserved
isr22:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 22
jmp isr_common_stub
; 23: Reserved
isr23:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 23
jmp isr_common_stub
; 24: Reserved
isr24:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 24
jmp isr_common_stub
; 25: Reserved
isr25:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 25
jmp isr_common_stub
; 26: Reserved
isr26:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 26
jmp isr_common_stub
; 27: Reserved
isr27:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 27
jmp isr_common_stub
; 28: Reserved
isr28:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 28
jmp isr_common_stub
; 29: Reserved
isr29:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 29
jmp isr_common_stub
; 30: Reserved
isr30:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 30
jmp isr_common_stub
; 31: Reserved
isr31:
; isr0 - isr31 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 31
jmp isr_common_stub
extern syscall_handler
; used to realize system calls
isrsyscall:
push ebp
push edi
push esi
push edx
push ecx
push ebx
push eax
call syscall_handler
add esp, 4 ; eax contains the return value
; => we did not restore eax
pop ebx
pop ecx
pop edx
pop esi
pop edi
pop ebp
iret
; We call a C function in here. We need to let the assembler know
; that 'fault_handler' exists in another file
extern fault_handler
; This is our common ISR stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
; and finally restores the stack frame.
isr_common_stub:
pusha
push esp
call fault_handler
add esp, 4
popa
add esp, 8
iret
global irq0
global irq1
global irq2
global irq3
global irq4
global irq5
global irq6
global irq7
global irq8
global irq9
global irq10
global irq11
global irq12
global irq13
global irq14
global irq15
extern irq_handler
extern current_task
extern scheduler
global reschedule
reschedule:
cli
; eax could change across a function call
; => we have not to save the original eax value
push ebx
push DWORD [current_task]
call scheduler
pop ebx
mov eax, DWORD [current_task]
cmp eax, ebx
je no_task_switch1
mov eax, [eax]
add ax, WORD 5
mov bx, WORD 8
mul bx
mov [hack1+5], ax
hack1:
jmp 0x00 : 0xDEADBEAF
no_task_switch1:
pop ebx
sti
ret
; 32: IRQ0
irq0:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 32
pusha
push esp
call irq_handler
add esp, 4
mov eax, DWORD [current_task]
push eax
call scheduler
pop ebx
mov eax, DWORD [current_task]
cmp eax, ebx
je no_task_switch2
mov eax, [eax]
add ax, WORD 5
mov bx, WORD 8
mul bx
mov [hack2+5], ax
hack2:
jmp 0x00 : 0xDEADBEAF
no_task_switch2:
popa
add esp, 8
iret
; 33: IRQ1
irq1:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 33
jmp irq_common_stub
; 34: IRQ2
irq2:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 34
jmp irq_common_stub
; 35: IRQ3
irq3:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 35
jmp irq_common_stub
; 36: IRQ4
irq4:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 36
jmp irq_common_stub
; 37: IRQ5
irq5:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 37
jmp irq_common_stub
; 38: IRQ6
irq6:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 38
jmp irq_common_stub
; 39: IRQ7
irq7:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 39
jmp irq_common_stub
; 40: IRQ8
irq8:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 40
jmp irq_common_stub
; 41: IRQ9
irq9:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 41
jmp irq_common_stub
; 42: IRQ10
irq10:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 42
jmp irq_common_stub
; 43: IRQ11
irq11:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 43
jmp irq_common_stub
; 44: IRQ12
irq12:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 44
jmp irq_common_stub
; 45: IRQ13
irq13:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 45
jmp irq_common_stub
; 46: IRQ14
irq14:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 46
jmp irq_common_stub
; 47: IRQ15
irq15:
; irq0 - irq15 are registered as "Interrupt Gate"
; Therefore, the interrupt flag (IF) is already cleared.
; cli
push byte 0
push byte 47
jmp irq_common_stub
irq_common_stub:
pusha
push esp
call irq_handler
add esp, 4
popa
add esp, 8
iret
; Here is the definition of our BSS section. Right now, we'll use
; it just to store the stack. Remember that a stack actually grows
; downwards, so we declare the size of the data before declaring
; the identifier '_sys_stack'
SECTION .bss
resb 8192 ; This reserves 8KBytes of memory here
_sys_stack: