145 lines
2.4 KiB
NASM
145 lines
2.4 KiB
NASM
bits 16 ; mode 16bits
|
|
org 0x7C00 ; mbr ae loaded at 0x7C00
|
|
|
|
jmp boot
|
|
|
|
display_enable:
|
|
push bp
|
|
mov bp, sp
|
|
mov ah, 0h ; 00h Set Video Mode
|
|
mov al, 07h ; Txt, monochrome, 80x25
|
|
|
|
int 10h
|
|
|
|
mov sp, bp
|
|
pop bp
|
|
ret
|
|
|
|
print:
|
|
push bp
|
|
mov bp, sp
|
|
mov si, [bp + 4]; put first function arg in si. sp is stask pointer
|
|
.loop:
|
|
lodsb ; load si content into al then inc si
|
|
cmp al, 0;
|
|
je .end
|
|
|
|
mov ah, 0eh
|
|
mov bx, 0
|
|
int 10h
|
|
|
|
jmp .loop
|
|
|
|
.end:
|
|
mov sp, bp
|
|
pop bp
|
|
ret
|
|
|
|
println:
|
|
push bp
|
|
mov bp, sp
|
|
push word [bp + 4]
|
|
call print
|
|
add sp, 2
|
|
|
|
mov ah, 03h ; read cursor position
|
|
int 10h ; row number in dh. Col in dl
|
|
|
|
inc dh ; goto next line
|
|
mov dl, 0
|
|
|
|
mov ah, 02h ; Set Cursor Position
|
|
int 10h
|
|
mov sp, bp
|
|
pop bp
|
|
ret
|
|
|
|
hello db 'Hello world', 0
|
|
name db 'This is a name', 0
|
|
|
|
boot:
|
|
sti ; enable virtual interupts
|
|
|
|
call display_enable
|
|
|
|
push hello
|
|
call println
|
|
add sp, 2
|
|
|
|
push name
|
|
call println
|
|
add sp, 2
|
|
|
|
; Switch in 32bits Protected mode
|
|
|
|
; Activate A20 http://wiki.osdev.org/A20_Line to be able to access more than 1Mb memory
|
|
mov ah, 0h
|
|
mov ax, 0x2401
|
|
int 0x15
|
|
|
|
; Change video mode to display VGA
|
|
mov ax, 0x3
|
|
int 0x10
|
|
|
|
|
|
cli ; clear interruption flag
|
|
|
|
; switch in 32 bits
|
|
lgdt [gdt_pointer] ; switch in 32bits here
|
|
mov eax, cr0
|
|
or eax,0x1; set the protected mode bit on special CPU reg cr0
|
|
mov cr0, eax
|
|
jmp CODE_SEG:boot2
|
|
|
|
; GDT table desciption could be found http://wiki.osdev.org/Global_Descriptor_Table
|
|
; here we define the 3 64bits segment needed: null segment, code segment and data segment
|
|
gdt_start: ;null segment
|
|
dq 0x0
|
|
gdt_code: ;code segment
|
|
dw 0xFFFF
|
|
dw 0x0
|
|
db 0x0
|
|
db 10011010b
|
|
db 11001111b
|
|
db 0x0
|
|
gdt_data:
|
|
dw 0xFFFF
|
|
dw 0x0
|
|
db 0x0
|
|
db 10010010b
|
|
db 11001111b
|
|
db 0x0
|
|
gdt_end:
|
|
gdt_pointer:
|
|
dw gdt_end - gdt_start
|
|
dd gdt_start
|
|
|
|
CODE_SEG equ gdt_code - gdt_start
|
|
DATA_SEG equ gdt_data - gdt_start
|
|
|
|
bits 32
|
|
boot2:
|
|
mov ax, DATA_SEG
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov fs, ax
|
|
mov gs, ax
|
|
mov ss, ax
|
|
mov esi,hello32
|
|
mov ebx,0xb8000 ; Cannot use BIOS anymore, use VGA Text buffer instead
|
|
|
|
.loop32:
|
|
lodsb
|
|
or al,al
|
|
jz halt
|
|
or eax,0x0100 ; blue bg
|
|
mov word [ebx], ax
|
|
add ebx,2
|
|
jmp .loop32
|
|
halt:
|
|
cli
|
|
hlt
|
|
hello32: db "Hello world!",0
|
|
times 510 - ($ - $$) db 0 ; fill up to 510 with 0
|
|
dw 0xAA55 ; MBR magic number
|