
git-svn-id: http://svn.lfbs.rwth-aachen.de/svn/scc/trunk/MetalSVM@127 315a16e6-25f9-4109-90ae-ca3045a26c18
161 lines
3.2 KiB
NASM
161 lines
3.2 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 16]
|
|
SECTION .text
|
|
GLOBAL _start
|
|
ORG 0
|
|
struc GDT_STR
|
|
s0_15: resw 1
|
|
b0_15: resw 1
|
|
b16_23: resb 1
|
|
flags: resb 1
|
|
access: resb 1
|
|
b24_31: resb 1
|
|
endstruc
|
|
|
|
gdt_start dw gdt_size
|
|
gdt_ptr dd 0
|
|
|
|
dummy_descriptor: istruc GDT_STR
|
|
at s0_15, dw 0
|
|
at b0_15, dw 0
|
|
at b16_23, db 0
|
|
at flags, db 0
|
|
at access, db 0
|
|
at b24_31, db 0
|
|
iend
|
|
|
|
; 4GB 32-bit code , 9ah = 10011010b = Present, DPL 00,No System, Code Exec/Read.
|
|
code32_descriptor: istruc GDT_STR
|
|
at s0_15, dw 0x0ffff
|
|
at b0_15, dw 0
|
|
at b16_23, db 0
|
|
at flags, db 0x9a
|
|
at access, db 0xcf
|
|
at b24_31, db 0
|
|
iend
|
|
|
|
; 4GB 32-bit data, 92h = 10010010b = Presetn , DPL 00, No System, Data Read/Write
|
|
data32_descriptor: istruc GDT_STR
|
|
at s0_15, dw 0x0ffff
|
|
at b0_15, dw 0
|
|
at b16_23, db 0
|
|
at flags, db 0x92
|
|
at access, db 0xcf
|
|
at b24_31, db 0
|
|
iend
|
|
|
|
gdt_size equ $-(dummy_descriptor)
|
|
msg db "0ello from MetalSVM bootloader!!",0
|
|
|
|
enable_A20:
|
|
call a20wait
|
|
mov al,0xAD
|
|
out 0x64,al
|
|
|
|
call a20wait
|
|
mov al,0xD0
|
|
out 0x64,al
|
|
|
|
call a20wait2
|
|
in al,0x60
|
|
push eax
|
|
|
|
call a20wait
|
|
mov al,0xD1
|
|
out 0x64,al
|
|
|
|
call a20wait
|
|
pop eax
|
|
or al,2
|
|
out 0x60,al
|
|
|
|
call a20wait
|
|
mov al,0xAE
|
|
out 0x64,al
|
|
|
|
call a20wait
|
|
ret
|
|
|
|
a20wait:
|
|
in al,0x64
|
|
test al,2
|
|
jnz a20wait
|
|
ret
|
|
|
|
a20wait2:
|
|
in al,0x64
|
|
test al,1
|
|
jz a20wait2
|
|
ret
|
|
|
|
_realstart:
|
|
cli
|
|
cld
|
|
|
|
mov [msg], BYTE 'H'
|
|
|
|
mov ax, dummy_descriptor
|
|
mov [gdt_ptr], ax
|
|
|
|
mov bx, gdt_start
|
|
lgdt [bx]
|
|
|
|
; call enable_A20
|
|
|
|
; switch to protected mode by setting PE bit
|
|
; we also clear the VM bit
|
|
mov eax, cr0
|
|
or eax, 0x1
|
|
and eax, 0x7FFFFFFF
|
|
mov cr0, eax
|
|
|
|
; far jump
|
|
db 0x66 ; Prefix for 32-bit
|
|
db 0xea ; Opcode for far jump
|
|
dd _pmstart ; Offset to start, 32-bit
|
|
dw 0x08 ; This is the selector for CODE32_DESCRIPTOR,
|
|
; assuming that start address resides in this segment
|
|
|
|
[BITS 32]
|
|
_pmstart:
|
|
; MetalSVM support Multiboot
|
|
; => Therefore, we switch to the same machine state. Afterwards, we jump to our kernel
|
|
mov ax, 0x10
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov fs, ax
|
|
mov gs, ax
|
|
mov ss, ax
|
|
mov eax, 0x2BAD002
|
|
xor ebx, ebx ; => it exists n valid multiboot information structure
|
|
jmp 0x08 : 0x100000
|
|
|
|
TIMES 4080 - ($-$$) DB 0
|
|
|
|
[BITS 16]
|
|
_start:
|
|
jmp _realstart
|
|
|
|
TIMES 4096 - ($-$$) DB 0
|