;=----------------------------------------------------------------------------=; ; GNU GPL OS/K ; ; ; ; Authors: spectral` ; ; NeoX ; ; ; ; Desc: Kernel (second stage) Loader for OS/K ; ; (x86_64 architecture only) ; ;=----------------------------------------------------------------------------=; [ORG 0x1000] pop ax mov [Bootdrv], ax jmp main ;; DATA %define TRAM 0x0B8000 ; [T]ext[RAM] %define VRAM 0x0A0000 ; [V]ideo[RAM] Bootdrv db 0x00 VGA_HEIGHT dq 0 VIDEO_MODE dw 0 ;; GDT WITH DOC GDT64: NULL_SELECTOR: ;; null selector within 64 bits dw GDT_LENGTH ; limit of GDT dw GDT64 ; linear address of GDT dd 0x0 CODE_SELECTOR: ;; 32-bit code selector (ring 0) dw 0x0FFFF ; Segment Limit 15:00 db 0x0, 0x0, 0x0 ; Base Address 23:00 db 10011010b ; |7|6|5|4|3|2|1|0| ; | | | | | | | `----- 1 when segment used. ; | | | | | | `------ 1 when writable. ; | | | | | `------- 1 if "conformant". Don't know what is it... spectral ? xD ; | | | | `-------- 1 always ; | | | `--------- 1 for segment descriptor, 0 for system descriptor ; | | `---------- DPL !!! 0 for ring 0 ; | `----------- DPL (2/2) ; `------------ 1 if in physical memory, 0 if page fault db 11001111b ; |7|6|5|4|3|2|1|0| ; | | | | | | | `----- Limit 16 ; | | | | | | `------ Limit 17 ; | | | | | `------- Limit 18 ; | | | | `-------- Limit 19 ; | | | `--------- available for use ; | | `---------- 0 always ; | `----------- size of data. 1 for 32bits ; `------------ 0 if limit is in Bytes, 1 if it's in pages (4ko) db 0x0 ; Base Address 31:24 DATA_SELECTOR: ;; flat data selector (ring 0) dw 0x0FFFF ; Segment Limit 15:00 db 0x0, 0x0, 0x0 ; Base Address 23:00 db 10010010b ; |7|6|5|4|3|2|1|0| ; | | | | | | | `----- 1 when segment used. ; | | | | | | `------ 1 when writable. ; | | | | | `------- expansion direction. 1 for a LIFO ; | | | | `-------- 1 always ; | | | `--------- 1 for segment descriptor, 0 for system descriptor ; | | `---------- DPL !!! 0 for ring 0 ; | `----------- DPL (2/2) ; `------------ 1 if in physical memory, 0 if page fault db 10001111b ; |7|6|5|4|3|2|1|0| ; | | | | | | | `----- Limit 16 ; | | | | | | `------ Limit 17 ; | | | | | `------- Limit 18 ; | | | | `-------- Limit 19 ; | | | `--------- available for use ; | | `---------- 0 always ; | `----------- size of data. 1 for 32bits ; `------------ 0 if limit is in Bytes, 1 if it's in pages (4ko) db 0x0 ; Base Address 31:24 LONG_SELECTOR: ;; 64-bit code selector (ring 0) dw 0x0FFFF ; Segment Limit 15:00 db 0x0, 0x0, 0x0 ; Base Address 23:00 db 10011010b ; |7|6|5|4|3|2|1|0| ; | | | | | | | `----- 1 when segment used. ; | | | | | | `------ 1 when writable. ; | | | | | `------- 1 if "conformant". Don't know what is it... spectral ? xD ; | | | | `-------- 1 always ; | | | `--------- 1 for segment descriptor, 0 for system descriptor ; | | `---------- DPL !!! 0 for ring 0 ; | `----------- DPL (2/2) ; `------------ 1 if in physical memory, 0 if page fault db 10101111b ; |7|6|5|4|3|2|1|0| ; | | | | | | | `----- Limit 16 ; | | | | | | `------ Limit 17 ; | | | | | `------- Limit 18 ; | | | | `-------- Limit 19 ; | | | `--------- available for use ; | | `---------- 0 always ; | `----------- size of data. 1 for 32bits ; `------------ 0 if limit is in Bytes, 1 if it's in pages (4ko) db 0x0 ; Base Address 31:24 GDT_LENGTH: [BITS 16] disable_cursor: pushf push eax push edx mov dx, 0x3D4 mov al, 0xA ; low cursor shape register out dx, al inc dx mov al, 0x20 ; bits 6-7 unused, bit 5 disables the cursor, bits 0-4 control the cursor shape out dx, al pop edx pop eax popf ret get_dimensions: push eax push ebx mov ah, 0x0F int 0x10 mov [VGA_HEIGHT], ah mov [VIDEO_MODE], al pop ebx pop eax ret main: ;; DISABLING CURSOR BLINKING AND GETTING INFOS call get_dimensions call disable_cursor ;;GO GDT64 cli ; disable interrupts lgdt [GDT64] ;; ACTIVATE PROTECTED MODE mov eax, cr0 or al, 1b ; PE = 1 mov cr0, eax ;; DISABLE PAGING mov eax, cr0 and eax, 0x7FFFFFFF ; PG = 0 ; |0|111111111111111111111111111111 ; | ; `------ Paging bit mov cr0, eax push dword [VIDEO_MODE] push dword [VGA_HEIGHT] jmp (CODE_SELECTOR-GDT64):main32 [BITS 32] VIDEO_MODE32 dw 0 VGA_HEIGHT32 dw 0 main32: pop dword [VGA_HEIGHT32] pop dword [VIDEO_MODE32] ;; INITIALIZE PROTECTED MODE SEGMENT REGISTERS mov ax, DATA_SELECTOR-GDT64 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax ;; ACTIVATE PHYSICAL ADRESS EXTENSION mov eax, cr4 or eax, 100000b ; PAE = 1 = 4 Mo / page. 0 = 4 Ko mov cr4, eax ;;cleanup mov edi, 0x70000 mov ecx, 0x10000 xor eax, eax rep stosd ;;formatting mov dword [0x70000], 0x71000 + 7 ; first PDP table mov dword [0x71000], 0x72000 + 7 ; first page directory mov dword [0x72000], 0x73000 + 7 ; first page table mov edi, 0x73000 ; address of first page table mov eax, 7 mov ecx, 256 ; number of pages to map (1 MB) .make_page_entries: stosd add edi, 4 add eax, 0x1000 loop .make_page_entries ;; pointing pml4 mov eax, 0x70000 ; Bass address of PML4 mov cr3, eax ; load page-map level-4 base ;; ACTIVATE LONG MODE mov ecx, 0xC0000080 ; address of MSR rdmsr ; read MSR or eax, 100000000b ; LME = 1. (Long Mode Enable) wrmsr ; write MSR ;; ACTIVATE PAGING mov eax, cr0 or eax, 0x80000000 ; make bit 31 (PG = Paging) to 1 : ; |1|000000000000000000000000000000 ; | ; `------ Paging bit mov cr0, eax push dword 0 push dword [VIDEO_MODE] push dword 0 push dword [VGA_HEIGHT] jmp (LONG_SELECTOR-GDT64):main64 [BITS 64] ;; FUNCTIONS write: ;-----------------------------------------------------------------------; ; x64/LM Text Printing Functions ; ; bl : color code ; ; esi : string address ; ;-----------------------------------------------------------------------; mov edi, [NextTRAM] ;TRAM ADDRESS push rsi push rdi .pLoop: lodsb cmp al, 0 ; while @al, i.e. while we're not hitting '\0' je .pEnd cmp al, 0x0A ; LF je .lf cmp al, 0x0D ; CR je .cr stosb ; text subpixel mov al, bl stosb ; color subpixel add qword [NextTRAM], 0x2 ; Cursor moving add qword [VGA_X], 0x2 ; coord + 2 because 2 subpixels jmp .pLoop .pEnd: pop rdi pop rsi ret .lf: mov rax, [VGA_HEIGHT64] add [NextTRAM], rax ; Cursor moving add [NextTRAM], rax add edi, eax ; Address moving add edi, eax jmp .pLoop .cr: push rax mov rax, qword [VGA_X] sub qword [NextTRAM], rax ; pos = X + Y * VGA_HEIGHT64. Donc pos - X = début de ligne sub edi, edx mov qword [VGA_X], 0 pop rax jmp .pLoop .scroll: jmp .pLoop ;; DATA txt db 0x09, " Switching to Long Mode... OK", 0x0A, 0x0D, 0 NextTRAM dq 0x0B8AA0 ; Last position of cursor VIDEO_MODE64 dq 0 VGA_HEIGHT64 dq 0 VGA_X dq 0x0 msg db "The system is now in x64 mode. Is this not beautiful ?", 0x0A, 0x0D, 0 main64: pop qword [VGA_HEIGHT64] pop qword [VIDEO_MODE64] ;; INITIALIZE STACK mov rsp, 0x9F000 ;; NOTIFYING mov bl, 0x0A mov esi, txt call write mov bl, 0x0B mov esi, msg call write mov bl, 0x0C mov esi, msg call write mov bl, 0x0D mov esi, msg call write mov bl, 0x0E mov esi, msg call write ;call KERNEL jmp $ times 1024-($-$$) db 144 KERNEL: