section .boot bits 16 global boot boot: jmp main 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 'Booting matOs', 0 main: sti ; enable virtual interupts mov [disk],dl ; save disk used to boot by bios call display_enable push hello 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 ; http://www.ctyme.com/intr/rb-0607.htm ; Bios read first 512 bytes, read next disk sector mov ah, 0x2 ;read sectors mov al, 15 ;sectors to read mov ch, 0 ;cylinder idx mov dh, 0 ;head idx mov cl, 2 ;sector idx mov dl, [disk] ;disk idx mov bx, copy_target;target pointer int 0x13 cli ; disable interruption when setting GDT ; 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 ; In protected mode we need to add the segment selector ; 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 ; limit [0:15] dw 0x0 ; base [0:15] db 0x0 ; base [16:23] db 10011010b ; access byte: Present(1)| Priv(2) 0 ->kernel 3->userspace | 1 | Executable(1) | Direction/Conformity (1) | RW(1) | Accessed(1) db 11001111b ; Granularity(1) | Size (1) 0-> 16bit mode 1->32protected mode | 0 | 0 | Limit [16:19] db 0x0 ; base [24:31] 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 disk: db 0x0 CODE_SEG equ gdt_code - gdt_start DATA_SEG equ gdt_data - gdt_start times 510 - ($-$$) db 0 dw 0xaa55 copy_target: bits 32 boot2: mov ax, DATA_SEG ; set all segments to point to DATA_SEG https://en.wikipedia.org/wiki/X86_memory_segmentation mov ds, ax ; Data segment mov es, ax ; Extra Segment (for string operation) mov fs, ax ; No Specific use mov gs, ax ; No Specific use mov ss, ax ; stack segment 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: mov esp,kernel_stack_top extern kmain call kmain cli hlt hello32: db "Hello 32 bits world!",0 section .bss align 4 kernel_stack_bottom: equ $ resb 16384 ; 16 KB kernel_stack_top: