├── .gitignore ├── .vscode └── settings.json ├── bin ├── disk1000 ├── disk1000.vdi ├── disk1001.vdi ├── disk1004.vdi ├── disk200.vdi ├── disk201.vdi ├── disk4000.vdi ├── new20.vdi ├── new21.vdi ├── new22.vdi ├── new23.vdi ├── new24.vdi ├── new25.vdi ├── new26.vdi └── new27.vdi ├── bochsrc ├── boot ├── boot32.s ├── os_trampoline32.s ├── vbe_setup.s └── vbe_strucs.s ├── kernel ├── 32 │ ├── main32.c │ ├── vmalloc32.c │ └── vmalloc32.h ├── 64 │ ├── acpi.c │ ├── acpi.h │ ├── apic.c │ ├── apic.h │ ├── draw.c │ ├── draw.h │ ├── drivers │ │ ├── driverman.c │ │ ├── driverman.h │ │ ├── fs │ │ │ ├── fs.c │ │ │ └── fs.h │ │ ├── hpet │ │ │ ├── hpet.c │ │ │ └── hpet.h │ │ ├── ide │ │ │ ├── ata.s │ │ │ ├── ide.c │ │ │ └── ide.h │ │ ├── nvme │ │ │ ├── nvme.c │ │ │ └── nvme.h │ │ ├── ps2 │ │ │ ├── ps2.c │ │ │ └── ps2.h │ │ └── usb │ │ │ ├── xhci.c │ │ │ └── xhci.h │ ├── font.c │ ├── font.h │ ├── idt.c │ ├── idt.h │ ├── idt.s │ ├── io.c │ ├── io.h │ ├── iomem.h │ ├── irqhandlers.c │ ├── main.c │ ├── memtools.c │ ├── memtools.h │ ├── msr.c │ ├── msr.h │ ├── panic.c │ ├── panic.h │ ├── pci.c │ ├── pci.h │ ├── pic.c │ ├── pic.h │ ├── scheduler.c │ ├── scheduler.h │ ├── sleep.h │ ├── softtss.h │ ├── syscall.c │ ├── syscall.h │ ├── vmalloc.c │ └── vmalloc.h ├── draw.h ├── file.h ├── include.h └── vbe.h ├── link32.ld ├── link64.ld ├── linkos.ld ├── linktrampoline.ld ├── makefile ├── os ├── drawcall.h ├── drawman.c ├── drawman.h ├── filecall.h ├── font.c ├── font.h ├── helper.s ├── include.h ├── log.c ├── log.h ├── mem.c ├── mem.h ├── modules │ ├── helpers │ │ ├── bf │ │ │ ├── bf.c │ │ │ ├── bf.h │ │ │ ├── linked_list.c │ │ │ ├── linked_list.h │ │ │ ├── string.c │ │ │ └── string.h │ │ ├── shell.c │ │ └── shell.h │ ├── keyboard.c │ ├── keyboard.h │ ├── winman.c │ └── winman.h ├── os.c ├── proc.c ├── proc.h └── timer.h └── run.bat /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | .vscode 3 | debug-log.txt 4 | *.o -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "include.h": "c", 4 | "vmalloc.h": "c", 5 | "draw.h": "c", 6 | "drawman.h": "c", 7 | "softtss.h": "c", 8 | "ps2.h": "c", 9 | "ide.h": "c", 10 | "pci.h": "c", 11 | "pic.h": "c", 12 | "idt.h": "c", 13 | "keyboard.h": "c", 14 | "xutility": "cpp", 15 | "format": "cpp", 16 | "initializer_list": "cpp", 17 | "xstring": "cpp", 18 | "type_traits": "cpp", 19 | "xiosbase": "cpp", 20 | "memtools.h": "c", 21 | "panic.h": "c", 22 | "apic.h": "c", 23 | "stdatomic.h": "c", 24 | "nvme.h": "c" 25 | } 26 | } -------------------------------------------------------------------------------- /bin/disk1000: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/disk1000 -------------------------------------------------------------------------------- /bin/disk1000.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/disk1000.vdi -------------------------------------------------------------------------------- /bin/disk1001.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/disk1001.vdi -------------------------------------------------------------------------------- /bin/disk1004.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/disk1004.vdi -------------------------------------------------------------------------------- /bin/disk200.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/disk200.vdi -------------------------------------------------------------------------------- /bin/disk201.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/disk201.vdi -------------------------------------------------------------------------------- /bin/disk4000.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/disk4000.vdi -------------------------------------------------------------------------------- /bin/new20.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/new20.vdi -------------------------------------------------------------------------------- /bin/new21.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/new21.vdi -------------------------------------------------------------------------------- /bin/new22.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/new22.vdi -------------------------------------------------------------------------------- /bin/new23.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/new23.vdi -------------------------------------------------------------------------------- /bin/new24.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/new24.vdi -------------------------------------------------------------------------------- /bin/new25.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/new25.vdi -------------------------------------------------------------------------------- /bin/new26.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/new26.vdi -------------------------------------------------------------------------------- /bin/new27.vdi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/waternine9/untitled-os/beea7e5ab3b39fc0c1722209f2157221d7456841/bin/new27.vdi -------------------------------------------------------------------------------- /bochsrc: -------------------------------------------------------------------------------- 1 | log: "./debug-log.txt" 2 | 3 | megs: 2048 4 | 5 | cpu: model=corei7_sandy_bridge_2600k 6 | 7 | ata0-master: type=disk, path="bin/boot.img", status=inserted, cylinders=615, heads=6, spt=17 8 | boot: disk 9 | 10 | magic_break: enabled=1 -------------------------------------------------------------------------------- /boot/boot32.s: -------------------------------------------------------------------------------- 1 | ; Directives: 2 | [BITS 16] 3 | [ORG 0x7C00] 4 | 5 | section .boot 6 | 7 | global bootentry 8 | bootentry: jmp 0:entry0 9 | 10 | db "UNTITLED_OS" 11 | 12 | entry0: 13 | jmp entry 14 | ; Entry point: 15 | entry: 16 | 17 | ; Setup segments and stack pointer: 18 | xor ax, ax 19 | mov ds, ax 20 | mov es, ax 21 | mov ss, ax 22 | mov ax, 0x7C00 23 | mov sp, ax 24 | 25 | 26 | ; First things first, store the drive number 27 | or dl, 0x80 28 | mov [DriveNumber], dl 29 | 30 | mov si, DAPACK ; address of "disk address packet" 31 | mov ah, 0x42 ; AL is unused 32 | mov dl, [DriveNumber] 33 | int 0x13 34 | 35 | 36 | ; Interrogate BIOS for MemoryMap: 37 | ; ...prepare the first call: 38 | xor ebx, ebx 39 | mov es, bx 40 | sub sp, 20 ; Make space for the temporary structure on the stack. 41 | mov bp, sp 42 | mov di, MemoryMap 43 | ; ...repeatedly torment the BIOS until all information has been extracted: 44 | .interrogation_loop: 45 | ; ...intimidatingly ask the BIOS for the location of memory: 46 | push di 47 | mov di, bp 48 | mov eax, 0x0000E820 ; Magic 0. 49 | mov ecx, 20 ; Buffer size. 50 | mov edx, 0x534D4150 ; Magic 1. 51 | int 0x15 52 | pop di 53 | ; ...if unable to answer, conclude the interrogation: 54 | jc .interrogation_done 55 | cmp eax, 0x534D4150 ; Make sure EAX has the magic number given to EDX. 56 | jne .interrogation_done 57 | ; ...if the BIOS gave a valid answer, write it down before continuing extraction of information: 58 | mov si, bp 59 | mov eax, [si + 16] ; Make sure the answer is valid. 60 | cmp eax, 1 61 | jne .invalid_answer 62 | mov cx, 8 ; Now write it down. 63 | rep movsw 64 | inc dword [MemoryMapSize] 65 | cmp di, MemoryMap.end ; Make sure we have space in the buffer. 66 | jae .interrogation_done 67 | .invalid_answer: 68 | ; ...check if this was the last answer the BIOS could provide: 69 | test ebx, ebx 70 | jnz .interrogation_loop ; If the BIOS shows signs of still knowing something, continue the suffering. 71 | .interrogation_done: 72 | ; ...clean up afterwards: 73 | add sp, 20 74 | 75 | ; SSE support 76 | mov eax, cr4 77 | or ax, 3 << 9 ;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time 78 | mov cr4, eax 79 | 80 | jmp VbeSetup 81 | %include "boot/vbe_setup.s" 82 | VbeSetup: 83 | call VesaVbeSetup 84 | 85 | ; Load a global descriptor table for flat addressing: 86 | cli 87 | lgdt [GDTDesc] 88 | mov eax, cr0 89 | or eax, 1 90 | mov cr0, eax 91 | jmp 8:kstart 92 | 93 | align 4 94 | DAPACK: 95 | db 0x10 96 | db 0 97 | .cnt: dw 16 ; int 13 resets this to # of blocks actually read/written 98 | .dest: dw 0x8400 ; memory buffer destination address (0:7c00) 99 | dw 0 ; in memory page zero 100 | .lba: dd 4 ; put the lba to read in this spot 101 | dd 0 ; more storage bytes only for big lba's ( > 4 bytes ) 102 | 103 | GDTStart: 104 | dq 0 105 | GDTCode: 106 | dw 0xFFFF ; Limit 107 | dw 0x0000 ; Base 108 | db 0x00 ; Base 109 | db 0b10011010 ; Access 110 | db 0b11001111 ; Flags + Limit 111 | db 0x00 ; Base 112 | GDTData: 113 | dw 0xFFFF ; Limit 114 | dw 0x0000 ; Base 115 | db 0x00 ; Base 116 | db 0b10010010 ; Access 117 | db 0b11001111 ; Flags + Limit 118 | db 0x00 ; Base 119 | GDTEnd: 120 | 121 | GDTDesc: 122 | .GDTSize dw GDTEnd - GDTStart - 1 ; GDT size 123 | .GDTAddr dd GDTStart ; GDT address 124 | 125 | times 0x1BE-($-$$) db 0 126 | 127 | db 0x80, 0, 0, 0, 0, 0, 0, 0 128 | dd 0 129 | dd 0xFFFFFFFF 130 | 131 | ; Boot signature: 132 | times 510 - ($ - $$) db 0x0 133 | dw 0xAA55 134 | DriveNumber: db 0 135 | 136 | MemoryMapSize: dd 0 137 | MemoryMap: 138 | times 1024 - ($ - $$) db 0 139 | .end: 140 | 141 | %include "boot/vbe_strucs.s" 142 | 143 | times 2048 - ($ - $$) db 0x0 144 | kstart: -------------------------------------------------------------------------------- /boot/os_trampoline32.s: -------------------------------------------------------------------------------- 1 | ; Include the bootloader 2 | section .boot 3 | 4 | [BITS 32] 5 | [ORG 0x8400] 6 | 7 | kstart: 8 | ; Set up segments and stack pointer 9 | mov ax, 16 10 | mov ds, ax 11 | mov es, ax 12 | mov fs, ax 13 | mov gs, ax 14 | mov ss, ax 15 | 16 | mov eax, 0x7E00 17 | mov esp, eax 18 | 19 | ; Find RSDP 20 | mov ecx, 0x20000 21 | mov esi, 0xE0000 22 | RSDPfind: 23 | mov eax, [esi] 24 | cmp eax, "RSD " 25 | jne .NotFound 26 | mov eax, [esi + 4] 27 | cmp eax, "PTR " 28 | je .Found 29 | .NotFound: 30 | inc esi 31 | loop RSDPfind 32 | mov eax, 0xEEEEEE 33 | cli 34 | hlt 35 | .Found: 36 | mov edi, 0x7ED0 37 | mov ecx, 0x30 38 | .Copy: 39 | mov eax, [esi] 40 | mov [edi], eax 41 | inc esi 42 | inc edi 43 | loop .Copy 44 | 45 | cld 46 | 47 | ; Reprogram the PIT to be 1.193182 / 16 MHz 48 | cli 49 | mov al, 0b00110110 50 | out 0x43, al 51 | mov al, 0 52 | out 0x40, al 53 | mov al, 16 54 | out 0x40, al 55 | 56 | mov dword [CurrentLBA], 4 + (0x2000 / 512) 57 | mov dword [CurrentLBAOs], 4 + (0xB000 / 512) 58 | 59 | ReadLoop: 60 | mov eax, [CurrentLBA] 61 | cmp eax, 0x400 62 | jl ReadSectorsV8086 63 | 64 | ; Now call the paging initializer 65 | call 0x8800 66 | 67 | ; Enable PAE 68 | mov edx, cr4 69 | or edx, (1 << 5) 70 | mov cr4, edx 71 | 72 | ; Set LME (long mode enable) 73 | mov ecx, 0xC0000080 74 | rdmsr 75 | or eax, (1 << 8) 76 | wrmsr 77 | 78 | mov eax, 0x10000000 79 | mov cr3, eax 80 | 81 | ; Enable paging 82 | mov ebx, cr0 83 | or ebx, (1 << 31) 84 | mov cr0, ebx 85 | 86 | jmp 0x18:.fabled_64 87 | 88 | ; Don't proceed to the fabled 64-bit land before loading the 64-bit GDT 89 | [BITS 64] ; The fabled 64-bit 90 | .fabled_64: 91 | mov ax, 0x10 92 | mov ds, ax 93 | mov es, ax 94 | mov fs, ax 95 | mov gs, ax 96 | mov ss, ax 97 | mov rsp, 0xFFFFFFFFC0200000 98 | 99 | mov ecx, 0x277 100 | rdmsr 101 | and eax, 0xFFFF00FF 102 | or eax, 0x00000100 103 | wrmsr 104 | 105 | ; Now call the kernel 106 | call 0xFFFFFFFFC0000000 107 | ; Flush the pages 108 | mov rbx, 0x10000000 109 | mov cr3, rbx 110 | 111 | 112 | ; Now call the operating system 113 | mov rcx, rax 114 | mov rdx, rcx 115 | 116 | add rdx, 0x200000 117 | mov word [GDTTSS], 0x67 118 | mov dword [GDTTSS + 2], TSS 119 | or dword [GDTTSS + 2], (0b10001001) << 24 120 | 121 | mov ax, 0x30 122 | ltr ax 123 | 124 | 125 | mov dword [TSS + 0x4], esp 126 | mov dword [TSS + 0x8], 0xFFFFFFFF 127 | 128 | mov ax, 0x28 | 3 ; ring 3 data with bottom 2 bits set for ring 3 129 | mov ds, ax 130 | mov es, ax 131 | mov fs, ax 132 | mov gs, ax 133 | 134 | cli 135 | push 0x28 | 3 136 | push rdx 137 | pushfq 138 | pop rax 139 | or rax, 0x200 140 | push rax 141 | push 0x20 | 3 142 | push rcx 143 | iretq 144 | CurrentLBA: dd 4 + (0x2000 / 512) 145 | CurrentLBAOs: dd 4 + (0x40000 / 512) 146 | 147 | [BITS 32] 148 | IDT16: 149 | dw 0x3FF ; Limit 150 | dd 0x0 ; Base 151 | ReadSectorsV8086: 152 | cli 153 | lgdt [GDT16Desc] 154 | jmp 8:.PMode16 155 | [BITS 16] 156 | .PMode16: 157 | mov ax, 0x10 158 | mov ds, ax 159 | mov es, ax 160 | mov fs, ax 161 | mov gs, ax 162 | mov ss, ax 163 | 164 | mov eax, cr0 165 | and eax, ~1 166 | mov cr0, eax 167 | 168 | jmp 0:.RealMode 169 | .RealMode: 170 | mov ax, 0 171 | mov ds, ax 172 | mov es, ax 173 | mov ss, ax 174 | mov fs, ax 175 | mov gs, ax 176 | xor esp, esp 177 | mov sp, 0x7E00 178 | 179 | sti 180 | 181 | mov word [DAPACK.cnt], 4 182 | mov word [DAPACK.dest], 0x8400 + 4096 183 | mov eax, [CurrentLBA] 184 | mov [DAPACK.lba], eax 185 | mov si, DAPACK ; address of "disk address packet" 186 | mov ah, 0x42 ; AL is unused 187 | mov dl, [0x7E00] 188 | int 0x13 189 | 190 | mov word [DAPACK.cnt], 4 191 | mov word [DAPACK.dest], 0x8400 + 4096 + 2048 192 | mov eax, [CurrentLBAOs] 193 | mov [DAPACK.lba], eax 194 | mov si, DAPACK ; address of "disk address packet" 195 | mov ah, 0x42 ; AL is unused 196 | mov dl, [0x7E00] 197 | int 0x13 198 | ; Switch back to pmode 199 | cli 200 | lgdt [GDTDesc] 201 | mov eax, cr0 202 | or eax, 1 203 | mov cr0, eax 204 | jmp 8:.PMode 205 | [BITS 32] 206 | .PMode: 207 | ; Set up segments and stack pointer 208 | mov ax, 16 209 | mov ds, ax 210 | mov es, ax 211 | mov fs, ax 212 | mov gs, ax 213 | 214 | mov eax, 0x7E00 215 | mov esp, eax 216 | 217 | mov edi, 0x100000 218 | mov eax, [CurrentLBA] 219 | sub eax, 4 + (0x2000 / 512) 220 | imul eax, 512 221 | add edi, eax 222 | mov esi, 0x8400 + 4096 223 | mov ecx, (512 * 4) / 2 224 | rep movsw 225 | mov eax, [CurrentLBA] 226 | add eax, 4 227 | mov [CurrentLBA], eax 228 | 229 | mov edi, 0xB00000 230 | mov eax, [CurrentLBAOs] 231 | sub eax, 4 + (0x40000 / 512) 232 | imul eax, 512 233 | add edi, eax 234 | mov esi, 0x8400 + 4096 + 2048 235 | mov ecx, (512 * 4) / 2 236 | rep movsw 237 | mov eax, [CurrentLBAOs] 238 | add eax, 4 239 | mov [CurrentLBAOs], eax 240 | 241 | jmp ReadLoop 242 | 243 | align 4 244 | DAPACK: 245 | db 0x10 246 | db 0 247 | .cnt: dw 16 ; int 13 resets this to # of blocks actually read/written 248 | .dest: dw 0x8400 ; memory buffer destination address (0:7c00) 249 | dw 0 250 | .lba: dd 4 ; put the lba to read in this spot 251 | dd 0 ; more storage bytes only for big lba's ( > 4 bytes ) 252 | 253 | GDTStart: 254 | dq 0 255 | GDTCode: 256 | dw 0xFFFF ; Limit 257 | dw 0x0000 ; Base 258 | db 0x00 ; Base 259 | db 0b10011010 ; Access 260 | db 0b11001111 ; Flags + Limit 261 | db 0x00 ; Base 262 | GDTData: 263 | dw 0xFFFF ; Limit 264 | dw 0x0000 ; Base 265 | db 0x00 ; Base 266 | db 0b10010010 ; Access 267 | db 0b11001111 ; Flags + Limit 268 | db 0x00 ; Base 269 | GDTCode64: 270 | dw 0xFFFF ; Limit 271 | dw 0x0000 ; Base 272 | db 0x00 ; Base 273 | db 0b10011010 ; Access 274 | db 0b10101111 ; Flags + Limit 275 | db 0x00 ; Base 276 | GDTCode64User: 277 | dw 0xFFFF ; Limit 278 | dw 0x0000 ; Base 279 | db 0x00 ; Base 280 | db 0b11111010 ; Access 281 | db 0b10101111 ; Flags + Limit 282 | db 0x00 ; Base 283 | GDTDataUser: 284 | dw 0xFFFF ; Limit 285 | dw 0x0000 ; Base 286 | db 0x00 ; Base 287 | db 0b11110010 ; Access 288 | db 0b11001111 ; Flags + Limit 289 | db 0x00 ; Base 290 | GDTTSS: 291 | dw 0x67 ; Limit 292 | dw 0x0 ; Base 293 | db 0x00 ; Base 294 | db (0b10001001) ; Access 295 | db 0b00000000 ; Flags + Limit 296 | db 0x00 ; Base 297 | dq 0x0 ; Stuff 298 | GDTEnd: 299 | 300 | GDTDesc: 301 | .GDTSize dw GDTEnd - GDTStart - 1 ; GDT size 302 | .GDTAddr dd GDTStart ; GDT address 303 | 304 | GDT16Start: 305 | dq 0 306 | GDT16Code: ; 16-bit code segment descriptor 307 | dw 0xFFFF ; Limit 308 | dw 0x0000 ; Base 309 | db 0x00 ; Base 310 | db 0b10011010 ; Access 311 | db 0b00001111 ; Flags + Limit 312 | db 0x00 ; Base 313 | 314 | GDT16Data: ; 16-bit data segment descriptor 315 | dw 0xFFFF ; Limit 316 | dw 0x0000 ; Base 317 | db 0x00 ; Base 318 | db 0b10010010 ; Access 319 | db 0b11001111 ; Flags + Limit 320 | db 0x00 ; Base 321 | GDT16End: 322 | 323 | GDT16Desc: 324 | .GDTSize dw GDT16End - GDT16Start - 1 325 | .GDTAddr dd GDT16Start 326 | 327 | TSS: 328 | times 0x1A dd 0 329 | 330 | times 1024 - ($ - $$) db 0 331 | 332 | incbin "paging32.img" 333 | 334 | times 4096 - ($ - $$) db 0 335 | 336 | times 0x2000 - ($ - $$) db 0 337 | 338 | incbin "kernel.img" 339 | 340 | times 0x40000 - ($ - $$) db 0 341 | 342 | [BITS 64] 343 | 344 | section .os 345 | 346 | incbin "os.img" 347 | 348 | section .kernelend 349 | kernelend: -------------------------------------------------------------------------------- /boot/vbe_setup.s: -------------------------------------------------------------------------------- 1 | 2 | VbeCurrentMode: dw 0 3 | ;; Set up VESA VBE with maximum Resolution. 4 | VesaVbeSetup: 5 | 6 | ; Get controller information 7 | push es 8 | mov ax, 0x4F00 9 | mov di, VbeControllerInfo 10 | int 0x10 11 | pop es 12 | 13 | mov si, [VbeControllerInfo.VideoModePtr] 14 | 15 | 16 | .loop: 17 | 18 | mov ax, [VbeControllerInfo.VideoModePtr + 2] 19 | mov es, ax 20 | 21 | mov cx, [es:si] ; Our current mode number 22 | 23 | xor ax, ax 24 | mov es, ax 25 | 26 | cmp cx, 0xFFFF ; Check if at end of the list 27 | je .set_mode 28 | 29 | mov [VbeCurrentMode], cx 30 | 31 | add si, 2 ; Each element in the list is 2 bytes 32 | 33 | push si 34 | 35 | push es 36 | ; Get current mode information. 37 | mov ax, 0x4F01 38 | mov di, VbeModeInfo 39 | int 0x10 40 | pop es 41 | 42 | pop si 43 | 44 | ; Check if supports linear frame buffer 45 | mov ax, [VbeModeInfo.ModeAttributes] 46 | and ax, 0x90 47 | cmp ax, 0x90 48 | jne .loop 49 | 50 | ; Check if is direct color or packed pixel 51 | mov al, [VbeModeInfo.MemoryModel] 52 | 53 | cmp al, 0x04 54 | 55 | je .RGB 56 | 57 | mov al, [VbeModeInfo.MemoryModel] 58 | 59 | cmp al, 0x06 60 | 61 | jne .loop 62 | 63 | .RGB: 64 | 65 | ; Check if 32 bit 66 | mov al, [VbeModeInfo.BitsPerPixel] 67 | cmp al, 32 68 | 69 | jne .loop 70 | 71 | .loop_done: 72 | 73 | xor ebx, ebx 74 | add bx, [VbeModeInfo.XResolution] 75 | cmp word [VbeModeInfo.XResolution], 1920 76 | jg .loop 77 | add bx, [VbeModeInfo.YResolution] 78 | cmp word [VbeModeInfo.YResolution], 1080 79 | 80 | cmp ebx, [.BestScore] 81 | jl .loop 82 | 83 | mov [.BestScore], ebx 84 | mov bx, [VbeCurrentMode] 85 | mov [.BestMode], bx 86 | 87 | jmp .loop 88 | 89 | .set_mode: 90 | 91 | cmp word [.BestMode], 0xFFFF 92 | je .done_fail 93 | 94 | push es 95 | mov ax, 0x4F01 96 | mov cx, [.BestMode] 97 | mov di, VbeModeInfo 98 | int 0x10 99 | pop es 100 | 101 | push es 102 | mov ax, 0x4F02 103 | mov bx, [.BestMode] 104 | and bx, 0b111111111 105 | or bx, 0x4000 106 | mov di, 0 107 | int 0x10 108 | pop es 109 | 110 | .done: 111 | ret 112 | 113 | .BestMode: dw 0xFFFF 114 | .BestScore: dd 0x0 115 | 116 | .done_fail: 117 | mov ax, 0xb800 118 | mov es, ax 119 | mov word [es:0], 0x0F00 | 'F' 120 | cli 121 | hlt -------------------------------------------------------------------------------- /boot/vbe_strucs.s: -------------------------------------------------------------------------------- 1 | global VbeControllerInfo 2 | VbeControllerInfo: 3 | .VbeSignature db 'VESA' ; VBE Signature 4 | .VbeVersion dw 0200h ; VBE Version 5 | .OemStringPtr dd 0 ; Pointer to OEM String 6 | .Capabilities times 4 db 0 ; Capabilities of graphics controller 7 | .VideoModePtr dd 0 ; Pointer to VideoModeList 8 | .TotalMemory dw 0 ; Number of 64kb memory blocks 9 | ; Added for VBE 2.0 10 | .OemSoftwareRev dw 0 ; VBE implementation Software revision 11 | .OemVendorNamePtr dd 0 ; Pointer to Vendor Name String 12 | .OemProductNamePtr dd 0 ; Pointer to Product Name String 13 | .OemProductRevPtr dd 0 ; Pointer to Product Revision String 14 | .Reserved times 222 db 0 ; Reserved for VBE implementation scratch 15 | ; area 16 | .OemData times 256 db 0 ; Data Area for OEM Strings 17 | global VbeModeInfo 18 | VbeModeInfo: 19 | ; Mandatory information for all VBE revisions 20 | .ModeAttributes dw 0 ; mode attributes 21 | .WinAAttributes db 0 ; window A attributes 22 | .WinBAttributes db 0 ; window B attributes 23 | .WinGranularity dw 0 ; window granularity 24 | .WinSize dw 0 ; window size 25 | .WinASegment dw 0 ; window A start segment 26 | .WinBSegment dw 0 ; window B start segment 27 | .WinFuncPtr dd 0 ; pointer to window function 28 | .BytesPerScanLine dw 0 ; bytes per scan line 29 | ; Mandatory information for VBE 1.2 and above 30 | .XResolution dw 0 ; horizontal resolution in pixels or characters3 31 | .YResolution dw 0 ; vertical resolution in pixels or characters 32 | .XCharSize db 0 ; character cell width in pixels 33 | .YCharSize db 0 ; character cell height in pixels 34 | .NumberOfPlanes db 0 ; number of memory planes 35 | .BitsPerPixel db 0 ; bits per pixel 36 | .NumberOfBanks db 0 ; number of banks 37 | .MemoryModel db 0 ; memory model type 38 | .BankSize db 0 ; bank size in KB 39 | .NumberOfImagePages db 0 ; number of images 40 | .Reserved1 db 1 ; reserved for page function 41 | ; Direct Color fields (required for direct/6 and YUV/7 memory models) 42 | .RedMaskSize db 0 ; size of direct color red mask in bits 43 | .RedFieldPosition db 0 ; bit position of lsb of red mask 44 | .GreenMaskSize db 0 ; size of direct color green mask in bits 45 | .GreenFieldPosition db 0 ; bit position of lsb of green mask 46 | .BlueMaskSize db 0 ; size of direct color blue mask in bits 47 | .BlueFieldPosition db 0 ; bit position of lsb of blue mask 48 | .RsvdMaskSize db 0 ; size of direct color reserved mask in bits 49 | .RsvdFieldPosition db 0 ; bit position of lsb of reserved mask 50 | .DirectColorModeInfo db 0 ; direct color mode attributes 51 | ; Mandatory information for VBE 2.0 and above 52 | .PhysBasePtr dd 0 ; physical address for flat memory frame buffer 53 | .OffScreenMemOffset dd 0 ; pointer to start of off screen memory 54 | .OffScreenMemSize dw 0 ; amount of off screen memory in 1k units 55 | ; Mandatory information for VBE 3.0 and above 56 | .LinBytesPerScanLine dw 0 ; bytes per scan line for linear modes 57 | .BnkNumberOfImagePages db 0 ; number of images for banked modes 58 | .LinNumberOfImagePages db 0 ; number of images for linear modes 59 | .LinRedMaskSize db 0 ; size of direct color red mask (linear modes) 60 | .LinRedFieldPosition db 0 ; bit position of lsb of red mask (linear modes) 61 | .LinGreenMaskSize db 0 ; size of direct color green mask (linear modes) 62 | .LinGreenFieldPosition db 0 ; bit position of lsb of green mask (linear modes) 63 | .LinBlueMaskSize db 0 ; size of direct color blue mask (linear modes) 64 | .LinBlueFieldPosition db 0 ; bit position of lsb of blue mask (linear modes) 65 | .LinRsvdMaskSize db 0 ; size of direct color reserved mask (linear modes) 66 | .LinRsvdFieldPosition db 0 ; bit position of lsb of reserved mask (linear modes) 67 | .MaxPixelClock dd 0 ; maximum pixel clock (in Hz) for graphics mode 68 | .Reserved times 189 db 0 ; remainder of ModeInfoBlock -------------------------------------------------------------------------------- /kernel/32/main32.c: -------------------------------------------------------------------------------- 1 | #include "../include.h" 2 | #include "vmalloc32.h" 3 | 4 | volatile void __attribute__((section(".main32"))) main32() 5 | { 6 | uint64_t* MemMap = 0x7E05; 7 | Init(); 8 | if (!IdMap(0x0, 0x100000)) 9 | { 10 | *(uint16_t*)0xb8002 = 0x0F00 | '0'; 11 | asm volatile ("cli\nhlt\n"); 12 | } 13 | if (!IdMap(0x10000000, 0x10000000)) 14 | { 15 | *(uint16_t*)0xb8002 = 0x0F00 | '1'; 16 | asm volatile ("cli\nhlt\n"); 17 | } 18 | if (!MapHigher(0xC0000000, 0x100000, 0x200000)) 19 | { 20 | *(uint16_t*)0xb8002 = 0x0F00 | '2'; 21 | asm volatile ("cli\nhlt\n"); 22 | } 23 | if (!MapHigher(0xC1200000, 0x300000, 0x800000)) 24 | { 25 | *(uint16_t*)0xb8002 = 0x0F00 | '4'; 26 | asm volatile ("cli\nhlt\n"); 27 | } 28 | StoreNumber(); 29 | } -------------------------------------------------------------------------------- /kernel/32/vmalloc32.c: -------------------------------------------------------------------------------- 1 | #include "vmalloc32.h" 2 | 3 | #define MAX_ADDR_BIT 47 4 | #define PRESENT_BIT 0 5 | #define READWRITE_BIT 1 6 | #define USER_SUPERVISOR_BIT 2 7 | #define WRITE_THROUGH_BIT 3 8 | #define CACHE_DISABLE_BIT 4 9 | #define ACCESSED_BIT 5 10 | #define PAGE_SIZE_BIT 7 11 | #define ADDR_BIT 12 12 | #define AVAILABLE_BIT 52 13 | #define NO_EXECUTE_BIT 63 14 | #define PMT_SIZE 512 15 | 16 | typedef struct 17 | { 18 | uint32_t Low; 19 | uint32_t High; 20 | } __attribute__((packed)) PageMapTable; 21 | 22 | PageMapTable* Tier4; 23 | PageMapTable* AllocOffset = 0x500000; 24 | 25 | volatile PageMapTable InitTable(int Depth) 26 | { 27 | PageMapTable Ret; 28 | Ret.High = 0; 29 | Ret.Low = (size_t)(AllocOffset) & 0xFFFFF000; 30 | 31 | PageMapTable* TempAllocOffset = AllocOffset; 32 | AllocOffset += PMT_SIZE; 33 | if (Depth < 3) for (int i = 0;i < PMT_SIZE;i++) 34 | { 35 | (*TempAllocOffset) = InitTable(Depth + 1); 36 | TempAllocOffset++; 37 | } 38 | return Ret; 39 | } 40 | 41 | volatile void Init() 42 | { 43 | 44 | AllocOffset = 0x10000000 + 8 * PMT_SIZE; 45 | Tier4 = 0x10000000; 46 | for (int i = 0;i < PMT_SIZE;i++) 47 | { 48 | Tier4[i] = (PageMapTable){ 0, 0 }; 49 | } 50 | } 51 | 52 | volatile bool AllocPage(PageMapTable* BasePte, uint64_t vAddr, uint32_t pAddr, int Depth, int L4Add, int L3Add) 53 | { 54 | uint32_t Index = ((uint32_t)vAddr & (0x1FF << ((3 - Depth) * 9 + 12))) >> ((3 - Depth) * 9 + 12); 55 | if (Depth == 0) Index = L4Add; 56 | if (Depth == 1) Index += L3Add; 57 | if (Depth == 3) 58 | { 59 | BasePte[Index].High = 0; 60 | BasePte[Index].Low = (uint32_t)pAddr & 0xFFFFF000; 61 | BasePte[Index].Low |= 1 << PRESENT_BIT; 62 | BasePte[Index].Low |= 1 << READWRITE_BIT; 63 | return true; 64 | } 65 | if (BasePte[Index].Low == 0) 66 | { 67 | BasePte[Index].High = 0; 68 | AllocOffset += PMT_SIZE; 69 | BasePte[Index].Low = (size_t)AllocOffset & 0xFFFFF000; 70 | for (int i = 0;i < PMT_SIZE;i++) 71 | { 72 | AllocOffset[i] = (PageMapTable){ 0, 0 }; 73 | } 74 | } 75 | BasePte[Index].Low |= 1 << PRESENT_BIT; 76 | BasePte[Index].Low |= 1 << READWRITE_BIT; 77 | return AllocPage(BasePte[Index].Low & 0xFFFFF000, vAddr, pAddr, Depth + 1, L4Add, L3Add); 78 | } 79 | 80 | volatile bool IdMap(uint32_t Addr, uint32_t Size) 81 | { 82 | for (int i = 0;i < Size / 0x1000;i++) 83 | { 84 | if (!AllocPage(Tier4, Addr + i * 0x1000, Addr + i * 0x1000, 0, 0, 0)) return false; 85 | } 86 | return true; 87 | } 88 | 89 | volatile bool Map(uint32_t vAddr, uint32_t pAddr, uint32_t Size) 90 | { 91 | for (int i = 0;i < Size / 0x1000;i++) 92 | { 93 | if (!AllocPage(Tier4, vAddr + i * 0x1000, pAddr + i * 0x1000, 0, 0, 0)) return false; 94 | } 95 | return true; 96 | } 97 | 98 | volatile bool MapHigher(uint32_t vAddr, uint32_t pAddr, uint32_t Size) 99 | { 100 | for (int i = 0;i < Size / 0x1000;i++) 101 | { 102 | if (!AllocPage(Tier4, vAddr + i * 0x1000, pAddr + i * 0x1000, 0, PMT_SIZE - 1, 508)) return false; 103 | } 104 | return true; 105 | } 106 | 107 | volatile void StoreNumber() 108 | { 109 | *(uint32_t*)0x7FF0 = AllocOffset; 110 | } -------------------------------------------------------------------------------- /kernel/32/vmalloc32.h: -------------------------------------------------------------------------------- 1 | #include "../include.h" 2 | 3 | volatile bool IdMap(uint32_t Addr, uint32_t Size); 4 | volatile bool Map(uint32_t vAddr, uint32_t pAddr, uint32_t Size); 5 | volatile bool MapHigher(uint32_t vAddr, uint32_t pAddr, uint32_t Size); 6 | volatile void Init(); 7 | volatile void StoreNumber(); -------------------------------------------------------------------------------- /kernel/64/acpi.c: -------------------------------------------------------------------------------- 1 | #include "acpi.h" 2 | #include "vmalloc.h" 3 | 4 | RSDP_Descriptor* rsdp; 5 | 6 | bool CompareSignature(char *a, char *b) 7 | { 8 | for (int i = 0; i < 4; i++) 9 | { 10 | if (a[i] != b[i]) return false; 11 | } 12 | return true; 13 | } 14 | 15 | void *ACPIFindTable(char name[4]) 16 | { 17 | if (!rsdp->Xsdt && !rsdp->Revision) 18 | { 19 | uint32_t* TablePtrs = rsdp->Rsdt + 36; 20 | uint32_t NumEntries = 0x1000; 21 | for (uint32_t i = 0; i < NumEntries; i++) 22 | { 23 | ACPI_SDTHeader *TableHeader = (ACPI_SDTHeader*)TablePtrs[i]; 24 | AllocIdMap(TablePtrs[i], 0x1000, (1 << MALLOC_READWRITE_BIT) | (1 << MALLOC_CACHE_DISABLE_BIT)); 25 | if (CompareSignature(TableHeader->Signature, name)) 26 | { 27 | return TableHeader; 28 | } 29 | AllocUnMap(TablePtrs[i], 0x1000); 30 | } 31 | } 32 | else 33 | { 34 | uint64_t* TablePtrs = rsdp->Xsdt + 36; 35 | uint32_t NumEntries = 0x1000; 36 | for (uint32_t i = 0; i < NumEntries; i++) 37 | { 38 | ACPI_SDTHeader *TableHeader = (ACPI_SDTHeader*)TablePtrs[i]; 39 | AllocIdMap(TablePtrs[i], 0x1000, (1 << MALLOC_READWRITE_BIT) | (1 << MALLOC_CACHE_DISABLE_BIT)); 40 | if (CompareSignature(TableHeader->Signature, name)) 41 | { 42 | return TableHeader; 43 | } 44 | AllocUnMap(TablePtrs[i], 0x1000); 45 | } 46 | } 47 | } 48 | 49 | void ACPIInit() 50 | { 51 | rsdp = 0x7ED0; 52 | 53 | if (!rsdp->Xsdt && !rsdp->Revision) AllocIdMap(rsdp->Rsdt, 0x10000, (1 << MALLOC_READWRITE_BIT) | (1 << MALLOC_CACHE_DISABLE_BIT)); 54 | else AllocIdMap(rsdp->Xsdt, 0x10000, (1 << MALLOC_READWRITE_BIT) | (1 << MALLOC_CACHE_DISABLE_BIT)); 55 | } 56 | -------------------------------------------------------------------------------- /kernel/64/acpi.h: -------------------------------------------------------------------------------- 1 | #ifndef ACPI_H 2 | #define ACPI_H 3 | 4 | #include 5 | 6 | typedef struct { 7 | char Signature[4]; 8 | uint32_t Length; 9 | uint8_t Revision; 10 | uint8_t Checksum; 11 | char OEMID[6]; 12 | char OEMTableID[8]; 13 | uint32_t OEMRevision; 14 | uint32_t CreatorID; 15 | uint32_t CreatorRevision; 16 | } __attribute__((packed)) ACPI_SDTHeader; 17 | 18 | typedef struct { 19 | char Signature[8]; 20 | uint8_t Checksum; 21 | char OEMID[6]; 22 | uint8_t Revision; 23 | uint32_t Rsdt; 24 | 25 | uint32_t Length; 26 | uint64_t Xsdt; 27 | uint8_t ExtendedChecksum; 28 | uint8_t reserved[3]; 29 | } __attribute__((packed)) RSDP_Descriptor; 30 | 31 | 32 | 33 | void ACPIInit(); 34 | void *ACPIFindTable(char name[4]); 35 | 36 | #endif -------------------------------------------------------------------------------- /kernel/64/apic.c: -------------------------------------------------------------------------------- 1 | #define IA32_APIC_BASE_MSR 0x1BU 2 | #define IA32_APIC_BASE_MSR_BSP 0x100U // Processor is a BSP 3 | #define IA32_APIC_BASE_MSR_ENABLE 0x800U 4 | 5 | #include "../include.h" 6 | #include "msr.h" 7 | #include "vmalloc.h" 8 | #include "acpi.h" 9 | 10 | void* ApicVMAddr; 11 | void* IOApicAddr; 12 | void* IOApicVMAddr; 13 | uint32_t ApicID; 14 | uint32_t IOApicBaseInt; 15 | 16 | void SetApicBase(uint64_t apic) 17 | { 18 | uint32_t edx = 0; 19 | uint32_t eax = (apic & 0xfffff000ULL) | IA32_APIC_BASE_MSR_ENABLE; 20 | 21 | SetMSR(IA32_APIC_BASE_MSR, eax, edx); 22 | } 23 | 24 | uint64_t GetApicBase() 25 | { 26 | uint32_t lo, hi; 27 | GetMSR(IA32_APIC_BASE_MSR, &lo, &hi); 28 | return lo & 0xfffff000ULL; 29 | } 30 | 31 | void WriteReg(uint32_t Offset, uint32_t Value) 32 | { 33 | *(uint32_t volatile*)(ApicVMAddr + Offset) = Value; 34 | } 35 | 36 | void ApicEOI() 37 | { 38 | WriteReg(0xB0, 0x0); 39 | } 40 | 41 | uint32_t ReadReg(int Offset) 42 | { 43 | return *(uint32_t volatile*)(ApicVMAddr + Offset); 44 | } 45 | 46 | #define IOAPIC_IOREGSEL 0x00 47 | #define IOAPIC_IOWIN 0x10 48 | 49 | uint32_t ReadIoApic(uint32_t reg) 50 | { 51 | uint32_t volatile *ioapic = (uint32_t volatile *)IOApicVMAddr; 52 | ioapic[0] = (reg & 0xff); 53 | return ioapic[4]; 54 | } 55 | 56 | void WriteIoApic(uint32_t reg, uint32_t value) 57 | { 58 | uint32_t volatile *ioapic = (uint32_t volatile *)IOApicVMAddr; 59 | ioapic[0] = (reg & 0xff); 60 | ioapic[4] = value; 61 | } 62 | 63 | void RemapIrqToVector(uint8_t Irq, uint8_t Vector) 64 | { 65 | WriteIoApic(0x10 + 2*Irq, Vector); 66 | WriteIoApic(0x11 + 2*Irq, ReadReg(0x20) << 24); 67 | } 68 | 69 | void FindIOAPIC() 70 | { 71 | IOApicAddr = 0; 72 | 73 | uint8_t *Madt = ACPIFindTable("APIC"); // First find MADT 74 | if (!Madt) 75 | { 76 | *(uint32_t*)0xFFFFFFFF90000000 = 0xFFFFFFFF; 77 | *(uint32_t*)0xFFFFFFFF90000004 = 0xFFFFFFFF; 78 | *(uint32_t*)0xFFFFFFFF90000008 = 0xFFFFFFFF; 79 | *(uint32_t*)0xFFFFFFFF9000000c = 0xFFFFFFFF; 80 | asm volatile ("cli\nhlt"); 81 | } 82 | 83 | 84 | uint8_t *MadtEnd = Madt + *(uint32_t*)(Madt + 4); 85 | AllocIdMap(Madt + 0x2C, MadtEnd - Madt, (1 << MALLOC_READWRITE_BIT) | (1 << MALLOC_CACHE_DISABLE_BIT)); 86 | for (uint8_t *Ptr = Madt + 0x2C; Ptr < MadtEnd;Ptr += Ptr[1]) 87 | { 88 | if (*Ptr == 1) if (*(uint32_t*)(Ptr + 8) < 2) 89 | { 90 | IOApicAddr = *(uint32_t*)(Ptr + 4); 91 | IOApicBaseInt = *(uint32_t*)(Ptr + 8); 92 | } 93 | if (*Ptr == 0) ApicID = *(uint8_t*)(Ptr + 3); 94 | } 95 | 96 | if (!IOApicAddr) 97 | { 98 | *(uint32_t*)0xFFFFFFFF90000000 = 0xFFFFFFFF; 99 | *(uint32_t*)0xFFFFFFFF90000004 = 0xFFFFFFFF; 100 | *(uint32_t*)0xFFFFFFFF90000008 = 0xFFFFFFFF; 101 | *(uint32_t*)0xFFFFFFFF9000000c = 0xFFFFFFFF; 102 | asm volatile ("cli\nhlt"); 103 | } 104 | 105 | 106 | IOApicVMAddr = AllocVMAtPhys(IOApicAddr, 0x1000); 107 | for (uint8_t *Ptr = Madt + 0x2C; Ptr < MadtEnd;Ptr += Ptr[1]) 108 | { 109 | if (*Ptr == 2) 110 | { 111 | if (*(Ptr + 3) == 0 && *(uint32_t*)(Ptr + 4) == 2 && IOApicBaseInt == 1) asm volatile("cli\nhlt"); 112 | RemapIrqToVector(*(uint32_t*)(Ptr + 4), 32 + *(Ptr + 3)); 113 | } 114 | } 115 | } 116 | 117 | 118 | void ApicInit() 119 | { 120 | ApicVMAddr = AllocVMAtPhys(GetApicBase(), 0x1000); 121 | 122 | SetApicBase(GetApicBase()); 123 | 124 | WriteReg(0xF0, (ReadReg(0xF0) | 0x1FF) & ~(1ULL << 12)); 125 | 126 | WriteReg(0xE0, ReadReg(0xE0) | 0b1111U); 127 | 128 | FindIOAPIC(); 129 | 130 | //RemapIrqToVector(2, 32); 131 | RemapIrqToVector(1, 33); 132 | RemapIrqToVector(15, 0x72); 133 | } -------------------------------------------------------------------------------- /kernel/64/apic.h: -------------------------------------------------------------------------------- 1 | #ifndef APIC_H 2 | #define APIC_H 3 | 4 | #include "../include.h" 5 | 6 | typedef struct { 7 | char Signature[8]; 8 | uint8_t Checksum; 9 | char OEMID[6]; 10 | uint8_t Revision; 11 | uint32_t Rsdt; 12 | 13 | uint32_t Length; 14 | uint64_t Xsdt; 15 | uint8_t ExtendedChecksum; 16 | uint8_t reserved[3]; 17 | } __attribute__((packed)) rsdp_descriptor; 18 | 19 | void ApicInit(); 20 | void ApicEOI(); 21 | uint32_t GetApicBase(); 22 | 23 | #endif // APIC_H -------------------------------------------------------------------------------- /kernel/64/draw.c: -------------------------------------------------------------------------------- 1 | #include "draw.h" 2 | #include "font.h" 3 | #include "../vbe.h" 4 | 5 | static void* OutFramebuffer; 6 | 7 | static uint32_t TransformCol(uint32_t Col) 8 | { 9 | VesaVbeModeInfo* VbeModeInfo = VBE_INFO_LOC; 10 | uint32_t Blue = Col & 0xFF; 11 | uint32_t Green = (Col & 0xFF00) >> 8; 12 | uint32_t Red = (Col & 0xFF0000) >> 16; 13 | return (Red << VbeModeInfo->RedPosition) | (Green << VbeModeInfo->GreenPosition) | (Blue << VbeModeInfo->BluePosition); 14 | } 15 | 16 | void Draw_Init(void* Framebuffer) 17 | { 18 | OutFramebuffer = Framebuffer; 19 | } 20 | 21 | void Draw_Point(Draw_PointEntry Point) 22 | { 23 | VesaVbeModeInfo* VbeModeInfo = VBE_INFO_LOC; 24 | if (Point.x < 0) return; 25 | if (Point.y < 0) return; 26 | if (Point.x >= VbeModeInfo->Width) return; 27 | if (Point.y >= VbeModeInfo->Height) return; 28 | 29 | Point.col = TransformCol(Point.col); 30 | 31 | *(uint32_t*)(OutFramebuffer + (Point.x + Point.y * VbeModeInfo->Width) * 4) = Point.col; 32 | } 33 | 34 | void Draw_Line(Draw_LineEntry Line) 35 | { 36 | VesaVbeModeInfo* VbeModeInfo = VBE_INFO_LOC; 37 | Line.col = TransformCol(Line.col); 38 | 39 | float fx = Line.x0; 40 | float fy = Line.y0; 41 | for (;(int)fx != Line.x1 || (int)fy != Line.y1;fx += ((float)Line.x1 - Line.x0) / VbeModeInfo->Width,fy += ((float)Line.y1 - Line.y0) / VbeModeInfo->Width) 42 | { 43 | int x = fx; 44 | int y = fy; 45 | if (x < 0) continue; 46 | if (y < 0) continue; 47 | if (x >= VbeModeInfo->Width) continue; 48 | if (y >= VbeModeInfo->Height) continue; 49 | *(uint32_t*)(OutFramebuffer + (x + y * VbeModeInfo->Width) * 4) = Line.col; 50 | } 51 | } 52 | 53 | void Draw_Rect(Draw_RectEntry Rect) 54 | { 55 | VesaVbeModeInfo* VbeModeInfo = VBE_INFO_LOC; 56 | Rect.col = TransformCol(Rect.col); 57 | 58 | for (int y = Rect.y;y < Rect.y + Rect.h;y++) 59 | { 60 | if (y < 0) continue; 61 | if (y >= VbeModeInfo->Height) continue; 62 | for (int x = Rect.x;x < Rect.x + Rect.w;x++) 63 | { 64 | if (x < 0) continue; 65 | if (x >= VbeModeInfo->Width) continue; 66 | *(uint32_t*)(0xFFFFFFFF90000000 + (x + y * VbeModeInfo->Width) * 4) = Rect.col; 67 | } 68 | } 69 | } 70 | 71 | void Draw_Text(Draw_TextEntry Text) 72 | { 73 | VesaVbeModeInfo* VbeModeInfo = VBE_INFO_LOC; 74 | Text.col = TransformCol(Text.col); 75 | 76 | for (int i = 0;Text.text[i];i++) 77 | { 78 | uint8_t* ValP = SysFont[Text.text[i]]; 79 | for (int iy = 0;iy < 8;iy++) 80 | { 81 | uint8_t ValY = ValP[iy]; 82 | for (int ix = 0;ix < 8;ix++) 83 | { 84 | int x = ix + i * 0x8 + Text.x; 85 | int y = iy + Text.y; 86 | uint8_t Val = (ValY >> ix) & 1; 87 | if (!Val) 88 | { 89 | *(uint32_t*)(0xFFFFFFFF90000000 + (x + y * VbeModeInfo->Width) * 4) = 0; 90 | continue; 91 | } 92 | if (x < 0) continue; 93 | if (y < 0) continue; 94 | if (x >= VbeModeInfo->Width) continue; 95 | if (y >= VbeModeInfo->Height) continue; 96 | *(uint32_t*)(0xFFFFFFFF90000000 + (x + y * VbeModeInfo->Width) * 4) = Text.col; 97 | } 98 | } 99 | } 100 | } 101 | 102 | void Draw_Image(Draw_ImageEntry Image) 103 | { 104 | VesaVbeModeInfo* VbeModeInfo = VBE_INFO_LOC; 105 | for (int y = Image.y;y < Image.y + Image.h;y++) 106 | { 107 | if (y < 0) continue; 108 | if (y >= VbeModeInfo->Height) continue; 109 | for (int x = Image.x;x < Image.x + Image.w;x++) 110 | { 111 | if (x < 0) continue; 112 | if (x >= VbeModeInfo->Width) continue; 113 | *(uint32_t*)(0xFFFFFFFF90000000 + (x + y * VbeModeInfo->Width) * 4) = TransformCol(Image.image[(x - Image.x) + (y - Image.y) * Image.w]); 114 | } 115 | } 116 | } 117 | 118 | size_t Draw_GetResX() 119 | { 120 | VesaVbeModeInfo* VbeModeInfo = VBE_INFO_LOC; 121 | return VbeModeInfo->Width; 122 | } 123 | 124 | size_t Draw_GetResY() 125 | { 126 | VesaVbeModeInfo* VbeModeInfo = VBE_INFO_LOC; 127 | return VbeModeInfo->Height; 128 | } -------------------------------------------------------------------------------- /kernel/64/draw.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAW_H 2 | #define DRAW_H 3 | 4 | #include "../include.h" 5 | #include "../draw.h" 6 | 7 | void Draw_Init(void* Framebuffer); 8 | void Draw_Point(Draw_PointEntry Point); 9 | void Draw_Line(Draw_LineEntry Line); 10 | void Draw_Rect(Draw_RectEntry Rect); 11 | void Draw_Text(Draw_TextEntry Text); 12 | void Draw_Image(Draw_ImageEntry Image); 13 | size_t Draw_GetResX(); 14 | size_t Draw_GetResY(); 15 | 16 | #endif // DRAW_H -------------------------------------------------------------------------------- /kernel/64/drivers/driverman.c: -------------------------------------------------------------------------------- 1 | #include "driverman.h" 2 | #include "../vmalloc.h" 3 | #include "../memtools.h" 4 | #include "../panic.h" 5 | 6 | // DRIVER INCLUDES 7 | 8 | // Storage 9 | #include "nvme/nvme.h" 10 | 11 | // Filesystem 12 | #include "fs/fs.h" 13 | 14 | static DriverMan_Manager* Manager; 15 | 16 | extern void* DriverIrqTable[10]; 17 | 18 | void DriverMan_RegisterStorageDriver(DriverMan_StorageDriver* Driver) 19 | { 20 | Manager->StorageDrivers[Manager->NumStorageDrivers++] = Driver; 21 | DriverMan_StorageDriver** NewDrivers = AllocVM(sizeof(DriverMan_StorageDriver*) * (Manager->NumStorageDrivers + 1)); 22 | memcpy(NewDrivers, Manager->StorageDrivers, sizeof(DriverMan_StorageDriver*) * Manager->NumStorageDrivers); 23 | FreeVM(Manager->StorageDrivers); 24 | Manager->StorageDrivers = NewDrivers; 25 | } 26 | 27 | void DriverMan_RegisterFilesysDriver(DriverMan_FilesystemDriver* Driver) 28 | { 29 | Manager->FilesysDrivers[Manager->NumFilesysDrivers++] = Driver; 30 | DriverMan_FilesystemDriver** NewDrivers = AllocVM(sizeof(DriverMan_FilesystemDriver*) * (Manager->NumFilesysDrivers + 1)); 31 | memcpy(NewDrivers, Manager->FilesysDrivers, sizeof(DriverMan_FilesystemDriver*) * Manager->NumFilesysDrivers); 32 | FreeVM(Manager->FilesysDrivers); 33 | Manager->FilesysDrivers = NewDrivers; 34 | } 35 | 36 | void DriverMan_GetFilesysDrivers(DriverMan_FilesystemDriver*** OutFilesysDrivers, size_t* OutFilesysDriversNum) 37 | { 38 | *OutFilesysDrivers = Manager->FilesysDrivers; 39 | *OutFilesysDriversNum = Manager->NumFilesysDrivers; 40 | } 41 | 42 | void DriverMan_GetStorageDrivers(DriverMan_StorageDriver*** OutStorageDrivers, size_t* OutStorageDriversNum) 43 | { 44 | *OutStorageDrivers = Manager->StorageDrivers; 45 | *OutStorageDriversNum = Manager->NumStorageDrivers; 46 | } 47 | 48 | void DriverMan_GetStorageDevices(DriverMan_StorageDevice*** OutStorageDevices, size_t* OutStorageDevicesNum) 49 | { 50 | *OutStorageDevices = Manager->StorageDevices; 51 | *OutStorageDevicesNum = Manager->NumStorageDevices; 52 | } 53 | 54 | void DriverMan_Init() 55 | { 56 | Manager = AllocVM(sizeof(DriverMan_Manager)); 57 | 58 | Manager->NextIRQ = 0x70; 59 | 60 | Manager->StorageDevices = 0; 61 | Manager->NumStorageDevices = 0; 62 | Manager->StorageDrivers = AllocVM(sizeof(DriverMan_StorageDriver*)); 63 | Manager->NumStorageDrivers = 0; 64 | 65 | DriverMan_RegisterStorageDriver(NVMe_GetDriver()); 66 | 67 | for (int i = 0;i < Manager->NumStorageDrivers;i++) 68 | { 69 | if (Manager->StorageDrivers[i]->NeedsIRQ) 70 | { 71 | Manager->StorageDrivers[i]->IRQ = Manager->NextIRQ++; 72 | DriverIrqTable[Manager->StorageDrivers[i]->IRQ - 0x70] = Manager->StorageDrivers[i]->DriverIRQ; 73 | } 74 | Manager->StorageDrivers[i]->DriverInit(Manager->StorageDrivers[i]); 75 | 76 | 77 | size_t OriginalNum = Manager->NumStorageDevices; 78 | Manager->NumStorageDevices += Manager->StorageDrivers[i]->NumDevices; 79 | DriverMan_StorageDevice** NewDevices = AllocVM(sizeof(DriverMan_StorageDevice*) * Manager->NumStorageDevices); 80 | if (Manager->StorageDevices) memcpy(NewDevices, Manager->StorageDevices, sizeof(DriverMan_StorageDevice*) * OriginalNum); 81 | for (int j = 0;j < Manager->StorageDrivers[i]->NumDevices;j++) 82 | { 83 | NewDevices[OriginalNum + j] = &Manager->StorageDrivers[i]->Devices[j]; 84 | } 85 | FreeVM(Manager->StorageDevices); 86 | Manager->StorageDevices = NewDevices; 87 | } 88 | 89 | 90 | Manager->FilesysDrivers = AllocVM(sizeof(DriverMan_FilesystemDriver*)); 91 | Manager->NumFilesysDrivers = 0; 92 | 93 | DriverMan_RegisterFilesysDriver(CustomFS_GetDriver()); 94 | 95 | for (int i = 0;i < Manager->NumStorageDevices;i++) 96 | { 97 | Manager->StorageDevices[i]->FormatType = 0; 98 | 99 | for (int j = 0;j < Manager->NumFilesysDrivers;j++) 100 | { 101 | if (Manager->FilesysDrivers[j]->FilesysIsFormatted(Manager->FilesysDrivers[j], Manager->StorageDevices[i])) 102 | { 103 | Manager->StorageDevices[i]->FormatType = Manager->FilesysDrivers[j]; 104 | break; 105 | } 106 | } 107 | } 108 | } 109 | 110 | static bool Strcmp(char* x, char* y) 111 | { 112 | int xlen = 0, ylen = 0; 113 | while (x[xlen] && x[xlen] != ' ') xlen++; 114 | while (y[ylen] && x[ylen] != ' ') ylen++; 115 | 116 | if (xlen != ylen) return false; 117 | 118 | for (int i = 0;i < xlen;i++) 119 | { 120 | if (x[i] != y[i]) return false; 121 | } 122 | return true; 123 | } 124 | 125 | DriverMan_StorageDriver* DriverMan_GetStorageDriver(const char* Name) 126 | { 127 | for (int i = 0;i < Manager->NumStorageDrivers;i++) 128 | { 129 | if (Strcmp(Manager->StorageDrivers[i]->Header.Name, Name)) return Manager->StorageDrivers[i]; 130 | } 131 | return 0; 132 | } 133 | 134 | DriverMan_FilesystemDriver* DriverMan_GetFilesysDriver(const char* Name) 135 | { 136 | for (int i = 0;i < Manager->NumFilesysDrivers;i++) 137 | { 138 | if (Strcmp(Manager->FilesysDrivers[i]->Header.Name, Name)) return Manager->FilesysDrivers[i]; 139 | } 140 | return 0; 141 | } 142 | 143 | void DriverMan_Run() 144 | { 145 | FreeVM(Manager->StorageDevices); 146 | Manager->StorageDevices = 0; 147 | Manager->NumStorageDevices = 0; 148 | 149 | for (int i = 0;i < Manager->NumStorageDrivers;i++) 150 | { 151 | Manager->StorageDrivers[i]->DriverRun(Manager->StorageDrivers[i]); 152 | 153 | size_t OriginalNum = Manager->NumStorageDevices; 154 | Manager->NumStorageDevices += Manager->StorageDrivers[i]->NumDevices; 155 | DriverMan_StorageDevice** NewDevices = AllocVM(sizeof(DriverMan_StorageDevice*) * Manager->NumStorageDevices); 156 | memcpy(NewDevices, Manager->StorageDevices, sizeof(DriverMan_StorageDevice*) * OriginalNum); 157 | for (int j = 0;j < Manager->StorageDrivers[i]->NumDevices;j++) 158 | { 159 | NewDevices[OriginalNum + j] = &Manager->StorageDrivers[i]->Devices[j]; 160 | } 161 | FreeVM(Manager->StorageDevices); 162 | Manager->StorageDevices = NewDevices; 163 | } 164 | } 165 | 166 | void DriverMan_StorageReadFromDevice(DriverMan_StorageDevice* Device, size_t NumSectors, uint32_t LBA, void* Dest) 167 | { 168 | Device->ParentDriver->StorageRead(Device->ParentDriver, Device->MyID, NumSectors, LBA, Dest); 169 | } 170 | 171 | void DriverMan_StorageWriteToDevice(DriverMan_StorageDevice* Device, size_t NumSectors, uint32_t LBA, void* Src) 172 | { 173 | Device->ParentDriver->StorageWrite(Device->ParentDriver, Device->MyID, NumSectors, LBA, Src); 174 | } 175 | 176 | void DriverMan_FilesysFormat(DriverMan_StorageDevice* Device, char* FSName) 177 | { 178 | DriverMan_FilesystemDriver* Driver = DriverMan_GetFilesysDriver(FSName); 179 | if (!Driver) return; 180 | Driver->FilesysFormat(Driver, Device); 181 | Device->FormatType = Driver; 182 | } 183 | 184 | bool DriverMan_FilesysTryFormat(DriverMan_StorageDevice* Device, char* FSName) 185 | { 186 | DriverMan_FilesystemDriver* Driver = DriverMan_GetFilesysDriver(FSName); 187 | if (!Driver) return; 188 | bool Formatted = Driver->FilesysTryFormat(Driver, Device); 189 | if (Formatted) Device->FormatType = Driver; 190 | return Formatted; 191 | } 192 | 193 | bool DriverMan_FilesysIsFormatted(DriverMan_StorageDevice* Device) 194 | { 195 | return Device->FormatType != 0; 196 | } 197 | 198 | bool DriverMan_FilesysMakeFile(DriverMan_StorageDevice* Device, char* File) 199 | { 200 | if (Device->FormatType == 0) return false; 201 | return Device->FormatType->FilesysMakeFile(Device->FormatType, Device, File); 202 | } 203 | 204 | bool DriverMan_FilesysMakeDir(DriverMan_StorageDevice* Device, char* Dir) 205 | { 206 | if (Device->FormatType == 0) return false; 207 | return Device->FormatType->FilesysMakeDir(Device->FormatType, Device, Dir); 208 | } 209 | 210 | bool DriverMan_FilesysRemove(DriverMan_StorageDevice* Device, char* AnyDir) 211 | { 212 | if (Device->FormatType == 0) return false; 213 | return Device->FormatType->FilesysRemove(Device->FormatType, Device, AnyDir); 214 | } 215 | 216 | bool DriverMan_FilesysWriteFile(DriverMan_StorageDevice* Device, char* File, void* Data, size_t Bytes) 217 | { 218 | if (Device->FormatType == 0) return false; 219 | return Device->FormatType->FilesysWriteFile(Device->FormatType, Device, File, Data, Bytes); 220 | } 221 | 222 | void* DriverMan_FilesysReadFile(DriverMan_StorageDevice* Device, char* File, size_t* BytesRead) 223 | { 224 | if (Device->FormatType == 0) return false; 225 | return Device->FormatType->FilesysReadFile(Device->FormatType, Device, File, BytesRead); 226 | } 227 | 228 | FileListEntry* DriverMan_FilesysListFiles(DriverMan_StorageDevice* Device, char* Dir, size_t* NumFiles) 229 | { 230 | if (Device->FormatType == 0) return false; 231 | return Device->FormatType->FilesysListFiles(Device->FormatType, Device, Dir, NumFiles); 232 | } 233 | 234 | size_t DriverMan_FilesysFileSize(DriverMan_StorageDevice* Device, char* File) 235 | { 236 | if (Device->FormatType == 0) return false; 237 | return Device->FormatType->FilesysFileSize(Device->FormatType, Device, File); 238 | } -------------------------------------------------------------------------------- /kernel/64/drivers/driverman.h: -------------------------------------------------------------------------------- 1 | #ifndef DRIVER_MAN_H 2 | #define DRIVER_MAN_H 3 | 4 | #include "../../include.h" 5 | 6 | typedef struct 7 | { 8 | const char* Name; 9 | uint32_t Version; // Low 16 bits: Minor version, High 16 bits: Major version 10 | } DriverMan_DriverHeader; 11 | 12 | struct _DriverMan_StorageDriver; 13 | 14 | struct _DriverMan_FilesystemDriver; 15 | 16 | typedef struct 17 | { 18 | struct _DriverMan_StorageDriver* ParentDriver; // The driver that controls the device 19 | size_t MyID; // The index of the device in it's parent driver's device list 20 | size_t MyUID; // The unique identifier of this device (not unique across different drivers), useful for checking if the device is still in the parent driver's devices list 21 | size_t MaxReadSectorCount; // When performing a read operation, the amount of sectors to read can never be above this value 22 | size_t MaxWriteSectorCount; // When performing a write operation, the amount of sectors to read can never be above this value 23 | size_t Capacity; // Size of the storage device in bytes 24 | 25 | struct _DriverMan_FilesystemDriver* FormatType; // 0 if unknown format 26 | } DriverMan_StorageDevice; 27 | 28 | typedef struct _DriverMan_StorageDriver 29 | { 30 | DriverMan_DriverHeader Header; 31 | 32 | bool NeedsIRQ; // The driver sets this to true in its Init function if it needs an IRQ allocated for it 33 | 34 | size_t IRQ; // The IRQ that this driver is using for interrupts 35 | void(*DriverIRQ)(); // This is the IRQ handler for the driver 36 | 37 | DriverMan_StorageDevice* Devices; 38 | size_t NumDevices; 39 | 40 | void(*DriverInit)(struct _DriverMan_StorageDriver* MyDriver); // The driver must have the Devices member fully allocated and filled out by the end of this function 41 | void(*DriverRun)(struct _DriverMan_StorageDriver* MyDriver); // This function runs repeatedly so that the driver can do things like refresh the connected devices 42 | bool(*StorageRead)(struct _DriverMan_StorageDriver* MyDriver, int DeviceIdx, size_t NumSectors, uint32_t LBA, void* Dest); 43 | bool(*StorageWrite)(struct _DriverMan_StorageDriver* MyDriver, int DeviceIdx, size_t NumSectors, uint32_t LBA, void* Src); 44 | } DriverMan_StorageDriver; 45 | 46 | #include "../../file.h" 47 | 48 | typedef struct _DriverMan_FilesystemDriver 49 | { 50 | DriverMan_DriverHeader Header; 51 | 52 | void(*DriverInit)(struct _DriverMan_FilesystemDriver* MyDriver); // The driver must have the Devices member fully allocated and filled out by the end of this function 53 | void(*FilesysFormat)(struct _DriverMan_FilesystemDriver* MyDriver, DriverMan_StorageDevice* Device); 54 | bool(*FilesysTryFormat)(struct _DriverMan_FilesystemDriver* MyDriver, DriverMan_StorageDevice* Device); // Returns true if ended up formatting 55 | bool(*FilesysIsFormatted)(struct _DriverMan_FilesystemDriver* MyDriver, DriverMan_StorageDevice* Device); 56 | bool(*FilesysMakeFile)(struct _DriverMan_FilesystemDriver* MyDriver, DriverMan_StorageDevice* Device, char* File); 57 | bool(*FilesysMakeDir)(struct _DriverMan_FilesystemDriver* MyDriver, DriverMan_StorageDevice* Device, char* Dir); 58 | bool(*FilesysRemove)(struct _DriverMan_FilesystemDriver* MyDriver, DriverMan_StorageDevice* Device, char* AnyDir); 59 | bool(*FilesysWriteFile)(struct _DriverMan_FilesystemDriver* MyDriver, DriverMan_StorageDevice* Device, char* File, void* Data, size_t Bytes); 60 | void*(*FilesysReadFile)(struct _DriverMan_FilesystemDriver* MyDriver, DriverMan_StorageDevice* Device, char* File, size_t* BytesRead); 61 | size_t(*FilesysFileSize)(struct _DriverMan_FilesystemDriver* MyDriver, DriverMan_StorageDevice* Device, char* File); 62 | FileListEntry*(*FilesysListFiles)(struct _DriverMan_FilesystemDriver* MyDriver, DriverMan_StorageDevice* Device, char* Dir, size_t* NumFiles); 63 | } DriverMan_FilesystemDriver; 64 | 65 | typedef struct _DriverMan_Manager 66 | { 67 | DriverMan_StorageDevice** StorageDevices; 68 | size_t NumStorageDevices; 69 | DriverMan_StorageDriver** StorageDrivers; 70 | size_t NumStorageDrivers; 71 | 72 | DriverMan_FilesystemDriver** FilesysDrivers; 73 | size_t NumFilesysDrivers; 74 | 75 | size_t NextIRQ; 76 | } DriverMan_Manager; 77 | 78 | void DriverMan_Init(); 79 | void DriverMan_Run(); 80 | 81 | void DriverMan_RegisterStorageDriver(DriverMan_StorageDriver* Driver); 82 | DriverMan_StorageDriver* DriverMan_GetStorageDriver(const char* Name); 83 | void DriverMan_GetStorageDrivers(DriverMan_StorageDriver*** OutStorageDrivers, size_t* OutStorageDriversNum); 84 | void DriverMan_GetStorageDevices(DriverMan_StorageDevice*** OutStorageDevices, size_t* OutStorageDevicesNum); 85 | void DriverMan_StorageReadFromDevice(DriverMan_StorageDevice* Device, size_t NumSectors, uint32_t LBA, void* Dest); 86 | void DriverMan_StorageWriteToDevice(DriverMan_StorageDevice* Device, size_t NumSectors, uint32_t LBA, void* Src); 87 | 88 | void DriverMan_RegisterFilesysDriver(DriverMan_FilesystemDriver* Driver); 89 | DriverMan_FilesystemDriver* DriverMan_GetFilesysDriver(const char* Name); 90 | void DriverMan_GetFilesysDrivers(DriverMan_FilesystemDriver*** OutFilesysDrivers, size_t* OutFilesysDriversNum); 91 | void DriverMan_FilesysFormat(DriverMan_StorageDevice* Device, char* FSName); 92 | bool DriverMan_FilesysTryFormat(DriverMan_StorageDevice* Device, char* FSName); // Returns true if ended up formatting 93 | bool DriverMan_FilesysIsFormatted(DriverMan_StorageDevice* Device); 94 | bool DriverMan_FilesysMakeFile(DriverMan_StorageDevice* Device, char* File); 95 | bool DriverMan_FilesysMakeDir(DriverMan_StorageDevice* Device, char* Dir); 96 | bool DriverMan_FilesysRemove(DriverMan_StorageDevice* Device, char* AnyDir); 97 | bool DriverMan_FilesysWriteFile(DriverMan_StorageDevice* Device, char* File, void* Data, size_t Bytes); 98 | void* DriverMan_FilesysReadFile(DriverMan_StorageDevice* Device, char* File, size_t* BytesRead); 99 | size_t DriverMan_FilesysFileSize(DriverMan_StorageDevice* Device, char* File); 100 | FileListEntry* DriverMan_FilesysListFiles(DriverMan_StorageDevice* Device, char* Dir, size_t* NumFiles); 101 | 102 | #endif // DRIVER_MAN_H -------------------------------------------------------------------------------- /kernel/64/drivers/fs/fs.h: -------------------------------------------------------------------------------- 1 | #ifndef FS_H 2 | #define FS_H 3 | 4 | #include "../driverman.h" 5 | #include "../../../include.h" 6 | #include "../../../file.h" 7 | 8 | DriverMan_FilesystemDriver* CustomFS_GetDriver(); 9 | 10 | #endif // FS_H -------------------------------------------------------------------------------- /kernel/64/drivers/hpet/hpet.c: -------------------------------------------------------------------------------- 1 | #include "hpet.h" 2 | #include "../../vmalloc.h" 3 | 4 | typedef struct { 5 | uint64_t RevID:8; 6 | uint64_t TimerCount:5; 7 | uint64_t CounterSize:1; 8 | uint64_t Reserved:1; 9 | uint64_t LegacyReplacement:1; 10 | uint64_t VendorID:16; 11 | uint64_t CounterPeriod:32; 12 | } __attribute__((packed)) HPET_RegCapabilites; 13 | 14 | typedef struct { 15 | uint64_t EnableCnf:1; 16 | uint64_t LegacyRouteCap:1; 17 | uint64_t Reserved:62; 18 | } __attribute__((packed)) HPET_RegConfig; 19 | 20 | typedef struct { 21 | uint64_t Timer0_InterruptStatus:1; 22 | uint64_t Timer1_InterruptStatus:1; 23 | uint64_t Timer2_InterruptStatus:1; 24 | uint64_t Reserved:62; 25 | } __attribute__((packed)) HPET_RegInterrupt; 26 | 27 | typedef struct { 28 | uint64_t Reserved0:1; 29 | uint64_t InterruptType:1; 30 | uint64_t InterruptEnable:1; 31 | uint64_t TimerType:1; 32 | uint64_t TimerPeriodicCapable:1; 33 | uint64_t TimerSize:1; 34 | uint64_t TimerValueSet:1; 35 | uint64_t Reserved1:1; 36 | uint64_t TimerInterruptNo:5; 37 | uint64_t TimerFSBEnable:1; 38 | uint64_t TimerFSBCapable:1; 39 | uint64_t Reserved2:17; 40 | uint64_t TimerInterruptCapabilities:32; // which interrupts can be routed to this timer (bitmap) 41 | } __attribute__((packed)) HPET_TimerConfig; 42 | 43 | typedef struct { 44 | uint64_t TimerValue; 45 | } __attribute__((packed)) HPET_ComparatorValue; 46 | 47 | typedef struct { 48 | uint32_t FSBValue; // what value to write to addr 49 | uint32_t FSBAddr; // what address to write to 50 | } __attribute__((packed)) HPET_TimerComparator; 51 | 52 | typedef struct { 53 | HPET_TimerConfig Config; 54 | uint64_t ComparatorValue; 55 | uint64_t ComparatorFSBValue; 56 | uint64_t Reserved; 57 | } __attribute__((packed)) HPET_Timer; 58 | 59 | typedef struct { 60 | HPET_RegCapabilites Capabilites; 61 | uint64_t Reserved0; 62 | HPET_RegConfig Config; 63 | uint64_t Reserved1; 64 | HPET_RegInterrupt Interrupt; 65 | uint64_t Reserved2; 66 | uint64_t MainCounterValue; 67 | uint64_t Reserved3; 68 | HPET_Timer Timers[32]; 69 | } __attribute__((packed)) HPET; 70 | 71 | HPET *HPET_State; 72 | static uint64_t HPET_Freq; 73 | static uint16_t HPET_MinTick; 74 | 75 | // Returns -1 if no periodic timer found 76 | static int GetFirstPeriodicTimer(HPET* HPET_State) 77 | { 78 | for (int i = 0;i < 32;i++) 79 | { 80 | if (HPET_State->Timers[i].Config.TimerPeriodicCapable) return i; 81 | } 82 | return -1; 83 | } 84 | 85 | bool HPETInit() 86 | { 87 | HPET_Table *HPET_TBL = ACPIFindTable("HPET"); 88 | 89 | if (HPET_TBL) 90 | { 91 | HPET_State = (HPET*)HPET_TBL->address; 92 | AllocVMAtFlags(HPET_TBL->address, 0x1000, (1 << MALLOC_READWRITE_BIT) | (1 << MALLOC_CACHE_DISABLE_BIT)); 93 | 94 | HPET_Freq = 1e15 / HPET_State->Capabilites.CounterPeriod; 95 | HPET_MinTick = HPET_TBL->minimum_tick; 96 | HPET_RegConfig Config = HPET_State->Config; 97 | Config.EnableCnf = 1; 98 | HPET_State->Config = Config; 99 | 100 | int TimerIdx = GetFirstPeriodicTimer(HPET_State); 101 | if (TimerIdx == -1) return false; 102 | HPET_Timer* timer = &HPET_State->Timers[TimerIdx]; 103 | timer->Config.TimerType = 1; 104 | timer->Config.TimerValueSet = 1; 105 | timer->ComparatorValue = HPET_State->MainCounterValue + 10000000; 106 | timer->Config.TimerInterruptNo = 15; 107 | timer->Config.InterruptEnable = 1; 108 | } 109 | 110 | return HPET_TBL; 111 | } 112 | -------------------------------------------------------------------------------- /kernel/64/drivers/hpet/hpet.h: -------------------------------------------------------------------------------- 1 | #ifndef HPET_H 2 | #define HPET_H 3 | 4 | #ifndef __attribute__ 5 | #define __attribute__(x) 6 | #endif 7 | #include "../../acpi.h" 8 | #include 9 | 10 | typedef struct 11 | { 12 | ACPI_SDTHeader header; 13 | 14 | uint8_t hardware_rev_id; 15 | uint8_t comparator_count:5; 16 | uint8_t counter_size:1; 17 | uint8_t reserved0:1; 18 | uint8_t legacy_replacement:1; 19 | uint16_t pci_vendor_id; 20 | uint8_t address_space_id; // 0 - system memory, 1 - system I/O 21 | uint8_t register_bit_width; 22 | uint8_t register_bit_offset; 23 | uint8_t reserved1; 24 | uint64_t address; 25 | uint8_t hpet_number; 26 | uint16_t minimum_tick; 27 | uint8_t page_protection; 28 | } HPET_Table __attribute__((packed)); 29 | 30 | 31 | bool HPETInit(); 32 | 33 | #endif -------------------------------------------------------------------------------- /kernel/64/drivers/ide/ata.s: -------------------------------------------------------------------------------- 1 | [BITS 64] 2 | 3 | section .text 4 | ; rcx = LBA 5 | ; rdi = Destination 6 | ; rdx = IO Port Start 7 | global _ReadAta 8 | _ReadAta: 9 | 10 | push rax 11 | push rdx 12 | push rcx 13 | push rbx 14 | push rdi 15 | push rsi 16 | and rcx, 1 17 | shl rcx, 4 18 | or rcx, 0b11100000 19 | 20 | mov rdi, rsi 21 | mov rsi, rcx 22 | mov rcx, rdi 23 | mov rbx, rdx 24 | 25 | mov rax, rsi 26 | and rcx, 0x0FFFFFFF 27 | shr rcx, 24 28 | or rax, rcx 29 | 30 | mov rdx, rbx 31 | add rdx, 6 32 | out dx, al 33 | 34 | mov rdx, rbx 35 | add rdx, 2 36 | mov al, 1 37 | out dx, al 38 | mov rax, rcx 39 | mov rdx, rbx 40 | add rdx, 3 41 | out dx, al 42 | mov rax, rcx 43 | shr rax, 8 44 | mov rdx, rbx 45 | add rdx, 4 46 | out dx, al 47 | mov rax, rcx 48 | shr rax, 16 49 | mov rdx, rbx 50 | add rdx, 5 51 | out dx, al 52 | mov rdx, rbx 53 | add rdx, 7 54 | mov al, 0x20 55 | out dx, al 56 | 57 | push rbx 58 | mov rcx, 0xFFFFFF 59 | 60 | .wait_drq_set: 61 | dec rcx 62 | test rcx, rcx 63 | jz .fail 64 | 65 | in al, dx 66 | 67 | test al, 1 68 | jnz .fail 69 | 70 | test al, 1 << 5 71 | jnz .fail 72 | .ready: 73 | pop rbx 74 | mov rcx, 256 75 | mov rdx, rbx 76 | rep insw 77 | 78 | pop rsi 79 | pop rdi 80 | pop rbx 81 | pop rcx 82 | pop rdx 83 | pop rax 84 | 85 | mov rax, 1 86 | 87 | ret 88 | .fail: 89 | pop rbx 90 | mov rax, rsi 91 | mov rdx, rbx 92 | add rdx, 6 93 | out dx, al 94 | 95 | mov rdx, rbx 96 | mov rax, 1 << 2 97 | out dx, al 98 | in al, 0x80 99 | mov rax, 0 100 | out dx, al 101 | 102 | 103 | pop rsi 104 | pop rdi 105 | pop rbx 106 | pop rcx 107 | pop rdx 108 | pop rax 109 | 110 | mov rax, 0 111 | 112 | ret -------------------------------------------------------------------------------- /kernel/64/drivers/ide/ide.c: -------------------------------------------------------------------------------- 1 | #include "ide.h" 2 | 3 | extern uint64_t _ReadAta(uint64_t LBA, void* Out, uint64_t IOStart, uint64_t IsSlave); 4 | extern uint64_t _AtaAvailable(uint64_t LBA, uint64_t IOStart, uint64_t IsSlave); 5 | 6 | static uint64_t BootDriveStart = 0; 7 | static uint64_t BootDriveMS = 0; 8 | 9 | uint8_t IDEInit() 10 | { 11 | char* TestBuf = 0x7B00; 12 | if (_ReadAta(0, TestBuf, 0x1f0, 0)) 13 | { 14 | for (int i = 0;i < 40;i++) 15 | { 16 | if (TestBuf[i] == 'U' && TestBuf[i + 1] == 'N') 17 | { 18 | BootDriveStart = 0x1f0; 19 | BootDriveMS = 0; 20 | return 1; 21 | } 22 | } 23 | } 24 | if (_ReadAta(0, TestBuf, 0x1f0, 1)) 25 | { 26 | for (int i = 0;i < 40;i++) 27 | { 28 | if (TestBuf[i] == 'U' && TestBuf[i + 1] == 'N') 29 | { 30 | BootDriveStart = 0x1f0; 31 | BootDriveMS = 1; 32 | return 1; 33 | } 34 | } 35 | } 36 | if (_ReadAta(0, TestBuf, 0x170, 0)) 37 | { 38 | for (int i = 0;i < 40;i++) 39 | { 40 | if (TestBuf[i] == 'U' && TestBuf[i + 1] == 'N') 41 | { 42 | BootDriveStart = 0x170; 43 | BootDriveMS = 0; 44 | return 1; 45 | } 46 | } 47 | } 48 | if (_ReadAta(0, TestBuf, 0x170, 1)) 49 | { 50 | for (int i = 0;i < 40;i++) 51 | { 52 | if (TestBuf[i] == 'U' && TestBuf[i + 1] == 'N') 53 | { 54 | BootDriveStart = 0x170; 55 | BootDriveMS = 1; 56 | return 1; 57 | } 58 | } 59 | } 60 | return 0; 61 | } 62 | 63 | void IDEReadBoot(uint64_t LBA, void* Out); -------------------------------------------------------------------------------- /kernel/64/drivers/ide/ide.h: -------------------------------------------------------------------------------- 1 | #ifndef IDE_H 2 | #define IDE_H 3 | 4 | #include "../../../include.h" 5 | #include "../driverman.h" 6 | 7 | // Deprecated, no support 8 | 9 | #endif // IDE_H -------------------------------------------------------------------------------- /kernel/64/drivers/nvme/nvme.h: -------------------------------------------------------------------------------- 1 | #ifndef NVME_H 2 | #define NVME_H 3 | 4 | #include "../../../include.h" 5 | #include "../driverman.h" 6 | 7 | typedef struct 8 | { 9 | bool Sent; 10 | bool Completed; 11 | } NVME_CmdStatus; 12 | 13 | DriverMan_StorageDriver* NVMe_GetDriver(); 14 | 15 | #endif // NVME_H -------------------------------------------------------------------------------- /kernel/64/drivers/ps2/ps2.c: -------------------------------------------------------------------------------- 1 | #include "ps2.h" 2 | #include "../../io.h" 3 | 4 | void MouseWait() 5 | { 6 | uint64_t timeout = 100000; 7 | while (timeout--){ 8 | if ((IO_In8(0x64) & 0b10) == 0){ 9 | return; 10 | } 11 | } 12 | } 13 | 14 | void MouseWaitInput() 15 | { 16 | uint64_t timeout = 100000; 17 | while (timeout--){ 18 | if (IO_In8(0x64) & 0b1){ 19 | return; 20 | } 21 | } 22 | } 23 | 24 | void MouseWrite(uint8_t AWrite) 25 | { 26 | IO_Out8(0x64, 0xD4); 27 | IO_Wait(); 28 | IO_Out8(0x60, AWrite); 29 | IO_Wait(); 30 | } 31 | 32 | uint8_t MouseRead() 33 | { 34 | IO_Wait(); 35 | return IO_In8(0x60); 36 | } 37 | 38 | void PS2Install() 39 | { 40 | IO_Out8(0x64, 0xAD); 41 | MouseWait(); 42 | IO_Out8(0x64, 0xA7); 43 | MouseWaitInput(); 44 | IO_Out8(0x64, 0x20); 45 | MouseWait(); 46 | uint8_t status = IO_In8(0x60) | 3; 47 | MouseWait(); 48 | IO_Out8(0x64, 0x60); 49 | MouseWait(); 50 | IO_Out8(0x60, status); 51 | MouseWrite(0xF6); 52 | MouseRead(); 53 | MouseWrite(0xF4); 54 | MouseRead(); 55 | 56 | IO_Out8(0x64, 0xAE); 57 | MouseWait(); 58 | IO_Out8(0x64, 0xA8); 59 | MouseWait(); 60 | } -------------------------------------------------------------------------------- /kernel/64/drivers/ps2/ps2.h: -------------------------------------------------------------------------------- 1 | #ifndef PS2_H 2 | #define PS2_H 3 | 4 | void PS2Install(); 5 | 6 | #endif // PS2_H -------------------------------------------------------------------------------- /kernel/64/drivers/usb/xhci.c: -------------------------------------------------------------------------------- 1 | #include "xhci.h" 2 | #include "../../pci.h" 3 | #include "../../vmalloc.h" 4 | #include "../../idt.h" 5 | #include "../../io.h" 6 | #include "../../iomem.h" 7 | #include "../../apic.h" 8 | #include "../../sleep.h" 9 | 10 | #define MAX_CONTROLLERS 256 11 | #define COMMAND_RING_SIZE 64 12 | #define EVENT_RING_SIZE 32 13 | #define ERST_SIZE 16 14 | 15 | // Register masks (little endian) | Mask | Bit offset | 16 | #define XHCIM_CAPLENGTH 0xFF, 16 17 | #define XHCIM_HCIVERSION 0xFFFF, 0 18 | #define XHCIM_HCSPARAMS1 0xFF, 0 19 | // TODO 20 | 21 | typedef struct 22 | { 23 | // uint8_t CapLength; 24 | // uint8_t Reserved0; 25 | // uint16_t HciVersion; 26 | 27 | // uint32_t MaxDeviceSlots : 8; 28 | // uint32_t MaxInterrupters : 11; 29 | // uint32_t Reserved1 : 5; 30 | // uint32_t MaxPorts : 8; 31 | 32 | // uint32_t IST : 4; 33 | // uint32_t ERSTMax : 4; 34 | // uint32_t Reserved2 : 13; 35 | // uint32_t MaxScratchpadBufsHi : 5; 36 | // uint32_t SPR : 1; 37 | // uint32_t MaxScratchpadBufsLo : 5; 38 | 39 | // uint32_t U1DeviceExitLatency : 8; 40 | // uint32_t U2DeviceExitLatency : 8; 41 | // uint32_t Reserved3 : 16; 42 | 43 | // uint32_t AC64 : 1; 44 | // uint32_t BNC : 1; 45 | // uint32_t CSZ : 1; 46 | // uint32_t PPC : 1; 47 | // uint32_t PIND : 1; 48 | // uint32_t LHRC : 1; 49 | // uint32_t LTC : 1; 50 | // uint32_t NSS : 1; 51 | // uint32_t PAE : 1; 52 | // uint32_t SPC : 1; 53 | // uint32_t SEC : 1; 54 | // uint32_t CFC : 1; 55 | // uint32_t MaxPSASize : 4; 56 | // uint32_t XECP : 16; 57 | 58 | // uint32_t Reserved4 : 2; 59 | // uint32_t DBOffs : 30; 60 | 61 | // uint32_t Reserved5 : 5; 62 | // uint32_t RRSOffs : 27; 63 | 64 | // uint32_t U3C : 1; 65 | // uint32_t CMC : 1; 66 | // uint32_t FSC : 1; 67 | // uint32_t CTC : 1; 68 | // uint32_t LEC : 1; 69 | // uint32_t CIC : 1; 70 | // uint32_t ETC : 1; 71 | // uint32_t TSC : 1; 72 | // uint32_t GSC : 1; 73 | // uint32_t VTC : 1; 74 | // uint32_t Reserved6 : 22; 75 | uint32_t DWORD[8]; 76 | } __attribute__((packed)) xHC_CapRegisters; 77 | 78 | typedef struct 79 | { 80 | // uint32_t RunStop : 1; 81 | // uint32_t HCReset : 1; 82 | // uint32_t IntEnable : 1; 83 | // uint32_t HSErrorEnable : 1; 84 | // uint32_t Reserved0 : 3; 85 | // uint32_t LHCReset : 1; 86 | // uint32_t CSS : 1; 87 | // uint32_t CRS : 1; 88 | // uint32_t EWE : 1; 89 | // uint32_t EU3Stop : 1; 90 | // uint32_t Reserved1 : 1; 91 | // uint32_t CMEnable : 1; 92 | // uint32_t ETEnable : 1; 93 | // uint32_t TSCEnable : 1; 94 | // uint32_t VTIOEnable : 1; 95 | // uint32_t Reserved2 : 15; 96 | uint32_t DWORD[1]; 97 | } USBCMD; 98 | 99 | typedef struct 100 | { 101 | // uint32_t HCHalted : 1; 102 | // uint32_t Reserved0 : 1; 103 | // uint32_t HSError : 1; 104 | // uint32_t EInt : 1; 105 | // uint32_t PCDetect : 1; 106 | // uint32_t Reserved1 : 3; 107 | // uint32_t SSStatus : 1; 108 | // uint32_t RSStatus : 1; 109 | // uint32_t SRError : 1; 110 | // uint32_t CNR : 1; 111 | // uint32_t HCE : 1; 112 | // uint32_t Reserved2 : 19; 113 | uint32_t DWORD[1]; 114 | } USBSTS; 115 | 116 | typedef struct 117 | { 118 | // uint32_t RouteString : 20; 119 | // uint32_t Speed : 4; 120 | // uint32_t Reserved0 : 1; 121 | // uint32_t MTT : 1; 122 | // uint32_t Hub : 1; 123 | // uint32_t ContextEntries : 5; 124 | 125 | // uint32_t MaxExitLatency : 16; 126 | // uint32_t RootHubPortNumber : 8; 127 | // uint32_t NumberOfPorts : 8; 128 | 129 | // uint32_t ParentHubSlotID : 8; 130 | // uint32_t ParentPortNumber : 8; 131 | // uint32_t TTThinkTime : 2; 132 | // uint32_t Reserved1 : 4; 133 | // uint32_t InterrupterTarget : 10; 134 | 135 | // uint32_t USBDeviceAddress : 8; 136 | // uint32_t Reserved2 : 19; 137 | // uint32_t SlotState : 5; 138 | 139 | // uint64_t Reserved3; 140 | // uint64_t Reserved4; 141 | uint32_t DWORD[8]; 142 | } __attribute__((packed)) SlotContext; 143 | 144 | typedef struct 145 | { 146 | // uint32_t EPState : 3; 147 | // uint32_t Reserved0 : 5; 148 | // uint32_t Mult : 2; 149 | // uint32_t MaxPStreams : 5; 150 | // uint32_t LSA : 1; 151 | // uint32_t Interval : 8; 152 | // uint32_t MaxESITPayloadHi : 8; 153 | 154 | // uint32_t Reserved1 : 1; 155 | // uint32_t ErrorCount : 2; 156 | // uint32_t EPType : 3; 157 | // uint32_t Reserved2 : 1; 158 | // uint32_t HID : 1; 159 | // uint32_t MaxBurstSize : 8; 160 | // uint32_t MaxPacketSize : 16; 161 | 162 | // uint64_t DCS : 1; 163 | // uint64_t Reserved3 : 3; 164 | // uint64_t TRDequeuePtr : 60; // Make sure to shift the actual pointer to the right by 4 165 | 166 | // uint32_t AverageTRBLength : 16; 167 | // uint32_t MaxESITPayloadLo : 16; 168 | 169 | // uint32_t Reserved4; 170 | // uint64_t Reserved5; 171 | 172 | uint32_t DWORD[8]; 173 | } __attribute__((packed)) EndpointContext; 174 | 175 | typedef struct 176 | { 177 | // uint64_t DataPtr; 178 | 179 | // uint32_t TRBTransferLength : 17; 180 | // uint32_t TDSize : 5; 181 | // uint32_t InterrupterTarget : 10; 182 | 183 | // uint32_t Cycle : 1; 184 | // uint32_t ENT : 1; 185 | // uint32_t ISP : 1; 186 | // uint32_t NoSnoop : 1; 187 | // uint32_t ChainBit : 1; 188 | // uint32_t IOC : 1; 189 | // uint32_t IDT : 1; 190 | // uint32_t Reserved0 : 2; 191 | // uint32_t BEI : 1; 192 | // uint32_t TRBType : 6; 193 | // uint32_t Reserved1 : 16; 194 | 195 | uint32_t DWORD[4]; 196 | } __attribute__((packed)) NormalTRB; 197 | 198 | typedef uint32_t CommandTRB[4]; 199 | 200 | typedef struct 201 | { 202 | // uint64_t Reserved0 : 6; 203 | // uint64_t RingSegmentBaseAddress : 58; 204 | 205 | // uint64_t RingSegmentSize : 16; 206 | // uint64_t Reserved1 : 48; 207 | 208 | uint32_t DWORD[4]; 209 | } __attribute__((packed)) ERSTEntry; // Event Ring Segment Table Entry 210 | 211 | typedef struct 212 | { 213 | // uint32_t IntPending : 1; 214 | // uint32_t IntEnable : 1; 215 | // uint32_t Reserved0 : 30; 216 | 217 | // uint32_t IntModInterval : 16; 218 | // uint32_t IntModCounter : 16; 219 | 220 | // uint32_t ERSTSize : 16; 221 | // uint32_t Reserved1 : 16; 222 | 223 | // uint32_t Reserved2; 224 | 225 | // uint64_t Reserved3 : 6; 226 | // uint64_t ERSTBaseAddress : 58; 227 | 228 | // uint64_t DequeueERSTSegmentIdx : 3; 229 | // uint64_t EventHandlerBusy : 1; 230 | // uint64_t EventRingDequeuePtr : 60; 231 | 232 | uint32_t DWORD[8]; 233 | } __attribute__((packed)) xHC_InterrupterRegisters; 234 | 235 | typedef struct 236 | { 237 | // uint32_t CCS : 1; 238 | // uint32_t PED : 1; 239 | // uint32_t Reserved0 : 1; 240 | // uint32_t OCA : 1; 241 | // uint32_t PortReset : 1; 242 | // uint32_t PLS : 4; 243 | // uint32_t PortPower : 1; 244 | // uint32_t PortSpeed : 4; 245 | // uint32_t PortIndicatorControl : 2; 246 | // uint32_t LWS : 1; 247 | // uint32_t CSC : 1; 248 | // uint32_t PEC : 1; 249 | // uint32_t WRC : 1; 250 | // uint32_t OCC : 1; 251 | // uint32_t PRC : 1; 252 | // uint32_t PLC : 1; 253 | // uint32_t CEC : 1; 254 | // uint32_t CAS : 1; 255 | // uint32_t WCE : 1; 256 | // uint32_t WDE : 1; 257 | // uint32_t WOE : 1; 258 | // uint32_t Reserved1 : 2; 259 | // uint32_t DeviceRemovable : 1; 260 | // uint32_t WPR : 1; 261 | 262 | // uint32_t U1Timeout : 8; 263 | // uint32_t U2Timeout : 8; 264 | // uint32_t FLA : 1; 265 | // uint32_t Reserved2: 15; 266 | 267 | // uint32_t L1S : 3; 268 | // uint32_t RWE : 1; 269 | // uint32_t BESL : 4; 270 | // uint32_t L1DeviceSlot : 8; 271 | // uint32_t HLE : 1; 272 | // uint32_t Reserved3 : 11; 273 | // uint32_t PortTestControl : 4; 274 | 275 | // uint32_t LinkErrorCount: 16; 276 | // uint32_t RLC : 4; 277 | // uint32_t TLC : 4; 278 | // uint32_t Reserved4 : 8; 279 | 280 | uint32_t DWORD[4]; 281 | } __attribute__((packed)) xHC_PortRegisters; 282 | 283 | typedef struct 284 | { 285 | SlotContext SlotCtx; 286 | EndpointContext EndpointCtx[31]; 287 | } __attribute__((packed)) DeviceContext; 288 | 289 | typedef struct 290 | { 291 | USBCMD UsbCmd; // 1 292 | USBSTS UsbSts; // 1 293 | uint32_t PageSize; // 1 294 | uint64_t Reserved0; // 2 295 | uint32_t DNControl; // 1 296 | uint64_t CRControl; // 2 297 | uint64_t Reserved1; // 2 298 | uint64_t Reserved2; // 2 299 | uint64_t DCBAAP; // 2 300 | uint32_t Config; // 1 301 | uint32_t Reserved3[241]; 302 | xHC_PortRegisters PortRegs[256]; 303 | } xHC_OpRegisters; 304 | 305 | typedef struct 306 | { 307 | xHC_PortRegisters* PortRegs; 308 | xHC_CapRegisters* CapRegs; 309 | xHC_OpRegisters* OpRegs; 310 | uint64_t RunRegsBase; 311 | xHC_InterrupterRegisters* IntRegs; 312 | 313 | uint32_t MaxSlots; 314 | 315 | DeviceContext** DCBAA; 316 | CommandTRB* CommandRing; 317 | ERSTEntry* ERST[256]; 318 | } xHC; 319 | 320 | void XHCIInit() 321 | { 322 | } -------------------------------------------------------------------------------- /kernel/64/drivers/usb/xhci.h: -------------------------------------------------------------------------------- 1 | #ifndef XHCI_H 2 | #define XHCI_H 3 | 4 | #include "../../../include.h" 5 | 6 | void XHCIInit(); 7 | 8 | #endif // XHCI_H -------------------------------------------------------------------------------- /kernel/64/font.c: -------------------------------------------------------------------------------- 1 | #include 2 | const char SysFont[0x7F][8] = { 3 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0000 (nul) 4 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0001 5 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0002 6 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0003 7 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0004 8 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0005 9 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0006 10 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0007 11 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0008 12 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0009 13 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000A 14 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000B 15 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000C 16 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000D 17 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000E 18 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000F 19 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0010 20 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0011 21 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0012 22 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0013 23 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0014 24 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0015 25 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0016 26 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0017 27 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0018 28 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0019 29 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001A 30 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001B 31 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001C 32 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001D 33 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001E 34 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001F 35 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0020 (space) 36 | { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00 }, // U+0021 (!) 37 | { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0022 (") 38 | { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00 }, // U+0023 (#) 39 | { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00 }, // U+0024 ($) 40 | { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00 }, // U+0025 (%) 41 | { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00 }, // U+0026 (&) 42 | { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0027 (') 43 | { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00 }, // U+0028 (() 44 | { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00 }, // U+0029 ()) 45 | { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00 }, // U+002A (*) 46 | { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00 }, // U+002B (+) 47 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06 }, // U+002C (,) 48 | { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00 }, // U+002D (-) 49 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00 }, // U+002E (.) 50 | { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 }, // U+002F (/) 51 | { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00 }, // U+0030 (0) 52 | { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00 }, // U+0031 (1) 53 | { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00 }, // U+0032 (2) 54 | { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00 }, // U+0033 (3) 55 | { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00 }, // U+0034 (4) 56 | { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00 }, // U+0035 (5) 57 | { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00 }, // U+0036 (6) 58 | { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00 }, // U+0037 (7) 59 | { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00 }, // U+0038 (8) 60 | { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00 }, // U+0039 (9) 61 | { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00 }, // U+003A (:) 62 | { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06 }, // U+003B (;) 63 | { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00 }, // U+003C (<) 64 | { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00 }, // U+003D (=) 65 | { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00 }, // U+003E (>) 66 | { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00 }, // U+003F (?) 67 | { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00 }, // U+0040 (@) 68 | { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00 }, // U+0041 (A) 69 | { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00 }, // U+0042 (B) 70 | { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00 }, // U+0043 (C) 71 | { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00 }, // U+0044 (D) 72 | { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00 }, // U+0045 (E) 73 | { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00 }, // U+0046 (F) 74 | { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00 }, // U+0047 (G) 75 | { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00 }, // U+0048 (H) 76 | { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, // U+0049 (I) 77 | { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00 }, // U+004A (J) 78 | { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00 }, // U+004B (K) 79 | { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00 }, // U+004C (L) 80 | { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00 }, // U+004D (M) 81 | { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00 }, // U+004E (N) 82 | { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00 }, // U+004F (O) 83 | { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00 }, // U+0050 (P) 84 | { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00 }, // U+0051 (Q) 85 | { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00 }, // U+0052 (R) 86 | { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00 }, // U+0053 (S) 87 | { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, // U+0054 (T) 88 | { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00 }, // U+0055 (U) 89 | { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00 }, // U+0056 (V) 90 | { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00 }, // U+0057 (W) 91 | { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00 }, // U+0058 (X) 92 | { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00 }, // U+0059 (Y) 93 | { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00 }, // U+005A (Z) 94 | { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00 }, // U+005B ([) 95 | { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00 }, // U+005C (\) 96 | { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00 }, // U+005D (]) 97 | { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00 }, // U+005E (^) 98 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, // U+005F (_) 99 | { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0060 (`) 100 | { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00 }, // U+0061 (a) 101 | { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00 }, // U+0062 (b) 102 | { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00 }, // U+0063 (c) 103 | { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00 }, // U+0064 (d) 104 | { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00 }, // U+0065 (e) 105 | { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00 }, // U+0066 (f) 106 | { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F }, // U+0067 (g) 107 | { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00 }, // U+0068 (h) 108 | { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, // U+0069 (i) 109 | { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E }, // U+006A (j) 110 | { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00 }, // U+006B (k) 111 | { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, // U+006C (l) 112 | { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00 }, // U+006D (m) 113 | { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00 }, // U+006E (n) 114 | { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00 }, // U+006F (o) 115 | { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F }, // U+0070 (p) 116 | { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78 }, // U+0071 (q) 117 | { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00 }, // U+0072 (r) 118 | { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00 }, // U+0073 (s) 119 | { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00 }, // U+0074 (t) 120 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00 }, // U+0075 (u) 121 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00 }, // U+0076 (v) 122 | { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00 }, // U+0077 (w) 123 | { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00 }, // U+0078 (x) 124 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F }, // U+0079 (y) 125 | { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00 }, // U+007A (z) 126 | { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00 }, // U+007B ({) 127 | { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 }, // U+007C (|) 128 | { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00 }, // U+007D (}) 129 | { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+007E (~) 130 | }; -------------------------------------------------------------------------------- /kernel/64/font.h: -------------------------------------------------------------------------------- 1 | #ifndef FONT_H 2 | #define FONT_H 3 | #include 4 | 5 | extern const char SysFont[0x7F][8]; 6 | #endif -------------------------------------------------------------------------------- /kernel/64/idt.c: -------------------------------------------------------------------------------- 1 | #include "idt.h" 2 | #include "vmalloc.h" 3 | #include "apic.h" 4 | #include "syscall.h" 5 | #include "panic.h" 6 | 7 | #define PRESENT_BIT 47 8 | #define DPL_BIT 45 9 | #define RESERVED_1BIT 44 10 | 11 | #define GATE_TYPE_BIT 40 12 | #define RESERVED_5BIT 35 13 | #define IST_BIT 32 14 | 15 | #define OFFSET32_BIT 0 16 | #define OFFSET16_BIT 48 17 | #define SEGMENT_SEL_BIT 16 18 | #define OFFSET0_BIT 0 19 | 20 | typedef struct 21 | { 22 | uint16_t offset_1; // offset bits 0..15 23 | uint16_t selector; // a code segment selector in GDT or LDT 24 | uint8_t ist; // bits 0..2 holds Interrupt Stack Table offset, rest of bits zero. 25 | uint8_t type_attributes; // gate type, dpl, and p fields 26 | uint16_t offset_2; // offset bits 16..31 27 | uint32_t offset_3; // offset bits 32..63 28 | uint32_t zero; // reserved 29 | } __attribute__((packed)) IDTEntry; 30 | 31 | static IDTEntry* IDTEntries; 32 | 33 | /* Interrupt Handlers */ 34 | 35 | extern void PageFaultS(); 36 | extern void GeneralProtectionFaultS(); 37 | extern void UnknownFaultS(); 38 | extern void TSSFaultS(); 39 | extern void SyscallS(); 40 | extern void OSStartS(); 41 | 42 | extern void DriverIrqS_0(); 43 | extern void DriverIrqS_1(); 44 | extern void DriverIrqS_2(); 45 | extern void DriverIrqS_3(); 46 | extern void DriverIrqS_4(); 47 | extern void DriverIrqS_5(); 48 | extern void DriverIrqS_6(); 49 | extern void DriverIrqS_7(); 50 | extern void DriverIrqS_8(); 51 | extern void DriverIrqS_9(); 52 | 53 | extern void HandlerIRQ0(); 54 | extern void HandlerIRQ1(); 55 | extern void HandlerIRQ2(); 56 | extern void HandlerIRQ3(); 57 | extern void HandlerIRQ4(); 58 | extern void HandlerIRQ5(); 59 | extern void HandlerIRQ6(); 60 | extern void HandlerIRQ7(); 61 | extern void HandlerIRQ8(); 62 | extern void HandlerIRQ9(); 63 | extern void HandlerIRQ10(); 64 | extern void HandlerIRQ11(); 65 | extern void HandlerIRQ12(); 66 | extern void HandlerIRQ13(); 67 | extern void HandlerIRQ14(); 68 | extern void HandlerIRQ15(); 69 | extern void HandlerIVT70(); 70 | extern void HandlerIVT71(); 71 | extern void HandlerIVT72(); 72 | extern void HandlerSpurious(); 73 | 74 | void PageFault(void) 75 | { 76 | KernelPanic("PANIC: Page Fault!"); 77 | } 78 | 79 | void GeneralProtectionFault(void) 80 | { 81 | KernelPanic("PANIC: GP Fault!"); 82 | } 83 | 84 | void UnknownFault(void) 85 | { 86 | KernelPanic("PANIC: Unknown Fault!"); 87 | } 88 | 89 | void IDT_Init() 90 | { 91 | IDTEntries = 0xFFFFFFFFC1300000; 92 | static void (*Handlers[16])() = { 93 | HandlerIRQ0, HandlerIRQ1, HandlerIRQ2, HandlerIRQ3, 94 | HandlerIRQ4, HandlerIRQ5, HandlerIRQ6, HandlerIRQ7, 95 | HandlerIRQ8, HandlerIRQ9, HandlerIRQ10, HandlerIRQ11, 96 | HandlerIRQ12, HandlerIRQ13, HandlerIRQ14, HandlerIRQ15, 97 | }; 98 | static void (*DriverHandlers[10])() = { 99 | DriverIrqS_0, 100 | DriverIrqS_1, 101 | DriverIrqS_2, 102 | DriverIrqS_3, 103 | DriverIrqS_4, 104 | DriverIrqS_5, 105 | DriverIrqS_6, 106 | DriverIrqS_7, 107 | DriverIrqS_8, 108 | DriverIrqS_9 109 | }; 110 | for (int i = 0;i < 256;i++) 111 | { 112 | IDTEntries[i] = (IDTEntry){ 0, 0, 0, 0, 0, 0, 0 }; 113 | if (i == 0xA) // INVALID TSS FAULT 114 | { 115 | IDTEntries[i].type_attributes = 0x8F; 116 | IDTEntries[i].offset_3 = (((uint64_t)TSSFaultS & 0xFFFFFFFF00000000ULL) >> 32); 117 | IDTEntries[i].offset_2 = (((uint64_t)TSSFaultS & 0x00000000FFFF0000ULL) >> 16); 118 | IDTEntries[i].offset_1 = (((uint64_t)TSSFaultS & 0x000000000000FFFFULL) >> 0); 119 | IDTEntries[i].selector = 0x18; // 64-bit code segment is at 0x18 in the GDT 120 | } 121 | if (i == 0xE) // PAGE FAULT 122 | { 123 | IDTEntries[i].type_attributes = 0x8F; 124 | IDTEntries[i].offset_3 = (((uint64_t)PageFaultS & 0xFFFFFFFF00000000ULL) >> 32); 125 | IDTEntries[i].offset_2 = (((uint64_t)PageFaultS & 0x00000000FFFF0000ULL) >> 16); 126 | IDTEntries[i].offset_1 = (((uint64_t)PageFaultS & 0x000000000000FFFFULL) >> 0); 127 | IDTEntries[i].selector = 0x18; // 64-bit code segment is at 0x18 in the GDT 128 | } 129 | else if (i == 0xD) // GP FAULT 130 | { 131 | IDTEntries[i].type_attributes = 0x8F; 132 | IDTEntries[i].offset_3 = (((uint64_t)GeneralProtectionFaultS & 0xFFFFFFFF00000000ULL) >> 32); 133 | IDTEntries[i].offset_2 = (((uint64_t)GeneralProtectionFaultS & 0x00000000FFFF0000ULL) >> 16); 134 | IDTEntries[i].offset_1 = (((uint64_t)GeneralProtectionFaultS & 0x000000000000FFFFULL) >> 0); 135 | IDTEntries[i].selector = 0x18; // 64-bit code segment is at 0x18 in the GDT 136 | } 137 | else if (i < 32) 138 | { 139 | IDTEntries[i].type_attributes = 0x8F; 140 | IDTEntries[i].offset_3 = (((uint64_t)UnknownFaultS & 0xFFFFFFFF00000000ULL) >> 32); 141 | IDTEntries[i].offset_2 = (((uint64_t)UnknownFaultS & 0x00000000FFFF0000ULL) >> 16); 142 | IDTEntries[i].offset_1 = (((uint64_t)UnknownFaultS & 0x000000000000FFFFULL) >> 0); 143 | IDTEntries[i].selector = 0x18; // 64-bit code segment is at 0x18 in the GDT 144 | } 145 | else if (i < 48) 146 | { 147 | IDTEntries[i].type_attributes = 0x8E; 148 | IDTEntries[i].offset_3 = (((uint64_t)Handlers[i - 32] & 0xFFFFFFFF00000000ULL) >> 32); 149 | IDTEntries[i].offset_2 = (((uint64_t)Handlers[i - 32] & 0x00000000FFFF0000ULL) >> 16); 150 | IDTEntries[i].offset_1 = (((uint64_t)Handlers[i - 32] & 0x000000000000FFFFULL) >> 0); 151 | IDTEntries[i].selector = 0x18; // 64-bit code segment is at 0x18 in the GDT 152 | } 153 | else if (i >= 0x70 && i < 0x80) 154 | { 155 | IDTEntries[i].type_attributes = 0x8E; 156 | IDTEntries[i].offset_3 = 0xFFFFFFFF; 157 | IDTEntries[i].offset_2 = (((uint64_t)DriverHandlers[i - 0x70] & 0x00000000FFFF0000ULL) >> 16); 158 | IDTEntries[i].offset_1 = (((uint64_t)DriverHandlers[i - 0x70] & 0x000000000000FFFFULL) >> 0); 159 | IDTEntries[i].selector = 0x18; // 64-bit code segment is at 0x18 in the GDT 160 | } 161 | else if (i == 0x80) 162 | { 163 | IDTEntries[i].type_attributes = 0x8E | 0b01100000; // DPL is 3 164 | IDTEntries[i].offset_3 = 0xFFFFFFFF; 165 | IDTEntries[i].offset_2 = (((uint64_t)SyscallS & 0x00000000FFFF0000ULL) >> 16); 166 | IDTEntries[i].offset_1 = (((uint64_t)SyscallS & 0x000000000000FFFFULL) >> 0); 167 | IDTEntries[i].selector = 0x18; // 64-bit code segment is at 0x18 in the GDT 168 | } 169 | else if (i == 0xFF) 170 | { 171 | IDTEntries[i].type_attributes = 0x8E | 0b01100000; // DPL is 3 172 | IDTEntries[i].offset_3 = 0xFFFFFFFF; 173 | IDTEntries[i].offset_2 = (((uint64_t)HandlerSpurious & 0x00000000FFFF0000ULL) >> 16); 174 | IDTEntries[i].offset_1 = (((uint64_t)HandlerSpurious & 0x000000000000FFFFULL) >> 0); 175 | IDTEntries[i].selector = 0x18; // 64-bit code segment is at 0x18 in the GDT 176 | } 177 | } 178 | *(uint16_t*)0x7E50 = sizeof(IDTEntry) * 256 - 1; 179 | *(uint64_t*)0x7E52 = (uint64_t)IDTEntries; 180 | } -------------------------------------------------------------------------------- /kernel/64/idt.h: -------------------------------------------------------------------------------- 1 | #ifndef IDT_H 2 | #define IDT_H 3 | 4 | #include "../include.h" 5 | 6 | void IDT_Init(); 7 | extern void LoadIDT(); 8 | 9 | #endif // IDT_H -------------------------------------------------------------------------------- /kernel/64/idt.s: -------------------------------------------------------------------------------- 1 | [BITS 64] 2 | 3 | extern PageFault 4 | extern GeneralProtectionFault 5 | extern UnknownFault 6 | extern Syscall 7 | 8 | section .handlers 9 | 10 | global LoadIDT 11 | global SyscallS 12 | global OSStartS 13 | global PageFaultS 14 | global GeneralProtectionFaultS 15 | global TSSFaultS 16 | global UnknownFaultS 17 | global DriverIrqTable 18 | 19 | global HandlerIRQ0 20 | global HandlerIRQ1 21 | global HandlerIRQ2 22 | global HandlerIRQ3 23 | global HandlerIRQ4 24 | global HandlerIRQ5 25 | global HandlerIRQ6 26 | global HandlerIRQ7 27 | global HandlerIRQ8 28 | global HandlerIRQ9 29 | global HandlerIRQ10 30 | global HandlerIRQ11 31 | global HandlerIRQ12 32 | global HandlerIRQ13 33 | global HandlerIRQ14 34 | global HandlerIRQ15 35 | global HandlerSpurious 36 | 37 | extern CHandlerIRQ0 38 | extern CHandlerIRQ1 39 | extern CHandlerIRQ2 40 | extern CHandlerIRQ3 41 | extern CHandlerIRQ4 42 | extern CHandlerIRQ5 43 | extern CHandlerIRQ6 44 | extern CHandlerIRQ7 45 | extern CHandlerIRQ8 46 | extern CHandlerIRQ9 47 | extern CHandlerIRQ10 48 | extern CHandlerIRQ11 49 | extern CHandlerIRQ12 50 | extern CHandlerIRQ13 51 | extern CHandlerIRQ14 52 | extern CHandlerIRQ15 53 | extern CHandlerIVT70 54 | extern CHandlerIVT71 55 | extern CHandlerIVT72 56 | 57 | %macro PUSHA64 0 58 | 59 | push rax 60 | mov ax, ds 61 | push rax 62 | 63 | mov ax, 0x10 64 | mov es, ax 65 | mov ds, ax 66 | mov fs, ax 67 | mov gs, ax 68 | mov ss, ax 69 | 70 | push rbx 71 | push rcx 72 | push rdx 73 | push rdi 74 | push rsi 75 | push r10 76 | push r11 77 | 78 | %endmacro 79 | 80 | %macro POPA64 0 81 | pop r11 82 | pop r10 83 | pop rsi 84 | pop rdi 85 | pop rdx 86 | pop rcx 87 | pop rbx 88 | pop rax 89 | mov es, ax 90 | mov ds, ax 91 | mov fs, ax 92 | mov gs, ax 93 | pop rax 94 | %endmacro 95 | 96 | %macro POPA64NOSWITCH 0 97 | pop r11 98 | pop r10 99 | pop rsi 100 | pop rdi 101 | pop rdx 102 | pop rcx 103 | pop rbx 104 | pop rax 105 | pop rax 106 | %endmacro 107 | 108 | %macro RESTORESTATE 0 109 | add rsp, 36 110 | 111 | ; Restore state 112 | push qword [rdi + 136 + 16 * 16 + 8] 113 | push qword [rdi + 48] 114 | push qword [rdi + 56] 115 | push qword [rdi + 136 + 16 * 16] 116 | push qword [rdi + 64] 117 | 118 | mov rbx, [rdi + 8] 119 | mov rcx, [rdi + 16] 120 | mov rdx, [rdi + 24] 121 | mov rsi, [rdi + 40] 122 | mov rbp, [rdi + 72] 123 | mov r9, [rdi + 80] 124 | mov r10, [rdi + 88] 125 | mov r11, [rdi + 96] 126 | mov r12, [rdi + 104] 127 | mov r13, [rdi + 112] 128 | mov r14, [rdi + 120] 129 | mov r15, [rdi + 128] 130 | movdqu xmm0, [rdi + 136] 131 | movdqu xmm1, [rdi + 136 + 16 * 1] 132 | movdqu xmm2, [rdi + 136 + 16 * 2] 133 | movdqu xmm3, [rdi + 136 + 16 * 3] 134 | movdqu xmm4, [rdi + 136 + 16 * 4] 135 | movdqu xmm5, [rdi + 136 + 16 * 5] 136 | movdqu xmm6, [rdi + 136 + 16 * 6] 137 | movdqu xmm7, [rdi + 136 + 16 * 7] 138 | movdqu xmm8, [rdi + 136 + 16 * 8] 139 | movdqu xmm9, [rdi + 136 + 16 * 9] 140 | movdqu xmm10, [rdi + 136 + 16 * 10] 141 | movdqu xmm11, [rdi + 136 + 16 * 11] 142 | movdqu xmm12, [rdi + 136 + 16 * 12] 143 | movdqu xmm13, [rdi + 136 + 16 * 13] 144 | movdqu xmm14, [rdi + 136 + 16 * 14] 145 | movdqu xmm15, [rdi + 136 + 16 * 15] 146 | 147 | mov rax, [rdi + 136 + 16 * 16 + 8] 148 | mov es, ax 149 | mov ds, ax 150 | mov fs, ax 151 | mov gs, ax 152 | 153 | mov rax, [rdi] 154 | mov rdi, [rdi + 32] ; I didn't forget you! 155 | %endmacro 156 | 157 | global DriverIrqTable 158 | DriverIrqTable: 159 | times 10 dq 0x77 160 | 161 | %macro DriverIrqS 1 162 | global DriverIrqS_%1 163 | DriverIrqS_%1: 164 | cld 165 | PUSHA64 166 | mov rax, [DriverIrqTable + 8 * %1] 167 | call rax 168 | POPA64 169 | iretq 170 | %endmacro 171 | 172 | align 16 173 | 174 | PageFaultS: 175 | pop r12 176 | cld 177 | PUSHA64 178 | call PageFault 179 | POPA64 180 | iretq 181 | 182 | GeneralProtectionFaultS: 183 | PUSHA64 184 | call GeneralProtectionFault 185 | POPA64 186 | add rsp, 8 187 | iretq 188 | 189 | UnknownFaultS: 190 | pop r12 191 | PUSHA64 192 | call UnknownFault 193 | POPA64 194 | iretq 195 | 196 | TSSFaultS: 197 | PUSHA64 198 | mov word [0xFFFFFFFF90000000], 0x0F00 | 'T' 199 | hlt 200 | POPA64 201 | iretq 202 | 203 | SyscallS: 204 | 205 | push rax 206 | mov ax, 0x10 207 | mov es, ax 208 | mov ds, ax 209 | mov fs, ax 210 | mov gs, ax 211 | mov ss, ax 212 | pop rax 213 | 214 | mov [.tss], rax 215 | mov [.tss + 8], rbx 216 | mov [.tss + 16], rcx 217 | mov [.tss + 24], rdx 218 | mov [.tss + 32], rdi 219 | mov [.tss + 40], rsi 220 | mov rax, [rsp + 24] 221 | mov [.tss + 48], rax 222 | mov rax, [rsp + 16] 223 | mov [.tss + 56], rax 224 | mov rax, [rsp] 225 | mov [.tss + 64], rax 226 | mov rax, [rsp + 32] 227 | cmp rax, 0 228 | jg .done_seg 229 | mov rax, 0x10 230 | .done_seg: 231 | mov [.tss + 136 + 16 * 16 + 8], rax 232 | mov rax, [rsp + 8] 233 | mov [.tss + 136 + 16 * 16 + 0], rax 234 | mov [.tss + 72], rbp 235 | mov [.tss + 80], r9 236 | mov [.tss + 88], r10 237 | mov [.tss + 96], r11 238 | mov [.tss + 104], r12 239 | mov [.tss + 112], r13 240 | mov [.tss + 120], r14 241 | mov [.tss + 128], r15 242 | movdqu [.tss + 136], xmm0 243 | movdqu [.tss + 136 + 16 * 1], xmm1 244 | movdqu [.tss + 136 + 16 * 2], xmm2 245 | movdqu [.tss + 136 + 16 * 3], xmm3 246 | movdqu [.tss + 136 + 16 * 4], xmm4 247 | movdqu [.tss + 136 + 16 * 5], xmm5 248 | movdqu [.tss + 136 + 16 * 6], xmm6 249 | movdqu [.tss + 136 + 16 * 7], xmm7 250 | movdqu [.tss + 136 + 16 * 8], xmm8 251 | movdqu [.tss + 136 + 16 * 9], xmm9 252 | movdqu [.tss + 136 + 16 * 10], xmm10 253 | movdqu [.tss + 136 + 16 * 11], xmm11 254 | movdqu [.tss + 136 + 16 * 12], xmm12 255 | movdqu [.tss + 136 + 16 * 13], xmm13 256 | movdqu [.tss + 136 + 16 * 14], xmm14 257 | movdqu [.tss + 136 + 16 * 15], xmm15 258 | 259 | PUSHA64 260 | mov rdi, rbx 261 | mov rdx, rcx 262 | mov rcx, .tss 263 | 264 | call Syscall 265 | cmp rax, 0 266 | je .dont_switch 267 | mov rdi, rax 268 | 269 | RESTORESTATE 270 | iretq 271 | 272 | .dont_switch: 273 | POPA64 274 | .done: 275 | iretq 276 | .tss: 277 | times 0x400 / 8 dq 0 278 | 279 | ; rdx is the OSes stack pointer 280 | ; rcx is the OSes entrypoint 281 | OSStartS: 282 | ; TO BE REMOVED, BETTER SOLUTION FOUND 283 | 284 | HandlerIRQ0: 285 | push rax 286 | mov ax, 0x10 287 | mov es, ax 288 | mov ds, ax 289 | mov fs, ax 290 | mov gs, ax 291 | mov ss, ax 292 | pop rax 293 | 294 | ; Save state 295 | mov [.tss], rax 296 | mov [.tss + 8], rbx 297 | mov [.tss + 16], rcx 298 | mov [.tss + 24], rdx 299 | mov [.tss + 32], rdi 300 | mov [.tss + 40], rsi 301 | mov rax, [rsp + 24] 302 | mov [.tss + 48], rax 303 | mov rax, [rsp + 16] 304 | mov [.tss + 56], rax 305 | mov rax, [rsp] 306 | mov [.tss + 64], rax 307 | mov rax, [rsp + 32] 308 | cmp rax, 0 309 | jg .done_seg 310 | mov rax, 0x10 311 | .done_seg: 312 | mov [.tss + 136 + 16 * 16 + 8], rax 313 | mov rax, [rsp + 8] 314 | mov [.tss + 136 + 16 * 16 + 0], rax 315 | mov [.tss + 72], rbp 316 | mov [.tss + 80], r9 317 | mov [.tss + 88], r10 318 | mov [.tss + 96], r11 319 | mov [.tss + 104], r12 320 | mov [.tss + 112], r13 321 | mov [.tss + 120], r14 322 | mov [.tss + 128], r15 323 | movdqu [.tss + 136], xmm0 324 | movdqu [.tss + 136 + 16 * 1], xmm1 325 | movdqu [.tss + 136 + 16 * 2], xmm2 326 | movdqu [.tss + 136 + 16 * 3], xmm3 327 | movdqu [.tss + 136 + 16 * 4], xmm4 328 | movdqu [.tss + 136 + 16 * 5], xmm5 329 | movdqu [.tss + 136 + 16 * 6], xmm6 330 | movdqu [.tss + 136 + 16 * 7], xmm7 331 | movdqu [.tss + 136 + 16 * 8], xmm8 332 | movdqu [.tss + 136 + 16 * 9], xmm9 333 | movdqu [.tss + 136 + 16 * 10], xmm10 334 | movdqu [.tss + 136 + 16 * 11], xmm11 335 | movdqu [.tss + 136 + 16 * 12], xmm12 336 | movdqu [.tss + 136 + 16 * 13], xmm13 337 | movdqu [.tss + 136 + 16 * 14], xmm14 338 | movdqu [.tss + 136 + 16 * 15], xmm15 339 | 340 | cld 341 | mov rdi, .tss 342 | call CHandlerIRQ0 343 | mov rdi, rax 344 | 345 | RESTORESTATE 346 | iretq 347 | .tss: 348 | times 0x400 / 8 dq 0 349 | HandlerIRQ1: 350 | cld 351 | PUSHA64 352 | call CHandlerIRQ1 353 | POPA64 354 | iretq 355 | 356 | HandlerIRQ2: 357 | cld 358 | PUSHA64 359 | call CHandlerIRQ2 360 | POPA64 361 | iretq 362 | 363 | HandlerIRQ3: 364 | cld 365 | PUSHA64 366 | call CHandlerIRQ3 367 | POPA64 368 | iretq 369 | 370 | HandlerIRQ4: 371 | cld 372 | PUSHA64 373 | call CHandlerIRQ4 374 | POPA64 375 | iretq 376 | 377 | HandlerIRQ5: 378 | cld 379 | PUSHA64 380 | call CHandlerIRQ5 381 | POPA64 382 | iretq 383 | 384 | HandlerIRQ6: 385 | cld 386 | PUSHA64 387 | call CHandlerIRQ6 388 | POPA64 389 | iretq 390 | 391 | HandlerIRQ7: 392 | cld 393 | PUSHA64 394 | call CHandlerIRQ7 395 | POPA64 396 | iretq 397 | 398 | HandlerIRQ8: 399 | cld 400 | PUSHA64 401 | call CHandlerIRQ8 402 | POPA64 403 | iretq 404 | 405 | HandlerIRQ9: 406 | cld 407 | PUSHA64 408 | call CHandlerIRQ9 409 | POPA64 410 | iretq 411 | 412 | HandlerIRQ10: 413 | cld 414 | PUSHA64 415 | call CHandlerIRQ10 416 | POPA64 417 | iretq 418 | 419 | HandlerIRQ11: 420 | cld 421 | PUSHA64 422 | call CHandlerIRQ11 423 | POPA64 424 | iretq 425 | 426 | HandlerIRQ12: 427 | cld 428 | PUSHA64 429 | call CHandlerIRQ12 430 | POPA64 431 | iretq 432 | 433 | HandlerIRQ13: 434 | cld 435 | PUSHA64 436 | call CHandlerIRQ13 437 | POPA64 438 | iretq 439 | 440 | HandlerIRQ14: 441 | cld 442 | PUSHA64 443 | call CHandlerIRQ14 444 | POPA64 445 | iretq 446 | 447 | HandlerIRQ15: 448 | cld 449 | PUSHA64 450 | call CHandlerIRQ15 451 | POPA64 452 | iretq 453 | 454 | DriverIrqS 0 455 | DriverIrqS 1 456 | DriverIrqS 2 457 | DriverIrqS 3 458 | DriverIrqS 4 459 | DriverIrqS 5 460 | DriverIrqS 6 461 | DriverIrqS 7 462 | DriverIrqS 8 463 | DriverIrqS 9 464 | 465 | HandlerSpurious: 466 | iretq 467 | 468 | LoadIDT: 469 | lidt [0x7E50] 470 | sti 471 | ret -------------------------------------------------------------------------------- /kernel/64/io.c: -------------------------------------------------------------------------------- 1 | #include "io.h" 2 | 3 | uint8_t IO_In8 (uint16_t Port) 4 | { 5 | uint8_t Result = 0; 6 | asm volatile ("inb %1, %0" : "=a" (Result) : "Nd" (Port)); 7 | return Result; 8 | } 9 | uint16_t IO_In16(uint16_t Port) 10 | { 11 | uint16_t Result = 0; 12 | asm volatile ("inw %1, %0" : "=a" (Result) : "Nd" (Port)); 13 | return Result; 14 | } 15 | uint32_t IO_In32(uint16_t Port) 16 | { 17 | uint32_t Result = 0; 18 | asm volatile ("inl %1, %0" : "=a" (Result) : "Nd" (Port)); 19 | return Result; 20 | } 21 | 22 | void IO_Out8 (uint16_t Port, uint8_t Value) 23 | { 24 | asm volatile ("outb %0, %1" :: "a" (Value), "Nd" (Port)); 25 | } 26 | void IO_Out16(uint16_t Port, uint16_t Value) 27 | { 28 | asm volatile ("outw %0, %1" :: "a" (Value), "Nd" (Port)); 29 | } 30 | void IO_Out32(uint16_t Port, uint32_t Value) 31 | { 32 | asm volatile ("outl %0, %1" :: "a" (Value), "Nd" (Port)); 33 | } 34 | 35 | void IO_Wait() 36 | { 37 | /* Output into an unused port */ 38 | IO_Out8(0x80, 0); 39 | } -------------------------------------------------------------------------------- /kernel/64/io.h: -------------------------------------------------------------------------------- 1 | #ifndef IO_H 2 | #define IO_H 3 | 4 | #include 5 | 6 | uint8_t IO_In8 (uint16_t Port); 7 | uint16_t IO_In16(uint16_t Port); 8 | uint32_t IO_In32(uint16_t Port); 9 | 10 | void IO_Out8 (uint16_t Port, uint8_t Value); 11 | void IO_Out16(uint16_t Port, uint16_t Value); 12 | void IO_Out32(uint16_t Port, uint32_t Value); 13 | 14 | void IO_Wait(); 15 | 16 | #endif // IO_H -------------------------------------------------------------------------------- /kernel/64/iomem.h: -------------------------------------------------------------------------------- 1 | #ifndef IOMEM_H 2 | #define IOMEM_H 3 | #include 4 | 5 | #define IOMEM_READ_VALUE(dest, src) \ 6 | Iomem_ReadAligned32String((dest), (src), sizeof(*(dest))) 7 | 8 | #define IOMEM_WRITE_VALUE(dest, src) \ 9 | Iomem_WriteAligned32String((dest), (src), sizeof(*(dest))) 10 | 11 | static inline uint8_t Iomem_ReadAligned32(void *base) { 12 | size_t addr = (size_t)base; 13 | size_t offset = addr & 0b11; 14 | 15 | return ((*(uint32_t *)(addr & (~0b11))) >> (offset * 8)) & 0xFF; 16 | } 17 | 18 | static inline void Iomem_WriteAligned32(void *base, uint8_t value) { 19 | size_t addr = (size_t)base; 20 | size_t offset = addr & 0b11; 21 | 22 | uint32_t existing = *(uint32_t *)(addr & (~0b11)); 23 | ((uint8_t *)&existing)[offset] = value; 24 | *(uint32_t *)(addr & (~0b11)) = existing; 25 | } 26 | 27 | static inline uint8_t Iomem_ReadAligned32String(void *out, void *in, 28 | size_t size) { 29 | for (size_t i = 0; i < size; i++) { 30 | ((uint8_t *)out)[i] = Iomem_ReadAligned32((uint8_t *)in + i); 31 | } 32 | } 33 | 34 | static inline void Iomem_WriteAligned32String(void *out, void *in, 35 | size_t size) { 36 | for (size_t i = 0; i < size; i++) { 37 | Iomem_WriteAligned32((uint8_t *)out + i, ((uint8_t *)in)[i]); 38 | } 39 | } 40 | 41 | #endif -------------------------------------------------------------------------------- /kernel/64/irqhandlers.c: -------------------------------------------------------------------------------- 1 | #include "pic.h" 2 | #include "apic.h" 3 | #include "io.h" 4 | #include "../vbe.h" 5 | #include "softtss.h" 6 | #include "scheduler.h" 7 | #include "drivers/driverman.h" 8 | #include 9 | 10 | 11 | int SuspendPIT; 12 | 13 | float MSTicks = 0; // IN MS 14 | SoftTSS* CHandlerIRQ0(SoftTSS* SaveState) 15 | { 16 | MSTicks += 1000.0f / (1193182.0f) * 16000.0f; 17 | 18 | SoftTSS* NextState = Scheduler_NextProcess(SaveState); 19 | 20 | //DriverMan_Run(); 21 | 22 | ApicEOI(); 23 | 24 | return NextState; 25 | } 26 | 27 | #define KEY_QUEUE_SIZE 128 28 | char KeyQueue[KEY_QUEUE_SIZE]; 29 | size_t KeyQueueIdx = 0; 30 | 31 | /* Keyboard Interrupt */ 32 | void CHandlerIRQ1() 33 | { 34 | while (IO_In8(0x64) & 1) 35 | { 36 | char Scancode = IO_In8(0x60); 37 | for (int i = KEY_QUEUE_SIZE - 1; i > 0;i--) 38 | { 39 | KeyQueue[i] = KeyQueue[i - 1]; 40 | } 41 | KeyQueue[0] = Scancode; 42 | KeyQueueIdx++; 43 | if (KeyQueueIdx > KEY_QUEUE_SIZE) KeyQueueIdx = KEY_QUEUE_SIZE; 44 | } 45 | ApicEOI(); 46 | } 47 | /* Channel for Secondary PIC, don't use. */ 48 | void CHandlerIRQ2() 49 | { 50 | ApicEOI(); 51 | } 52 | /* COM2 */ 53 | void CHandlerIRQ3() 54 | { 55 | ApicEOI(); 56 | } 57 | /* COM1 */ 58 | void CHandlerIRQ4() 59 | { 60 | ApicEOI(); 61 | } 62 | /* LPT2 */ 63 | void CHandlerIRQ5() 64 | { 65 | ApicEOI(); 66 | } 67 | /* Floppy Disk */ 68 | void CHandlerIRQ6() 69 | { 70 | ApicEOI(); 71 | } 72 | /* LPT1 (spurious) */ 73 | void CHandlerIRQ7() 74 | { 75 | ApicEOI(); 76 | } 77 | /* CMOS Real time clock */ 78 | void CHandlerIRQ8() 79 | { 80 | ApicEOI(); 81 | } 82 | /* Free for peripherals */ 83 | void CHandlerIRQ9() 84 | { 85 | ApicEOI(); 86 | } 87 | /* Free for peripherals */ 88 | void CHandlerIRQ10() 89 | { 90 | ApicEOI(); 91 | } 92 | /* Free for peripherals */ 93 | void CHandlerIRQ11() 94 | { 95 | ApicEOI(); 96 | } 97 | /* PS/2 Mouse */ 98 | void CHandlerIRQ12() 99 | { 100 | while (IO_In8(0x64) & 1) 101 | { 102 | IO_In8(0x60); 103 | IO_In8(0x60); 104 | IO_In8(0x60); 105 | 106 | } 107 | ApicEOI(); 108 | } 109 | /* FPU */ 110 | void CHandlerIRQ13() 111 | { 112 | ApicEOI(); 113 | } 114 | /* Primary ATA */ 115 | void CHandlerIRQ14() 116 | { 117 | ApicEOI(); 118 | } 119 | /* Secondary ATA */ 120 | void CHandlerIRQ15() 121 | { 122 | ApicEOI(); 123 | } -------------------------------------------------------------------------------- /kernel/64/main.c: -------------------------------------------------------------------------------- 1 | #include "../include.h" 2 | #include "vmalloc.h" 3 | #include "idt.h" 4 | #include "pic.h" 5 | #include "apic.h" 6 | #include "acpi.h" 7 | #include "softtss.h" 8 | #include "draw.h" 9 | #include "scheduler.h" 10 | #include "panic.h" 11 | #include "../vbe.h" 12 | #include "pci.h" 13 | 14 | #include "drivers/driverman.h" 15 | 16 | #define FRAMEBUFFER_VM 0xFFFFFFFF90000000 17 | 18 | extern int SuspendPIT; 19 | extern float MSTicks; 20 | 21 | volatile uint64_t __attribute__((section(".main64"))) main64() 22 | { 23 | for (uint64_t i = 0;i < 0x800000;i += 1) 24 | { 25 | *(uint8_t*)(0xFFFFFFFFC1200000 + i) = 0; 26 | } 27 | 28 | AllocInit(); 29 | 30 | Scheduler_Init(); 31 | 32 | VesaVbeModeInfo* VbeModeInfo = VBE_INFO_LOC; 33 | 34 | if (!AllocMap(FRAMEBUFFER_VM, VbeModeInfo->Framebuffer, (VbeModeInfo->Bpp / 8) * VbeModeInfo->Width * VbeModeInfo->Height, (1 << MALLOC_READWRITE_BIT) | (1 << MALLOC_WRITE_THROUGH_BIT))) 35 | { 36 | KernelPanic("PANIC: Failed to map framebuffer to virtual memory!"); 37 | } 38 | 39 | AllocIdMap(0xB00000, 0x100000, (1ULL << MALLOC_READWRITE_BIT) | (1ULL << MALLOC_USER_SUPERVISOR_BIT)); 40 | Draw_Init(FRAMEBUFFER_VM); 41 | 42 | 43 | ACPIInit(); 44 | PicInit(); 45 | PicSetMask(0xFFFF); 46 | SuspendPIT = 1; 47 | IDT_Init(); 48 | LoadIDT(); 49 | ApicInit(); 50 | 51 | DriverMan_Init(); 52 | 53 | DriverMan_StorageDevice** StorageDevices; 54 | size_t StorageDevicesCount; 55 | DriverMan_GetStorageDevices(&StorageDevices, &StorageDevicesCount); 56 | DriverMan_FilesysTryFormat(StorageDevices[0], "CustomFS"); 57 | 58 | if (AllocVMAtStack(0xC00000, 0x100000) == 0) KernelPanic("PANIC: Failed to allocate OS stack!"); 59 | 60 | SuspendPIT = 0; 61 | MSTicks = 0; 62 | return 0xB00000; 63 | } -------------------------------------------------------------------------------- /kernel/64/memtools.c: -------------------------------------------------------------------------------- 1 | #include "memtools.h" 2 | 3 | void memcpy(void* _Dst, void* _Src, size_t _Bytes) 4 | { 5 | for (size_t i = 0;i < _Bytes;i++) 6 | { 7 | ((char*)_Dst)[i] = ((char*)_Src)[i]; 8 | } 9 | } 10 | 11 | void memset(void* _Dst, char _Val, size_t _Bytes) 12 | { 13 | for (size_t i = 0;i < _Bytes;i++) 14 | { 15 | ((char*)_Dst)[i] = _Val; 16 | } 17 | } -------------------------------------------------------------------------------- /kernel/64/memtools.h: -------------------------------------------------------------------------------- 1 | #ifndef MEMTOOLS_H 2 | #define MEMTOOLS_H 3 | 4 | #include "../include.h" 5 | 6 | void memcpy(void* _Dst, void* _Src, size_t _Bytes); 7 | void memset(void* _Dst, char _Val, size_t _Bytes); 8 | 9 | #endif // MEMTOOLS_H -------------------------------------------------------------------------------- /kernel/64/msr.c: -------------------------------------------------------------------------------- 1 | #include "msr.h" 2 | 3 | void GetMSR(uint32_t msr, uint32_t *lo, uint32_t *hi) 4 | { 5 | asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); 6 | } 7 | 8 | void SetMSR(uint32_t msr, uint32_t lo, uint32_t hi) 9 | { 10 | asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr)); 11 | } -------------------------------------------------------------------------------- /kernel/64/msr.h: -------------------------------------------------------------------------------- 1 | #ifndef MSR_H 2 | #define MSR_H 3 | 4 | #include "../include.h" 5 | 6 | void GetMSR(uint32_t msr, uint32_t *lo, uint32_t *hi); 7 | void SetMSR(uint32_t msr, uint32_t lo, uint32_t hi); 8 | 9 | #endif // MSR_H -------------------------------------------------------------------------------- /kernel/64/panic.c: -------------------------------------------------------------------------------- 1 | #include "panic.h" 2 | #include "../vbe.h" 3 | #include "draw.h" 4 | #include "io.h" 5 | #include 6 | 7 | static const char LowercaseHexListing[16] = { 8 | '0', '1', '2', '3', '4', '5', '6', '7', 9 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 10 | }; 11 | 12 | static const char UppercaseHexListing[16] = { 13 | '0', '1', '2', '3', '4', '5', '6', '7', 14 | '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 15 | }; 16 | 17 | /* 18 | * Returns true if base passed exceeded the base limit or is less than two 19 | * without trying to write into the string. 20 | * Otherwise prints the number `num` into `dest` using base `base`. 21 | * the function is guaranteed to write a finishing nul-terminator. 22 | */ 23 | static bool StrU(uint64_t Num, uint64_t Base, bool DoUpper, char *Dest) 24 | { 25 | if (Base < 2) { 26 | return true; 27 | } 28 | if (Base > sizeof(UppercaseHexListing)) { 29 | return true; 30 | } 31 | 32 | // Find the number of digits in the number 33 | uint64_t NumDigits = 0; 34 | { 35 | uint64_t x = Num; 36 | do { 37 | x /= Base; 38 | NumDigits += 1; 39 | } while (x != 0); 40 | } 41 | 42 | uint64_t Index = NumDigits; 43 | 44 | // Write the nul terminator 45 | Dest[Index] = 0; 46 | Index -= 1; 47 | 48 | // Write the remaining digits 49 | uint64_t x = Num; 50 | do { 51 | uint64_t Digit = x % Base; 52 | Dest[Index] = DoUpper 53 | ? UppercaseHexListing[Digit] 54 | : LowercaseHexListing[Digit]; 55 | x /= Base; 56 | Index -= 1; 57 | } while (x != 0); 58 | 59 | return false; 60 | } 61 | 62 | /* 63 | * Same as above, but can print negative numbers 64 | */ 65 | static bool StrI(int64_t Num, uint64_t Base, bool DoUpper, char *Dest) 66 | { 67 | if (Base < 2) { 68 | return true; 69 | } 70 | if (Base > sizeof(UppercaseHexListing)) { 71 | return true; 72 | } 73 | 74 | uint64_t AbsNum; 75 | if (Num >= 0) { 76 | AbsNum = (uint64_t)Num; 77 | } else { 78 | AbsNum = (uint64_t)(-Num); 79 | } 80 | 81 | // Find the number of digits in the number 82 | uint64_t NumDigits = 0; 83 | { 84 | uint64_t x = AbsNum; 85 | do { 86 | x /= Base; 87 | NumDigits += 1; 88 | } while (x != 0); 89 | } 90 | 91 | uint64_t Index = NumDigits; 92 | if (Num < 0) { 93 | Index += 1; 94 | } 95 | 96 | // Write the nul terminator 97 | Dest[Index] = 0; 98 | Index -= 1; 99 | 100 | // Write the remaining digits 101 | uint64_t x = AbsNum; 102 | do { 103 | uint64_t digit = x % Base; 104 | Dest[Index] = DoUpper 105 | ? UppercaseHexListing[digit] 106 | : LowercaseHexListing[digit]; 107 | x /= Base; 108 | Index -= 1; 109 | } while (x != 0); 110 | 111 | // Write the negative sign if needed 112 | if (Num < 0) { 113 | Dest[Index] = '-'; 114 | } 115 | 116 | return false; 117 | } 118 | 119 | static size_t ParseFmt(char *Dest, size_t WrittenThusFar, size_t *i, const char *Format, va_list Args) { 120 | *i += 1; 121 | // Temp buffer for numbers and misc 122 | char Temp[64] = { 0 }; 123 | size_t WrittenCount = 0; 124 | switch (Format[*i]) { 125 | case 's': { 126 | const char *Arg = va_arg(Args, const char*); 127 | size_t i = 0; 128 | for (; Arg[i]; i += 1) { 129 | Dest[WrittenThusFar + i] = Arg[i]; 130 | } 131 | WrittenCount += i; 132 | return WrittenCount; 133 | } 134 | break; 135 | case 'o': 136 | StrU((size_t)va_arg(Args, unsigned int), 8, false, Temp); 137 | break; 138 | case 'i': 139 | case 'd': 140 | StrI((int32_t)va_arg(Args, int), 10, false, Temp); 141 | break; 142 | case 'u': 143 | StrU((size_t)va_arg(Args, unsigned int), 10, false, Temp); 144 | break; 145 | case 'X': 146 | case 'x': 147 | StrU((size_t)va_arg(Args, unsigned int), 16, Format[*i] == 'X', Temp); 148 | break; 149 | case 'c': 150 | Temp[0] = (char)va_arg(Args, int); 151 | break; 152 | case 'n': 153 | *va_arg(Args, int*) = (int)(WrittenThusFar); 154 | break; 155 | case 'p': 156 | StrU((size_t)va_arg(Args, void*), 16, false, Temp); 157 | break; 158 | case '%': 159 | default: 160 | Temp[0] = '%'; 161 | break; 162 | } 163 | 164 | { 165 | size_t i = 0; 166 | for (; Temp[i]; i += 1) { 167 | Dest[WrittenThusFar + i] = Temp[i]; 168 | } 169 | WrittenCount += i; 170 | } 171 | return WrittenCount; 172 | } 173 | 174 | void FormatStringVaList(char *Out, const char *Format, va_list Args) 175 | { 176 | size_t WrittenCount = 0; 177 | for (size_t i = 0; Format[i]; i += 1) 178 | { 179 | if (Format[i] == '%') 180 | { 181 | WrittenCount += ParseFmt(Out, WrittenCount, &i, Format, Args); 182 | } 183 | else 184 | { 185 | Out[WrittenCount] = Format[i]; 186 | WrittenCount += 1; 187 | } 188 | } 189 | Out[WrittenCount] = 0; 190 | return WrittenCount; 191 | } 192 | 193 | void _KernelPanic(int Line, const char* File, const char* Message, ...) 194 | { 195 | va_list Args; 196 | va_start(Args, Message); 197 | char Buffer[4096]; 198 | FormatStringVaList(Buffer, Message, Args); 199 | va_end(Args); 200 | 201 | Draw_RectEntry Rect; 202 | Rect.x = 0; 203 | Rect.y = 0; 204 | Rect.w = Draw_GetResX(); 205 | Rect.x = Draw_GetResY(); 206 | Rect.col = 0; 207 | Draw_Rect(Rect); 208 | Draw_TextEntry Text; 209 | Text.col = 0xFFFFFFFF; 210 | Text.x = 10; 211 | Text.y = 10; 212 | Text.text = Buffer; 213 | Draw_Text(Text); 214 | Text.x = 10; 215 | Text.y = 20; 216 | Text.text = File; 217 | Draw_Text(Text); 218 | 219 | for (int i = 0;i < 0x10000;i++) IO_Wait(); 220 | 221 | asm volatile ("cli\nhlt"); 222 | } -------------------------------------------------------------------------------- /kernel/64/panic.h: -------------------------------------------------------------------------------- 1 | #ifndef PANIC_H 2 | #define PANIC_H 3 | 4 | #include "../include.h" 5 | 6 | #define KernelPanic(...) _KernelPanic(__LINE__, __FILE__, __VA_ARGS__) 7 | 8 | void _KernelPanic(int Line, const char* File, const char* Message, ...); 9 | 10 | #endif // PANIC_H -------------------------------------------------------------------------------- /kernel/64/pci.c: -------------------------------------------------------------------------------- 1 | #include "pci.h" 2 | #include "io.h" 3 | 4 | #define PCI_COMMAND_PORT 0xCF8 5 | #define PCI_DATA_PORT 0xCFC 6 | #define PCI_SPECIALTY(dev, cl, sub, sp) if (dev.Class == cl && dev.Subclass == sub) { return sp; } 7 | #define PCI_SPECIALTY_EXT(dev, cl, sub, progif, sp) if (dev.Class == cl && dev.Subclass == sub && dev.Interface == progif) { return sp; } 8 | 9 | uint32_t PCI_PathToObject(pci_device_path Path, uint8_t RegOffset) 10 | { 11 | return (uint32_t) 12 | 1 << 31 | // Enable bit 13 | ((Path.Bus & 0xFF) << 16 | // Bus number 14 | ((Path.Device & 0x1F) << 11) | // Device ID 15 | ((Path.Function) & 0x07) << 8) | // Device function 16 | (RegOffset & 0xFC) ; // Offset in the register 17 | } 18 | uint8_t PCI_Read8(pci_device_path Path, uint8_t RegOffset) 19 | { 20 | uint32_t Object = PCI_PathToObject(Path, RegOffset); 21 | 22 | IO_Out32(PCI_COMMAND_PORT, Object); 23 | 24 | /* Take the 2nd bit of RegOffset to know what word to read */ 25 | uint32_t Shift = ((RegOffset & 0b11) * 8); 26 | 27 | uint8_t _Byte = (IO_In32(PCI_DATA_PORT) >> Shift) & 0xFF; 28 | 29 | return _Byte; 30 | } 31 | uint16_t PCI_Read16(pci_device_path Path, uint8_t RegOffset) 32 | { 33 | uint32_t Object = PCI_PathToObject(Path, RegOffset); 34 | 35 | IO_Out32(PCI_COMMAND_PORT, Object); 36 | 37 | /* Take the 2nd bit of RegOffset to know what word to read */ 38 | uint32_t Shift = ((RegOffset & 2) * 8); 39 | 40 | uint16_t Word = (IO_In32(PCI_DATA_PORT) >> Shift) & 0xFFFF; 41 | 42 | return Word; 43 | } 44 | uint32_t PCI_Read32(pci_device_path Path, uint8_t RegOffset) 45 | { 46 | uint32_t Object = PCI_PathToObject(Path, RegOffset); 47 | 48 | IO_Out32(PCI_COMMAND_PORT, Object); 49 | 50 | return IO_In32(PCI_DATA_PORT); 51 | } 52 | void PCI_Write32(pci_device_path Path, uint8_t RegOffset, uint32_t Value32) 53 | { 54 | uint32_t Object = PCI_PathToObject(Path, RegOffset); 55 | 56 | IO_Out32(PCI_COMMAND_PORT, Object); 57 | 58 | IO_Out32(PCI_DATA_PORT, Value32); 59 | } 60 | void PCI_Write16(pci_device_path Path, uint8_t RegOffset, uint16_t Value16) 61 | { 62 | uint32_t Object = PCI_PathToObject(Path, RegOffset); 63 | 64 | IO_Out32(PCI_COMMAND_PORT, Object); 65 | 66 | uint32_t Cur = IO_In32(PCI_COMMAND_PORT); 67 | 68 | IO_Out32(PCI_COMMAND_PORT, Object); 69 | 70 | uint32_t Shift = ((RegOffset & 2) * 8); 71 | 72 | Cur &= ~(0xFFFFULL << Shift); 73 | 74 | IO_Out32(PCI_DATA_PORT, ((uint32_t)Value16 << Shift) | Cur); 75 | } 76 | void PCI_Write8(pci_device_path Path, uint8_t RegOffset, uint8_t Value8) 77 | { 78 | uint32_t Object = PCI_PathToObject(Path, RegOffset); 79 | 80 | IO_Out32(PCI_COMMAND_PORT, Object); 81 | 82 | uint32_t Cur = IO_In32(PCI_COMMAND_PORT); 83 | 84 | IO_Out32(PCI_COMMAND_PORT, Object); 85 | 86 | uint32_t Shift = ((RegOffset & 0b11) * 8); 87 | 88 | Cur &= ~(0xFFULL << Shift); 89 | 90 | IO_Out32(PCI_DATA_PORT, ((uint32_t)Value8 << Shift) | Cur); 91 | } 92 | pci_device_header PCI_QueryDeviceHeader(pci_device_path Path) 93 | { 94 | pci_device_header Result = { 0 }; 95 | 96 | Result.Path = Path; 97 | 98 | Result.VendorId = PCI_Read16(Path, 0); 99 | Result.DeviceId = PCI_Read16(Path, 2); 100 | Result.Command = PCI_Read16(Path, 4); 101 | Result.Status = PCI_Read16(Path, 6); 102 | 103 | uint16_t Interface_RevisionId_Word = PCI_Read16(Path, 8); 104 | Result.Interface = (Interface_RevisionId_Word >> 8) & 0xFF; 105 | Result.RevisionId = (Interface_RevisionId_Word) & 0xFF; 106 | 107 | uint16_t Class_Subclass_Word = PCI_Read16(Path, 10); 108 | Result.Class = (Class_Subclass_Word >> 8) & 0xFF; 109 | Result.Subclass = (Class_Subclass_Word) & 0xFF; 110 | 111 | uint16_t LatencyTimer_CacheLineSize_Word = PCI_Read16(Path, 12); 112 | Result.LatencyTimer = (LatencyTimer_CacheLineSize_Word >> 8) & 0xFF; 113 | Result.CacheLineSize= (LatencyTimer_CacheLineSize_Word) & 0xFF; 114 | 115 | uint16_t BIST_HeaderType_Word = PCI_Read16(Path, 14); 116 | Result.BIST = (BIST_HeaderType_Word >> 8) & 0xFF; 117 | Result.HeaderType = (BIST_HeaderType_Word) & 0x7F; 118 | 119 | Result.MultiFunction= ((BIST_HeaderType_Word) & 0x80) != 0; 120 | 121 | uint32_t BAR0_0 = PCI_Read16(Path, 0x10); 122 | uint32_t BAR0_1 = PCI_Read16(Path, 0x12); 123 | Result.BAR0 = (BAR0_1 << 16) | BAR0_0; 124 | 125 | uint32_t BAR1_0 = PCI_Read16(Path, 0x14); 126 | uint32_t BAR1_1 = PCI_Read16(Path, 0x16); 127 | Result.BAR1 = (BAR1_1 << 16) | BAR1_0; 128 | 129 | return Result; 130 | } 131 | pci_device_specialty PCI_QueryDeviceSpecialty(pci_device_header Header) 132 | { 133 | PCI_SPECIALTY(Header, 0x03, 0x00, PCI_DEVICE_VGA); 134 | PCI_SPECIALTY(Header, 0x02, 0x00, PCI_DEVICE_ETHERNET); 135 | PCI_SPECIALTY(Header, 0x01, 0x01, PCI_DEVICE_IDE); 136 | PCI_SPECIALTY(Header, 0x01, 0x01, PCI_DEVICE_IDE); 137 | PCI_SPECIALTY(Header, 0x06, 0x00, PCI_DEVICE_HOST_BRIDGE); 138 | PCI_SPECIALTY(Header, 0x06, 0x01, PCI_DEVICE_ISA_BRIDGE); 139 | PCI_SPECIALTY_EXT(Header, 0x01, 0x08, 0x2, PCI_DEVICE_NVME); 140 | PCI_SPECIALTY_EXT(Header, 0x0C, 0x03, 0x30, PCI_DEVICE_XHCI); 141 | 142 | return PCI_DEVICE_UNKNOWN; 143 | } -------------------------------------------------------------------------------- /kernel/64/pci.h: -------------------------------------------------------------------------------- 1 | #ifndef PCI_H 2 | #define PCI_H 3 | 4 | #include 5 | 6 | typedef struct { 7 | uint8_t Bus; // Which bus device is on 8 | uint8_t Device; // Which device 9 | uint8_t Function; // Which function of the device 10 | } pci_device_path; 11 | 12 | typedef enum { 13 | PCI_GENERAL_DEVICE, 14 | PCI_TO_PCI_BRIDGE, 15 | PCI_TO_CARDBUS_BRIDGE 16 | } pci_header_type; 17 | 18 | typedef enum { 19 | PCI_DEVICE_UNKNOWN, 20 | PCI_DEVICE_VGA, 21 | PCI_DEVICE_ETHERNET, 22 | PCI_DEVICE_IDE, 23 | PCI_DEVICE_EHCI, 24 | PCI_DEVICE_XHCI, 25 | PCI_DEVICE_HOST_BRIDGE, 26 | PCI_DEVICE_ISA_BRIDGE, 27 | PCI_DEVICE_NVME 28 | } pci_device_specialty; 29 | 30 | typedef struct { 31 | pci_device_path Path; 32 | uint16_t VendorId; 33 | uint16_t DeviceId; 34 | uint16_t Command; 35 | uint16_t Status; 36 | uint8_t RevisionId; 37 | uint8_t Interface; 38 | uint8_t Subclass; 39 | uint8_t Class; 40 | uint8_t CacheLineSize; 41 | uint8_t LatencyTimer; 42 | pci_header_type HeaderType; 43 | uint8_t BIST; 44 | uint32_t BAR0; 45 | uint32_t BAR1; 46 | uint8_t MultiFunction; 47 | } pci_device_header; 48 | 49 | typedef struct 50 | { 51 | uint32_t AddressLow; 52 | uint32_t AddressHigh; 53 | uint32_t Data; 54 | uint32_t Mask; 55 | } __attribute__((packed)) MSIX_VectorControl; 56 | 57 | uint32_t PCI_PathToObject(pci_device_path Path, uint8_t RegOffset); 58 | uint32_t PCI_Read32(pci_device_path Path, uint8_t RegOffset); 59 | uint16_t PCI_Read16(pci_device_path Path, uint8_t RegOffset); 60 | uint8_t PCI_Read8(pci_device_path Path, uint8_t RegOffset); 61 | void PCI_Write32(pci_device_path Path, uint8_t RegOffset, uint32_t Value32); 62 | void PCI_Write16(pci_device_path Path, uint8_t RegOffset, uint16_t Value16); 63 | void PCI_Write8(pci_device_path Path, uint8_t RegOffset, uint8_t Value8); 64 | pci_device_header PCI_QueryDeviceHeader(pci_device_path Path); 65 | pci_device_specialty PCI_QueryDeviceSpecialty(pci_device_header Header); 66 | 67 | #endif // PCI_H -------------------------------------------------------------------------------- /kernel/64/pic.c: -------------------------------------------------------------------------------- 1 | #include "pic.h" 2 | #include "io.h" 3 | 4 | #define PRIM_COMMAND 0x20 5 | #define PRIM_DATA 0x21 6 | #define SECN_COMMAND 0xA0 7 | #define SECN_DATA 0xA1 8 | 9 | #define WORD_INIT 0x10 10 | #define WORD_ENV 0x01 11 | #define WORD_M8086 0x01 12 | #define WORD_EOI 0x20 13 | 14 | #define PRIM_IDT 32 15 | #define SECN_IDT 32 + 8 16 | 17 | volatile void PicInit() 18 | { 19 | /* Save masks */ 20 | uint8_t Mask1, Mask2; 21 | Mask1 = IO_In8(PRIM_DATA); 22 | Mask2 = IO_In8(SECN_DATA); 23 | 24 | /* Start initialization */ 25 | IO_Out8(PRIM_COMMAND, WORD_INIT | WORD_ENV); 26 | IO_Wait(); 27 | IO_Out8(SECN_COMMAND, WORD_INIT | WORD_ENV); 28 | IO_Wait(); 29 | 30 | /* Assign IDT entries to the IRQ's */ 31 | IO_Out8(PRIM_DATA, PRIM_IDT); 32 | IO_Wait(); 33 | IO_Out8(SECN_DATA, SECN_IDT); 34 | IO_Wait(); 35 | 36 | /* Connect Secondary PIC to Primary PIC on line 2 */ 37 | IO_Out8(PRIM_DATA, 1 << 2); 38 | IO_Wait(); 39 | IO_Out8(SECN_DATA, 2); 40 | IO_Wait(); 41 | 42 | /* 8086 Mode */ 43 | IO_Out8(PRIM_DATA, WORD_M8086); 44 | IO_Wait(); 45 | IO_Out8(SECN_DATA, WORD_M8086); 46 | IO_Wait(); 47 | 48 | /* Restore masks */ 49 | IO_Out8(PRIM_DATA, Mask1); 50 | IO_Wait(); 51 | IO_Out8(SECN_DATA, Mask2); 52 | IO_Wait(); 53 | } 54 | volatile void PicSetMask(uint16_t Mask) 55 | { 56 | IO_Out8(PRIM_DATA, Mask & 0xFF); 57 | IO_Wait(); 58 | IO_Out8(SECN_DATA, (Mask >> 8) & 0xFF); 59 | IO_Wait(); 60 | } 61 | volatile uint16_t PicGetMask() 62 | { 63 | uint16_t Lo = IO_In8(PRIM_DATA); 64 | IO_Wait(); 65 | uint16_t Hi = IO_In8(SECN_DATA); 66 | IO_Wait(); 67 | return Lo | (Hi << 8); 68 | } 69 | volatile void PicEndOfInterrupt(uint8_t Interrupt) 70 | { 71 | if (Interrupt >= 8) { 72 | IO_Out8(SECN_COMMAND, WORD_EOI); 73 | } 74 | IO_Out8(PRIM_COMMAND, WORD_EOI); 75 | } -------------------------------------------------------------------------------- /kernel/64/pic.h: -------------------------------------------------------------------------------- 1 | #ifndef PIC_H 2 | #define PIC_H 3 | 4 | #include 5 | 6 | void PicInit(); 7 | void PicSetMask(uint16_t Mask); 8 | uint16_t PicGetMask(); 9 | void PicEndOfInterrupt(uint8_t Interrupt); 10 | 11 | #endif // PIC_H -------------------------------------------------------------------------------- /kernel/64/scheduler.c: -------------------------------------------------------------------------------- 1 | #include "scheduler.h" 2 | #include "vmalloc.h" 3 | 4 | static SoftTSS* SchedRing = 0; 5 | static int SchedRingIdx = 0; 6 | static int SchedRingSize = 0; 7 | 8 | void Scheduler_Init() 9 | { 10 | SchedRing = AllocVM(sizeof(SoftTSS) * 128); 11 | SchedRing[0].Privilege = 1; 12 | SchedRing[0].Suspended = 0; 13 | SchedRing[0].SuspendIdx = 0; 14 | SchedRingSize = 1; 15 | SchedRingIdx = 0; 16 | } 17 | 18 | static void StepRing() 19 | { 20 | SchedRingIdx++; 21 | if (SchedRingIdx >= SchedRingSize) SchedRingIdx = 0; 22 | } 23 | 24 | static void SkipSuspended() 25 | { 26 | while (SchedRing[SchedRingIdx].Suspended) 27 | { 28 | StepRing(); 29 | } 30 | } 31 | 32 | SoftTSS* Scheduler_NextProcess(SoftTSS* SaveState) 33 | { 34 | if (SchedRingIdx != 0x7FFFFFFF) 35 | { 36 | if (SchedRingIdx >= SchedRingSize) SchedRingIdx = 0; 37 | if (SchedRingIdx < 0) SchedRingIdx = 0; 38 | 39 | if (SchedRingSize <= 0) SchedRingSize = 1; 40 | 41 | uint64_t Priv = SchedRing[SchedRingIdx].Privilege; 42 | uint64_t StackStart = SchedRing[SchedRingIdx].StackStart; 43 | uint64_t Suspended = SchedRing[SchedRingIdx].Suspended; 44 | uint64_t SuspendIdx = SchedRing[SchedRingIdx].SuspendIdx; 45 | SchedRing[SchedRingIdx] = *SaveState; 46 | SchedRing[SchedRingIdx].Privilege = Priv; 47 | SchedRing[SchedRingIdx].StackStart = StackStart; 48 | SchedRing[SchedRingIdx].Suspended = Suspended; 49 | SchedRing[SchedRingIdx].SuspendIdx = SuspendIdx; 50 | } 51 | else 52 | { 53 | SchedRingIdx = 0; 54 | } 55 | 56 | StepRing(); 57 | 58 | SkipSuspended(); 59 | 60 | return SchedRing + SchedRingIdx; 61 | } 62 | 63 | void Scheduler_AddProcess(uint64_t rip, uint64_t Size) 64 | { 65 | if ((SchedRingSize % 128) == 127) 66 | { 67 | SoftTSS* NewRing = (SoftTSS*)AllocVM(sizeof(SoftTSS) * (SchedRingSize / 128 * 128 + 128)); 68 | for (int i = 0;i < SchedRingSize;i++) 69 | { 70 | NewRing[i] = SchedRing[i]; 71 | } 72 | FreeVM((uint64_t)SchedRing); 73 | SchedRing = NewRing; 74 | } 75 | 76 | SchedRing[SchedRingSize].Privilege = (Size & (uint64_t)0x100000000) >> 32; 77 | SchedRing[SchedRingSize].cs = 0x20 | 3; 78 | SchedRing[SchedRingSize].ds = 0x28 | 3; 79 | SchedRing[SchedRingSize].rip = rip; 80 | SchedRing[SchedRingSize].rsp = AllocVM(0x40000) + 0x40000; 81 | SchedRing[SchedRingSize].StackStart = SchedRing[SchedRingSize].rsp - 0x40000; 82 | SchedRing[SchedRingSize].rflags = 0x200; 83 | SchedRing[SchedRingSize].SuspendIdx = 0; 84 | SchedRing[SchedRingSize].Suspended = 0; 85 | SchedRingSize++; 86 | } 87 | 88 | SoftTSS* Scheduler_EndCurrentProcess(bool SkipToStart) 89 | { 90 | if (SchedRingSize == 0) return; 91 | 92 | if (SchedRing[SchedRingIdx].SuspendIdx) SchedRing[SchedRing[SchedRingIdx].SuspendIdx - 1].Suspended = 0; 93 | 94 | for (int i = 0;i < SchedRingSize;i++) 95 | { 96 | if (i == SchedRingIdx) continue; 97 | if (SchedRing[i].SuspendIdx) if (SchedRing[i].SuspendIdx - 1 > SchedRingIdx) SchedRing[i].SuspendIdx--; 98 | } 99 | 100 | FreeVM(SchedRing[SchedRingIdx].StackStart); 101 | 102 | for (int i = SchedRingIdx + 1;i < SchedRingSize;i++) 103 | { 104 | SchedRing[i - 1] = SchedRing[i]; 105 | } 106 | 107 | SchedRingSize--; 108 | 109 | if (SkipToStart) SchedRingIdx = 0; 110 | else SchedRingIdx = 0x7FFFFFFF; 111 | return SchedRing + SchedRingIdx; 112 | } 113 | 114 | void Scheduler_AddSyscallProcess(uint64_t rip, uint64_t Code, uint64_t rsi, uint64_t Selector) 115 | { 116 | if ((SchedRingSize % 128) == 127) 117 | { 118 | SoftTSS* NewRing = (SoftTSS*)AllocVM(sizeof(SoftTSS) * (SchedRingSize / 128 * 128 + 128)); 119 | for (int i = 0;i < SchedRingSize;i++) 120 | { 121 | NewRing[i] = SchedRing[i]; 122 | } 123 | FreeVM((uint64_t)SchedRing); 124 | SchedRing = NewRing; 125 | } 126 | 127 | SchedRing[SchedRingSize].Privilege = 1; 128 | SchedRing[SchedRingSize].cs = 0x18; 129 | SchedRing[SchedRingSize].ds = 0x10; 130 | SchedRing[SchedRingSize].rsi = rsi; 131 | SchedRing[SchedRingSize].rdi = Code; 132 | SchedRing[SchedRingSize].rdx = Selector; 133 | SchedRing[SchedRingSize].rip = rip; 134 | SchedRing[SchedRingSize].rsp = AllocVM(0x40000) + 0x40000; 135 | SchedRing[SchedRingSize].StackStart = SchedRing[SchedRingSize].rsp - 0x40000; 136 | SchedRing[SchedRingSize].rflags = 0x200; 137 | SchedRing[SchedRingSize].SuspendIdx = SchedRingIdx + 1; 138 | SchedRing[SchedRingSize].Suspended = 0; 139 | SchedRing[SchedRingIdx].Suspended = 1; 140 | SchedRingSize++; 141 | } -------------------------------------------------------------------------------- /kernel/64/scheduler.h: -------------------------------------------------------------------------------- 1 | #ifndef SCHEDULER_H 2 | #define SCHEDULER_H 3 | 4 | #include "../include.h" 5 | #include "softtss.h" 6 | 7 | void Scheduler_Init(); 8 | // Returns pointer to next program's TSS. Doesnt immediately switch to the next process. 9 | SoftTSS* Scheduler_NextProcess(SoftTSS* SaveState); 10 | SoftTSS* Scheduler_EndCurrentProcess(bool SkipToStart); 11 | void Scheduler_AddProcess(uint64_t rip, uint64_t Size); 12 | void Scheduler_AddSyscallProcess(uint64_t rip, uint64_t Code, uint64_t rsi, uint64_t Selector); 13 | 14 | #endif // SCHEDULER_H -------------------------------------------------------------------------------- /kernel/64/sleep.h: -------------------------------------------------------------------------------- 1 | #ifndef SLEEP_H 2 | #define SLEEP_H 3 | 4 | // STUB 5 | static inline void Sleep(size_t ms) { 6 | for (int j = 0; j < 100 * ms; j++) { 7 | // TODO: Make a sleep function 8 | IO_Wait(); 9 | } 10 | } 11 | 12 | #endif -------------------------------------------------------------------------------- /kernel/64/softtss.h: -------------------------------------------------------------------------------- 1 | #ifndef SOFTTSS_H 2 | #define SOFTTSS_H 3 | 4 | #include "../include.h" 5 | 6 | typedef struct { 7 | uint64_t rax; 8 | uint64_t rbx; 9 | uint64_t rcx; 10 | uint64_t rdx; 11 | uint64_t rdi; 12 | uint64_t rsi; 13 | uint64_t rsp; 14 | uint64_t rflags; 15 | uint64_t rip; 16 | uint64_t rbp; 17 | uint64_t r9; 18 | uint64_t r10; 19 | uint64_t r11; 20 | uint64_t r12; 21 | uint64_t r13; 22 | uint64_t r14; 23 | uint64_t r15; 24 | uint64_t XMM0_0; 25 | uint64_t XMM0_1; 26 | uint64_t XMM1_0; 27 | uint64_t XMM1_1; 28 | uint64_t XMM2_0; 29 | uint64_t XMM2_1; 30 | uint64_t XMM3_0; 31 | uint64_t XMM3_1; 32 | uint64_t XMM4_0; 33 | uint64_t XMM4_1; 34 | uint64_t XMM5_0; 35 | uint64_t XMM5_1; 36 | uint64_t XMM6_0; 37 | uint64_t XMM6_1; 38 | uint64_t XMM7_0; 39 | uint64_t XMM7_1; 40 | uint64_t XMM8_0; 41 | uint64_t XMM8_1; 42 | uint64_t XMM9_0; 43 | uint64_t XMM9_1; 44 | uint64_t XMM10_0; 45 | uint64_t XMM10_1; 46 | uint64_t XMM11_0; 47 | uint64_t XMM11_1; 48 | uint64_t XMM12_0; 49 | uint64_t XMM12_1; 50 | uint64_t XMM13_0; 51 | uint64_t XMM13_1; 52 | uint64_t XMM14_0; 53 | uint64_t XMM14_1; 54 | uint64_t XMM15_0; 55 | uint64_t XMM15_1; 56 | uint64_t cs; 57 | uint64_t ds; 58 | 59 | // EXTERNAL 60 | uint64_t Privilege; 61 | uint64_t StackStart; 62 | uint64_t SuspendIdx; 63 | uint64_t Suspended; 64 | } __attribute__((packed)) SoftTSS; 65 | 66 | #endif // SOFTTSS_H -------------------------------------------------------------------------------- /kernel/64/syscall.c: -------------------------------------------------------------------------------- 1 | #include "syscall.h" 2 | #include "scheduler.h" 3 | #include "draw.h" 4 | #include "panic.h" 5 | #include "drivers/driverman.h" 6 | 7 | #define KEY_QUEUE_SIZE 64 8 | 9 | extern char KeyQueue[KEY_QUEUE_SIZE]; 10 | extern size_t KeyQueueIdx; 11 | 12 | extern int MSTicks; 13 | 14 | static void SyscallInline(uint64_t Code, uint64_t rsi, uint64_t Selector) 15 | { 16 | if (Code == 0) 17 | { 18 | FreeVM(rsi); 19 | } 20 | else if (Code == 1) 21 | { 22 | *(void**)rsi = (void*)AllocVM(Selector); 23 | } 24 | else if (Code == 2) 25 | { 26 | Scheduler_AddProcess(rsi, Selector); 27 | } 28 | else if (Code == 4) 29 | { 30 | Draw_Packet* Packet = (Draw_Packet*)rsi; 31 | for (int i = 0; i < Packet->pointsSize; i++) 32 | { 33 | Draw_PointEntry Entry = ((Draw_PointEntry*)Packet->points)[i]; 34 | 35 | Draw_Point(Entry); 36 | } 37 | for (int i = 0; i < Packet->linesSize; i++) 38 | { 39 | Draw_LineEntry Entry = ((Draw_LineEntry*)Packet->lines)[i]; 40 | 41 | Draw_Line(Entry); 42 | } 43 | for (int i = 0; i < Packet->textsSize; i++) 44 | { 45 | Draw_TextEntry Entry = ((Draw_TextEntry*)Packet->texts)[i]; 46 | 47 | Draw_Text(Entry); 48 | } 49 | for (int i = 0; i < Packet->rectsSize; i++) 50 | { 51 | Draw_RectEntry Entry = ((Draw_RectEntry*)Packet->rects)[i]; 52 | 53 | Draw_Rect(Entry); 54 | } 55 | for (int i = 0; i < Packet->imagesSize; i++) 56 | { 57 | Draw_ImageEntry Entry = ((Draw_ImageEntry*)Packet->images)[i]; 58 | 59 | Draw_Image(Entry); 60 | } 61 | } 62 | else if (Code == 5) 63 | { 64 | *(float*)rsi = MSTicks; 65 | } 66 | else if (Code == 6) 67 | { 68 | *(char*)rsi = KeyQueueIdx > 0 ? KeyQueue[--KeyQueueIdx] : 0; 69 | } 70 | } 71 | 72 | static void SyscallIndirect(uint64_t Code, uint64_t rsi, uint64_t Selector) 73 | { 74 | DriverMan_StorageDevice** StorageDevices; 75 | size_t StorageDevicesCount; 76 | DriverMan_GetStorageDevices(&StorageDevices, &StorageDevicesCount); 77 | 78 | if (Code == 7) 79 | { 80 | DriverMan_FilesysMakeDir(StorageDevices[0], (char*)rsi); 81 | } 82 | else if (Code == 8) 83 | { 84 | DriverMan_FilesysMakeFile(StorageDevices[0], (char*)rsi); 85 | } 86 | else if (Code == 9) 87 | { 88 | DriverMan_FilesysRemove(StorageDevices[0], (char*)rsi); 89 | } 90 | else if (Code == 10) 91 | { 92 | FileRequest* Req = (FileRequest*)Selector; 93 | DriverMan_FilesysWriteFile(StorageDevices[0], (char*)rsi, Req->Data, Req->Bytes); 94 | } 95 | else if (Code == 11) 96 | { 97 | FileResponse Response; 98 | Response.Data = DriverMan_FilesysReadFile(StorageDevices[0], (char*)rsi, &Response.BytesRead); 99 | *(FileResponse*)Selector = Response; 100 | } 101 | else if (Code == 12) 102 | { 103 | *(size_t*)Selector = DriverMan_FilesysFileSize(StorageDevices[0], (char*)rsi); 104 | } 105 | else if (Code == 13) 106 | { 107 | FileListResponse Response; 108 | Response.Data = DriverMan_FilesysListFiles(StorageDevices[0], (char*)rsi, &Response.NumEntries); 109 | *(FileListResponse*)Selector = Response; 110 | } 111 | Scheduler_EndCurrentProcess(false); 112 | while (1); 113 | } 114 | 115 | uint64_t Syscall(uint64_t Code, uint64_t rsi, uint64_t Selector, SoftTSS* SaveState) 116 | { 117 | if (Code == 3) 118 | { 119 | return Scheduler_EndCurrentProcess(true); 120 | } 121 | 122 | if (Code < 7) 123 | { 124 | SyscallInline(Code, rsi, Selector); 125 | return 0; 126 | } 127 | 128 | Scheduler_AddSyscallProcess(SyscallIndirect, Code, rsi, Selector); 129 | 130 | return Scheduler_NextProcess(SaveState); 131 | } -------------------------------------------------------------------------------- /kernel/64/syscall.h: -------------------------------------------------------------------------------- 1 | #ifndef SYSCALL_H 2 | #define SYSCALL_H 3 | 4 | #include "../include.h" 5 | #include "softtss.h" 6 | uint64_t Syscall(uint64_t Code, uint64_t rsi, uint64_t Selector, SoftTSS* SaveState); 7 | 8 | #endif // SYSCALL_H -------------------------------------------------------------------------------- /kernel/64/vmalloc.c: -------------------------------------------------------------------------------- 1 | #include "vmalloc.h" 2 | 3 | #define MAX_ADDR_BIT 47 4 | #define PRESENT_BIT 0 5 | #define READWRITE_BIT 1 6 | #define USER_SUPERVISOR_BIT 2 7 | #define WRITE_THROUGH_BIT 3 8 | #define CACHE_DISABLE_BIT 4 9 | #define ACCESSED_BIT 5 10 | #define PAGE_SIZE_BIT 7 11 | #define ADDR_BIT 12 12 | #define AVAILABLE_BIT 52 13 | #define NO_EXECUTE_BIT 63 14 | #define PMT_SIZE 512 15 | 16 | typedef struct 17 | { 18 | uint64_t Data; 19 | } __attribute__((packed, scalar_storage_order("little-endian"))) PageMapTable; 20 | 21 | PageMapTable* Tier4; 22 | PageMapTable* AllocOffset = 0x400000; 23 | 24 | volatile PageMapTable InitTable(int Depth) 25 | { 26 | PageMapTable Ret; 27 | Ret.Data = (uint64_t)AllocOffset & 0xFFFFFFFFF000; 28 | 29 | PageMapTable* TempAllocOffset = AllocOffset; 30 | AllocOffset += PMT_SIZE; 31 | if (Depth < 3) for (int i = 0;i < PMT_SIZE;i++) 32 | { 33 | (*TempAllocOffset) = InitTable(Depth + 1); 34 | TempAllocOffset++; 35 | } 36 | return Ret; 37 | } 38 | 39 | volatile bool AllocPage(PageMapTable* BasePte, uint64_t vAddr, uint64_t pAddr, int Depth, uint64_t Flags) 40 | { 41 | uint64_t Index = (vAddr & (0x1FFULL << ((3 - Depth) * 9 + 12))) >> ((3 - Depth) * 9 + 12); 42 | Index &= 0x1FF; 43 | if (Depth == 3) 44 | { 45 | BasePte[Index].Data = Flags; 46 | BasePte[Index].Data |= pAddr & 0xFFFFFFFFF000; 47 | BasePte[Index].Data |= 1 << PRESENT_BIT; 48 | BasePte[Index].Data |= 1 << READWRITE_BIT; 49 | return true; 50 | } 51 | if (BasePte[Index].Data == 0) 52 | { 53 | AllocOffset += PMT_SIZE; 54 | if (AllocOffset >= 0x20000000) 55 | { 56 | return false; 57 | } 58 | BasePte[Index].Data = Flags; 59 | BasePte[Index].Data |= (uint64_t)AllocOffset & 0xFFFFFFFFF000; 60 | for (int i = 0;i < PMT_SIZE;i++) 61 | { 62 | AllocOffset[i].Data = 0; 63 | } 64 | } 65 | else 66 | { 67 | BasePte[Index].Data &= 0x7FFFFFFFFFFFF000; 68 | BasePte[Index].Data |= Flags & 0b111111111; 69 | } 70 | BasePte[Index].Data |= 1 << PRESENT_BIT; 71 | BasePte[Index].Data |= 1 << READWRITE_BIT; 72 | return AllocPage(BasePte[Index].Data & 0xFFFFFFFFF000, vAddr, pAddr, Depth + 1, Flags); 73 | } 74 | 75 | volatile bool PageAvailable(PageMapTable* BasePte, uint64_t vAddr, int Depth) 76 | { 77 | uint64_t Index = (vAddr & (0x1FFULL << ((3 - Depth) * 9 + 12))) >> ((3 - Depth) * 9 + 12); 78 | Index &= 0x1FF; 79 | 80 | if ((BasePte[Index].Data & (1ULL << PRESENT_BIT)) == 0) return true; 81 | if (Depth == 3) return false; 82 | return PageAvailable(BasePte[Index].Data & 0xFFFFFFFFF000, vAddr, Depth + 1); 83 | } 84 | 85 | volatile uint64_t GetPage(PageMapTable* BasePte, uint64_t vAddr, int Depth) 86 | { 87 | uint64_t Index = (vAddr & (0x1FFULL << ((3 - Depth) * 9 + 12))) >> ((3 - Depth) * 9 + 12); 88 | Index &= 0x1FF; 89 | 90 | if (Depth == 3) 91 | { 92 | if ((BasePte[Index].Data & (1ULL << PRESENT_BIT)) == 0) return BasePte[Index].Data; 93 | return 0; 94 | } 95 | return PageAvailable(BasePte[Index].Data & 0xFFFFFFFFF000, vAddr, Depth + 1); 96 | } 97 | 98 | volatile void FreePage(PageMapTable* BasePte, uint64_t vAddr, int Depth) 99 | { 100 | uint64_t Index = ((uint64_t)vAddr & (0x1FFULL << ((3 - Depth) * 9 + 12))) >> ((3 - Depth) * 9 + 12); 101 | Index &= 0x1FF; 102 | if (Depth == 3) 103 | { 104 | if (BasePte[Index].Data & (1ULL << PRESENT_BIT)) return; 105 | BasePte[Index].Data = 0; 106 | return; 107 | } 108 | if ((BasePte[Index].Data & (1ULL << PRESENT_BIT)) == 0) 109 | { 110 | return; 111 | } 112 | FreePage(BasePte[Index].Data & 0xFFFFFFFFF000, vAddr, Depth + 1); 113 | PageMapTable* Check = BasePte[Index].Data & 0xFFFFFFFFF000; 114 | for (int i = 0;i < PMT_SIZE;i++) 115 | { 116 | if (Check[i].Data) return; 117 | } 118 | BasePte[Index].Data = 0; 119 | } 120 | 121 | static inline void Flush() 122 | { 123 | asm volatile("mov $0x10000000, %rax\nmov %rax, %cr3"); 124 | } 125 | 126 | volatile bool AllocIdMap(uint64_t Addr, uint64_t Size, uint64_t Flags) 127 | { 128 | // FIXME: If the size is the factor of 0x1000 it will allocate an extra page 129 | for (uint64_t i = 0;i <= Size / 0x1000;i++) 130 | { 131 | if (!AllocPage(Tier4, Addr + i * 0x1000, Addr + i * 0x1000, 0, Flags)) return false; 132 | } 133 | Flush(); 134 | return true; 135 | } 136 | 137 | volatile bool AllocMap(uint64_t vAddr, uint64_t pAddr, uint64_t Size, uint64_t Flags) 138 | { 139 | // FIXME: If the size is the factor of 0x1000 it will allocate an extra page 140 | for (uint64_t i = 0;i <= Size / 0x1000;i++) 141 | { 142 | if (!AllocPage(Tier4, vAddr + i * 0x1000, pAddr + i * 0x1000, 0, Flags)) return false; 143 | } 144 | Flush(); 145 | return true; 146 | } 147 | 148 | volatile void AllocUnMap(uint64_t vAddr, uint64_t Size) 149 | { 150 | // FIXME: If the size is the factor of 0x1000 it will free an extra page 151 | for (uint64_t i = 0;i <= Size / 0x1000;i++) 152 | { 153 | FreePage(Tier4, vAddr + i * 0x1000, 0); 154 | } 155 | Flush(); 156 | } 157 | 158 | #define PHYS_TAKEN_SIZE (0x80000000 / 0x1000) 159 | #define PHYS_TAKEN_START 0x20000000 160 | 161 | static uint8_t PhysTaken[PHYS_TAKEN_SIZE]; // 4 KiB (Page) Blocks 162 | static size_t PhysTakenCache = 0; 163 | static size_t VmCache = 0; 164 | 165 | volatile uint64_t AllocVM(uint64_t Size) 166 | { 167 | uint64_t MemMapSize = *(uint64_t*)0x7E01; 168 | uint64_t* MemMap = 0x7E05; 169 | 170 | uint64_t PAddr = 0; 171 | uint64_t PAddrI = 0; 172 | 173 | if (Size < 0x1000) Size = 0x1000; 174 | Size /= 0x1000; 175 | 176 | uint64_t StoreSize = Size; 177 | if (StoreSize > 0b1111111111ULL) StoreSize = (uint64_t)0b1111111111ULL; 178 | 179 | uint64_t Size0 = (StoreSize & (uint64_t)0b111) << 9; 180 | uint64_t Size1 = ((StoreSize & (uint64_t)0b1111111000) >> 3) << 52; 181 | 182 | for (uint64_t i = PhysTakenCache;i < PHYS_TAKEN_SIZE;i++) 183 | { 184 | uint64_t Con = i * 0x1000 + PHYS_TAKEN_START; 185 | for (uint64_t j = 0;j < Size;j++) 186 | { 187 | if (PhysTaken[i++]) 188 | { 189 | i--; 190 | goto NextAttemptAllocVM; 191 | } 192 | } 193 | for (uint64_t k = 0;k < MemMapSize;k++) 194 | { 195 | if (MemMap[k * 2 + 0] < Con && MemMap[k * 2 + 0] + MemMap[k * 2 + 1] > Con + Size * 0x1000) goto FoundAllocVM; 196 | } 197 | continue; 198 | FoundAllocVM: 199 | 200 | PAddr = Con; 201 | PAddrI = i; 202 | break; 203 | 204 | NextAttemptAllocVM: 205 | } 206 | if (PAddr == 0) return 0; 207 | 208 | PhysTakenCache = PAddrI; 209 | 210 | for (uint64_t i = VmCache ? VmCache : 0x10000000;i < 0x80000000;i += 0x1000) 211 | { 212 | uint64_t Con = i; 213 | for (uint64_t j = 0;j < Size;j++) 214 | { 215 | if (!PageAvailable(Tier4, i, 0)) goto NextVAttemptAllocVM; 216 | i += 0x1000; 217 | } 218 | i = Con; 219 | for (uint64_t j = 0;j < Size;j++) 220 | { 221 | if (j == 0) 222 | { 223 | if (!AllocPage(Tier4, i, PAddr, 0, (1ULL << READWRITE_BIT) | (1ULL << USER_SUPERVISOR_BIT) | Size0 | Size1)) return 0; 224 | } 225 | else 226 | { 227 | if (!AllocPage(Tier4, i, PAddr, 0, (1ULL << READWRITE_BIT) | (1ULL << USER_SUPERVISOR_BIT))) return 0; 228 | } 229 | PhysTaken[(PAddr - PHYS_TAKEN_START) / 0x1000] = 1; 230 | i += 0x1000; 231 | PAddr += 0x1000; 232 | } 233 | 234 | Flush(); 235 | 236 | VmCache = Con + Size * 0x1000; 237 | return Con; 238 | 239 | NextVAttemptAllocVM: 240 | } 241 | 242 | return 0; 243 | } 244 | 245 | volatile uint64_t AllocPhys(uint64_t Size) 246 | { 247 | uint64_t MemMapSize = *(uint64_t*)0x7E01; 248 | uint64_t* MemMap = 0x7E05; 249 | 250 | uint64_t PAddr = 0; 251 | uint64_t PAddrI = 0; 252 | 253 | if (Size < 0x1000) Size = 0x1000; 254 | Size /= 0x1000; 255 | 256 | uint64_t StoreSize = Size; 257 | if (StoreSize > 0b1111111111ULL) StoreSize = (uint64_t)0b1111111111ULL; 258 | 259 | uint64_t Size0 = (StoreSize & (uint64_t)0b111) << 9; 260 | uint64_t Size1 = ((StoreSize & (uint64_t)0b1111111000) >> 3) << 52; 261 | 262 | for (uint64_t i = 0;i < PHYS_TAKEN_SIZE;i++) 263 | { 264 | uint64_t Con = i * 0x1000 + PHYS_TAKEN_START; 265 | for (uint64_t j = 0;j < Size;j++) 266 | { 267 | if (PhysTaken[i++]) 268 | { 269 | i--; 270 | goto NextAttemptAllocPhys; 271 | } 272 | } 273 | for (uint64_t k = 0;k < MemMapSize;k++) 274 | { 275 | if (MemMap[k * 2 + 0] < Con && MemMap[k * 2 + 0] + MemMap[k * 2 + 1] > Con + Size * 0x1000) goto FoundAllocPhys; 276 | } 277 | continue; 278 | FoundAllocPhys: 279 | 280 | PAddr = Con; 281 | PAddrI = i; 282 | break; 283 | 284 | NextAttemptAllocPhys: 285 | } 286 | if (PAddr == 0) return 0; 287 | 288 | uint64_t Con = PAddr; 289 | for (uint64_t j = 0;j < Size;j++) 290 | { 291 | if (j == 0) 292 | { 293 | if (!AllocPage(Tier4, Con + j * 0x1000, PAddr, 0, (1ULL << READWRITE_BIT) | (1ULL << USER_SUPERVISOR_BIT) | (1ULL << CACHE_DISABLE_BIT) | Size0 | Size1)) return 0; 294 | } 295 | else 296 | { 297 | if (!AllocPage(Tier4, Con + j * 0x1000, PAddr, 0, (1ULL << READWRITE_BIT) | (1ULL << USER_SUPERVISOR_BIT) | (1ULL << CACHE_DISABLE_BIT))) return 0; 298 | } 299 | PhysTaken[(PAddr - PHYS_TAKEN_START) / 0x1000] = 1; 300 | PAddr += 0x1000; 301 | } 302 | 303 | Flush(); 304 | 305 | return Con; 306 | } 307 | 308 | volatile uint64_t AllocVMAtPhys(uint64_t pAddr, uint64_t Size) 309 | { 310 | uint64_t PAddr = pAddr; 311 | uint64_t PAddrI = (PAddr - PHYS_TAKEN_START) / 0x1000; 312 | 313 | if (Size < 0x1000) Size = 0x1000; 314 | Size /= 0x1000; 315 | 316 | uint64_t StoreSize = Size; 317 | if (StoreSize > 0b1111111111ULL) StoreSize = (uint64_t)0b1111111111ULL; 318 | 319 | uint64_t Size0 = (StoreSize & (uint64_t)0b111) << 9; 320 | uint64_t Size1 = ((StoreSize & (uint64_t)0b1111111000) >> 3) << 52; 321 | 322 | for (uint64_t i = 0x10000000;i < 0x80000000;i += 0x1000) 323 | { 324 | uint64_t Con = i; 325 | for (uint64_t j = 0;j < Size;j++) 326 | { 327 | if (!PageAvailable(Tier4, i, 0)) goto NextVAttemptAllocVM; 328 | i += 0x1000; 329 | } 330 | i = Con; 331 | for (uint64_t j = 0;j < Size;j++) 332 | { 333 | if (j == 0) 334 | { 335 | if (!AllocPage(Tier4, i, PAddr, 0, (1ULL << READWRITE_BIT) | (1ULL << CACHE_DISABLE_BIT) | Size0 | Size1)) return 0; 336 | } 337 | else 338 | { 339 | if (!AllocPage(Tier4, i, PAddr, 0, (1ULL << READWRITE_BIT) | (1ULL << CACHE_DISABLE_BIT))) return 0; 340 | } 341 | i += 0x1000; 342 | PAddr += 0x1000; 343 | } 344 | 345 | Flush(); 346 | 347 | return Con; 348 | 349 | NextVAttemptAllocVM: 350 | } 351 | 352 | return 0; 353 | } 354 | 355 | volatile void FreeVM(uint64_t vAddr) 356 | { 357 | uint64_t Page = GetPage(Tier4, vAddr, 0); 358 | uint64_t Size0 = (Page >> 9) & 0b111; 359 | uint64_t Size1 = (Page >> 52) & 0b1111111; 360 | uint64_t PagePhys = Page >> 12; 361 | PagePhys &= 0xFFFFFULL; 362 | PagePhys *= 0x1000; 363 | 364 | if (vAddr < VmCache) VmCache = vAddr; 365 | PhysTakenCache = 0; 366 | 367 | if (Size0 == 0 && Size1 == 0) return; 368 | 369 | uint64_t Size = (Size1 << 3) | Size0; 370 | 371 | int PAddrI = (PagePhys - PHYS_TAKEN_START) / 0x1000; 372 | for (int i = 0;i < Size;i++) 373 | { 374 | FreePage(Tier4, vAddr + i * 0x1000, 0); 375 | PhysTaken[PAddrI++] = 0; 376 | } 377 | } 378 | 379 | volatile uint64_t AllocVMAt(uint64_t vAddr, uint64_t Size) 380 | { 381 | uint64_t MemMapSize = *(uint64_t*)0x7E01; 382 | uint64_t* MemMap = 0x7E05; 383 | 384 | uint64_t PAddr = vAddr; 385 | 386 | for (uint64_t j = vAddr;j < vAddr + Size;j += 0x1000) 387 | { 388 | AllocPage(Tier4, j, PAddr, 0, (1ULL << READWRITE_BIT) | (1ULL << USER_SUPERVISOR_BIT)); 389 | PAddr += 0x1000; 390 | } 391 | return vAddr; 392 | } 393 | 394 | volatile uint64_t AllocVMAtFlags(uint64_t vAddr, uint64_t Size, uint64_t Flags) 395 | { 396 | uint64_t MemMapSize = *(uint64_t*)0x7E01; 397 | uint64_t* MemMap = 0x7E05; 398 | 399 | uint64_t PAddr = vAddr; 400 | 401 | for (uint64_t j = vAddr;j < vAddr + Size;j += 0x1000) 402 | { 403 | AllocPage(Tier4, j, PAddr, 0, Flags); 404 | PAddr += 0x1000; 405 | } 406 | return vAddr; 407 | } 408 | 409 | volatile uint64_t AllocVMAtStack(uint64_t vAddr, uint64_t Size) 410 | { 411 | uint64_t MemMapSize = *(uint64_t*)0x7E01; 412 | uint64_t* MemMap = 0x7E05; 413 | 414 | uint64_t PAddr = vAddr; 415 | 416 | for (uint64_t j = vAddr;j < vAddr + Size;j += 0x1000) 417 | { 418 | AllocPage(Tier4, j, PAddr, 0, (1ULL << READWRITE_BIT) | (1ULL << USER_SUPERVISOR_BIT)); 419 | PAddr += 0x1000; 420 | } 421 | return vAddr; 422 | } 423 | 424 | volatile void AllocInit() 425 | { 426 | AllocOffset = *(uint32_t*)0x7FF0; 427 | Tier4 = 0x10000000; 428 | 429 | VmCache = 0; 430 | PhysTakenCache = 0; 431 | 432 | for (int i = 0;i < PHYS_TAKEN_SIZE;i++) 433 | { 434 | PhysTaken[i] = 0; 435 | } 436 | } -------------------------------------------------------------------------------- /kernel/64/vmalloc.h: -------------------------------------------------------------------------------- 1 | #ifndef VMALLOC_H 2 | #define VMALLOC_H 3 | 4 | #include "../include.h" 5 | 6 | #define MALLOC_MAX_ADDR_BIT 47 7 | #define MALLOC_PRESENT_BIT 0 8 | #define MALLOC_READWRITE_BIT 1 9 | #define MALLOC_USER_SUPERVISOR_BIT 2 10 | #define MALLOC_WRITE_THROUGH_BIT 3 11 | #define MALLOC_CACHE_DISABLE_BIT 4 12 | #define MALLOC_ACCESSED_BIT 5 13 | #define MALLOC_PAGE_SIZE_BIT 7 14 | #define MALLOC_ADDR_BIT 12 15 | #define MALLOC_AVAILABLE_BIT 52 16 | #define MALLOC_NO_EXECUTE_BIT 63 17 | 18 | volatile bool AllocIdMap(uint64_t Addr, uint64_t Size, uint64_t Flags); 19 | volatile bool AllocMap(uint64_t vAddr, uint64_t pAddr, uint64_t Size, uint64_t Flags); 20 | volatile void AllocUnMap(uint64_t vAddr, uint64_t Size); 21 | volatile uint64_t AllocVM(uint64_t Size); 22 | volatile uint64_t AllocPhys(uint64_t Size); // Must return 4 KiB aligned address for NVMe driver, etc 23 | volatile void FreeVM(uint64_t vAddr); 24 | volatile uint64_t AllocVMAt(uint64_t vAddr, uint64_t Size); 25 | volatile uint64_t AllocVMAtFlags(uint64_t vAddr, uint64_t Size, uint64_t Flags); 26 | volatile uint64_t AllocVMAtPhys(uint64_t pAddr, uint64_t Size); // FOR DRIVERS 27 | volatile uint64_t AllocVMAtStack(uint64_t vAddr, uint64_t Size); 28 | volatile void AllocInit(); 29 | 30 | #endif VMALLOC_H -------------------------------------------------------------------------------- /kernel/draw.h: -------------------------------------------------------------------------------- 1 | #include "include.h" 2 | 3 | typedef struct { 4 | int32_t x; 5 | int32_t y; 6 | int32_t w; 7 | int32_t h; 8 | uint32_t col; 9 | } Draw_RectEntry; 10 | 11 | typedef struct { 12 | int32_t x0; 13 | int32_t y0; 14 | int32_t x1; 15 | int32_t y1; 16 | uint32_t col; 17 | } Draw_LineEntry; 18 | 19 | typedef struct { 20 | int32_t x; 21 | int32_t y; 22 | uint32_t col; 23 | } Draw_PointEntry; 24 | 25 | typedef struct { 26 | const char* text; 27 | int32_t x; 28 | int32_t y; 29 | uint32_t col; 30 | } Draw_TextEntry; 31 | 32 | typedef struct { 33 | int32_t x; 34 | int32_t y; 35 | uint32_t w; 36 | uint32_t h; 37 | uint32_t* image; // ARGB 38 | } Draw_ImageEntry; 39 | 40 | typedef struct { 41 | Draw_RectEntry* rects; 42 | size_t rectsSize; 43 | Draw_LineEntry* lines; 44 | size_t linesSize; 45 | Draw_PointEntry* points; 46 | size_t pointsSize; 47 | Draw_TextEntry* texts; 48 | size_t textsSize; 49 | Draw_ImageEntry* images; 50 | size_t imagesSize; 51 | } Draw_Packet; 52 | 53 | typedef struct { 54 | uint64_t Width; 55 | uint64_t Height; 56 | } Draw_Info; 57 | 58 | -------------------------------------------------------------------------------- /kernel/file.h: -------------------------------------------------------------------------------- 1 | #ifndef FILE_H 2 | #define FILE_H 3 | 4 | #include "include.h" 5 | 6 | typedef struct 7 | { 8 | void* Data; 9 | 10 | // For read 11 | size_t BytesRead; 12 | } FileResponse; 13 | 14 | typedef struct 15 | { 16 | char* Name; 17 | bool IsDir; 18 | } FileListEntry; 19 | 20 | typedef struct 21 | { 22 | FileListEntry* Data; 23 | size_t NumEntries; 24 | } FileListResponse; 25 | 26 | typedef struct 27 | { 28 | void* Data; 29 | size_t Bytes; 30 | } FileRequest; 31 | 32 | #endif // FILE_H -------------------------------------------------------------------------------- /kernel/include.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include -------------------------------------------------------------------------------- /kernel/vbe.h: -------------------------------------------------------------------------------- 1 | #ifndef VBE_H 2 | #define VBE_H 3 | 4 | #include 5 | 6 | #define VBE_INFO_LOC 0x8000 7 | 8 | typedef struct { 9 | uint8_t Junk[256 + 256]; 10 | uint16_t Attributes; // deprecated, only bit 7 should be of interest to you, and it indicates the mode supports a linear frame buffer. 11 | uint8_t WindowA; // deprecated 12 | uint8_t WindowB; // deprecated 13 | uint16_t Granularity; // deprecated; used while calculating bank numbers 14 | uint16_t WindowSize; 15 | uint16_t SegmentA; 16 | uint16_t SegmentB; 17 | uint32_t WinFuncPtr; // deprecated; used to switch banks from protected mode without returning to real mode 18 | uint16_t Pitch; // number of bytes per horizontal line 19 | uint16_t Width; // width in pixels 20 | uint16_t Height; // height in pixels 21 | uint8_t WChar; // unused... 22 | uint8_t YChar; // ... 23 | uint8_t Planes; 24 | uint8_t Bpp; // bits per pixel in this mode 25 | uint8_t Banks; // deprecated; total number of banks in this mode 26 | uint8_t MemoryModel; 27 | uint8_t BankSize; // deprecated; size of a bank, almost always 64 KB but may be 16 KB... 28 | uint8_t ImagePages; 29 | uint8_t Reserved0; 30 | 31 | uint8_t RedMask; 32 | uint8_t RedPosition; 33 | uint8_t GreenMask; 34 | uint8_t GreenPosition; 35 | uint8_t BlueMask; 36 | uint8_t BluePosition; 37 | uint8_t ReservedMask; 38 | uint8_t ReservedPosition; 39 | uint8_t DirectColorAttributes; 40 | 41 | uint32_t Framebuffer; // physical address of the linear frame buffer; write here to draw to the screen 42 | uint32_t OffScreenMemOff; 43 | uint16_t OffScreenMemSize; // size of memory in the framebuffer but not being displayed on the screen 44 | uint8_t reserved1[206]; 45 | } __attribute__ ((packed)) VesaVbeModeInfo; 46 | 47 | #endif // VBE_H -------------------------------------------------------------------------------- /link32.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT(binary) 2 | SECTIONS { 3 | . = 0x8600; 4 | .main32 : 5 | { 6 | *(.main32) 7 | *(.text) 8 | } 9 | .rodata : 10 | { 11 | *(.rodata) 12 | } 13 | .data : 14 | { 15 | *(.data) 16 | } 17 | .bss : 18 | { 19 | *(.bss) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /link64.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT(binary) 2 | SECTIONS { 3 | . = 0xFFFFFFFFC0000000; 4 | start_of_sections = .; 5 | 6 | .main64 : 7 | { 8 | *(.main64) 9 | *(.text) 10 | *(.handlers) 11 | } 12 | .rodata : 13 | { 14 | *(.rodata) 15 | } 16 | .data : 17 | { 18 | *(.data) 19 | } 20 | 21 | end_of_sections = .; 22 | 23 | ASSERT((end_of_sections - start_of_sections) <= 0x200000, "Size of all sections exceeds the limit") 24 | . = 0xFFFFFFFFC1200000; 25 | .bss : 26 | { 27 | *(.bss) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /linkos.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT(binary) 2 | SECTIONS { 3 | . = 0xB00000; 4 | .text : 5 | { 6 | *(.startos) 7 | *(.text) 8 | *(.helper) 9 | } 10 | .rodata : 11 | { 12 | *(.rodata) 13 | } 14 | .data : 15 | { 16 | *(.data) 17 | } 18 | . = 0xB50000; 19 | start_of_sections = .; 20 | .bss : 21 | { 22 | *(.bss) 23 | } 24 | end_of_sections = .; 25 | 26 | ASSERT((end_of_sections - start_of_sections) <= 0x50000, "Size of bss exceeds the limit") 27 | } 28 | -------------------------------------------------------------------------------- /linktrampoline.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_FORMAT(binary) 2 | SECTIONS { 3 | . = 0x8400; 4 | .boot : 5 | { 6 | *(.boot) 7 | } 8 | . = 0x100000; 9 | .os : 10 | { 11 | *(.os) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | build: 2 | mkdir -p bin 3 | gcc -m32 kernel/32/*.c -nostdlib -ffreestanding -fno-stack-protector -fno-stack-check -mno-red-zone -fno-exceptions -nodefaultlibs -fno-builtin -fno-pic -fno-pie -O2 -T link32.ld -o paging32.img 4 | gcc -c -m64 kernel/64/*.c kernel/64/drivers/*/*.c kernel/64/drivers/*.c -nostdlib -ffreestanding -fno-stack-protector -fno-stack-check -mno-red-zone -fno-exceptions -nodefaultlibs -fno-builtin -fno-pic -fno-pie -mcmodel=large -fcf-protection=none -O0 -w 5 | nasm -f elf64 kernel/64/idt.s -o idt_s.o 6 | nasm -f elf64 kernel/64/drivers/ide/ata.s -o ide_ata.o 7 | ld -m elf_x86_64 -T link64.ld *.o -o kernel.img 8 | rm *.o 9 | nasm -f elf64 os/helper.s -o helper.o 10 | gcc -m64 os/*.c os/modules/*.c os/modules/helpers/*.c os/modules/helpers/bf/*.c helper.o -nostdlib -ffreestanding -fno-stack-protector -fno-stack-check -mno-red-zone -fno-exceptions -nodefaultlibs -fno-builtin -fno-PIC -fno-PIE -mcmodel=large -fcf-protection=none -fno-inline -O0 -T linkos.ld -o os.img 11 | nasm -f bin boot/boot32.s -o boot.img 12 | nasm -f bin boot/os_trampoline32.s -o boot-x86_64.img 13 | cat boot.img > bin/boot.img 14 | cat boot-x86_64.img >> bin/boot.img 15 | rm *.img 16 | rm *.o 17 | qemu-img resize bin/boot.img 32M 18 | run: 19 | qemu-system-x86_64 -hda bin/boot.img -drive file=bin/storage.disk,format=raw,if=none,id=nvm -device nvme,serial=deadbeef,id=nvme-ctrl-0 -device nvme-ns,drive=nvm,nsid=1 -no-reboot -m 4G -smp 1 -device qemu-xhci -device usb-mouse -------------------------------------------------------------------------------- /os/drawcall.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAWCALL_H 2 | #define DRAWCALL_H 3 | 4 | extern volatile void DrawCall(void*); 5 | 6 | #endif // DRAWCALL_H -------------------------------------------------------------------------------- /os/drawman.c: -------------------------------------------------------------------------------- 1 | #include "drawman.h" 2 | #include "../kernel/draw.h" 3 | #include "font.h" 4 | #include "drawcall.h" 5 | 6 | static uint32_t* CtxBuff = 0; 7 | static uint32_t CtxW = 0; 8 | static uint32_t CtxH = 0; 9 | 10 | void DrawSetContext(uint32_t* buff, uint32_t w, uint32_t h) 11 | { 12 | CtxBuff = buff; 13 | CtxW = w; 14 | CtxH = h; 15 | } 16 | 17 | void DrawClearFrame() 18 | { 19 | for (int i = 0;i < CtxW * CtxH;i++) 20 | { 21 | CtxBuff[i] = 0; 22 | } 23 | } 24 | 25 | void DrawText(int x, int y, char* text, uint32_t col) 26 | { 27 | for (int i = 0;text[i];i++) 28 | { 29 | uint8_t* ValP = SysFont[text[i]]; 30 | for (int iy = 0;iy < 8;iy++) 31 | { 32 | uint8_t ValY = ValP[iy]; 33 | for (int ix = 0;ix < 8;ix++) 34 | { 35 | int nx = ix + i * 0x8 + x; 36 | int ny = iy + y; 37 | uint8_t Val = (ValY >> ix) & 1; 38 | if (!Val) 39 | { 40 | CtxBuff[(nx + ny * CtxW)] = 0; 41 | continue; 42 | } 43 | if (nx < 0) continue; 44 | if (ny < 0) continue; 45 | if (nx >= CtxW) continue; 46 | if (ny >= CtxH) continue; 47 | CtxBuff[(nx + ny * CtxW)] = col; 48 | } 49 | } 50 | } 51 | } 52 | 53 | void DrawRect(int x, int y, int w, int h, uint32_t col) 54 | { 55 | for (int ny = y;ny < y + h;ny++) 56 | { 57 | for (int nx = x;nx < x + w;nx++) 58 | { 59 | if (nx < 0) continue; 60 | if (ny < 0) continue; 61 | if (nx >= CtxW) continue; 62 | if (ny >= CtxH) continue; 63 | CtxBuff[(nx + ny * CtxW)] = col; 64 | } 65 | } 66 | } 67 | 68 | void DrawPoint(int x, int y, uint32_t col) 69 | { 70 | if (x < 0) return; 71 | if (y < 0) return; 72 | if (x >= CtxW) return; 73 | if (y >= CtxH) return; 74 | CtxBuff[(x + y * CtxW)] = col; 75 | } 76 | 77 | void DrawLine(int x0, int y0, int x1, int y1, uint32_t col) 78 | { 79 | float fx = x0; 80 | float fy = y0; 81 | for (;(int)fx != x1 || (int)fy != y1;fx += ((float)x1 - x0) / CtxW,fy += ((float)y1 - y0) / CtxW) 82 | { 83 | int x = fx; 84 | int y = fy; 85 | if (x < 0) continue; 86 | if (y < 0) continue; 87 | if (x >= CtxW) continue; 88 | if (y >= CtxH) continue; 89 | CtxBuff[(x + y * CtxW)] = col; 90 | } 91 | } 92 | 93 | void DrawImageStencil(int x, int y, int w, int h, uint32_t* img) 94 | { 95 | for (int ny = 0;ny < h;ny++) 96 | { 97 | if (ny + y < 0) continue; 98 | if (ny + y >= CtxH) continue; 99 | for (int nx = 0;nx < w;nx++) 100 | { 101 | if (nx + x < 0) continue; 102 | if (nx + x >= CtxW) continue; 103 | uint32_t col = img[nx + ny * w]; 104 | if (col >> 24) 105 | { 106 | CtxBuff[((x + nx) + (y + ny) * CtxW)] = col; 107 | } 108 | } 109 | } 110 | } 111 | 112 | void DrawUpdate(int x, int y) 113 | { 114 | Draw_Packet Packet; 115 | Packet.imagesSize = 1; 116 | Packet.rectsSize = 0; 117 | Packet.linesSize = 0; 118 | Packet.pointsSize = 0; 119 | Packet.textsSize = 0; 120 | 121 | Draw_ImageEntry Image; 122 | Image.image = CtxBuff; 123 | Image.x = x; 124 | Image.y = y; 125 | Image.w = CtxW; 126 | Image.h = CtxH; 127 | 128 | Packet.images = &Image; 129 | 130 | DrawCall(&Packet); 131 | } 132 | -------------------------------------------------------------------------------- /os/drawman.h: -------------------------------------------------------------------------------- 1 | #ifndef DRAWCALL_H 2 | #define DRAWCALL_H 3 | 4 | #include "include.h" 5 | 6 | volatile void DrawSetContext(uint32_t* buff, uint32_t w, uint32_t h); 7 | volatile void DrawClearFrame(); 8 | volatile void DrawText(int x, int y, char* text, uint32_t col); 9 | volatile void DrawRect(int x, int y, int w, int h, uint32_t col); 10 | volatile void DrawPoint(int x, int y, uint32_t col); 11 | volatile void DrawLine(int x0, int y0, int x1, int y1, uint32_t col); 12 | volatile void DrawImageStencil(int x, int y, int w, int h, uint32_t* img); 13 | volatile void DrawUpdate(int x, int y); 14 | 15 | #endif // DRAWCALL_H -------------------------------------------------------------------------------- /os/filecall.h: -------------------------------------------------------------------------------- 1 | #ifndef FILECALL_H 2 | #define FILECALL_H 3 | 4 | #include "../kernel/file.h" 5 | 6 | extern volatile void ReadFile(char* Dir, FileResponse* Out); 7 | extern volatile void WriteFile(char* Dir, FileRequest* Data); 8 | extern volatile void GetFileSize(char* Dir, size_t* Size); 9 | extern volatile void ListFiles(char* Dir, FileListResponse* Out); 10 | extern volatile void MakeDir(char* Dir); 11 | extern volatile void MakeFile(char* File); 12 | extern volatile void RemoveFileOrDir(char* Any); 13 | 14 | #endif // FILECALL_H -------------------------------------------------------------------------------- /os/font.c: -------------------------------------------------------------------------------- 1 | #include 2 | const char SysFont[0x7F][8] = { 3 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0000 (nul) 4 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0001 5 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0002 6 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0003 7 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0004 8 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0005 9 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0006 10 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0007 11 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0008 12 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0009 13 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000A 14 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000B 15 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000C 16 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000D 17 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000E 18 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+000F 19 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0010 20 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0011 21 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0012 22 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0013 23 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0014 24 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0015 25 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0016 26 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0017 27 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0018 28 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0019 29 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001A 30 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001B 31 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001C 32 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001D 33 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001E 34 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+001F 35 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0020 (space) 36 | { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00 }, // U+0021 (!) 37 | { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0022 (") 38 | { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00 }, // U+0023 (#) 39 | { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00 }, // U+0024 ($) 40 | { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00 }, // U+0025 (%) 41 | { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00 }, // U+0026 (&) 42 | { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0027 (') 43 | { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00 }, // U+0028 (() 44 | { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00 }, // U+0029 ()) 45 | { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00 }, // U+002A (*) 46 | { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00 }, // U+002B (+) 47 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06 }, // U+002C (,) 48 | { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00 }, // U+002D (-) 49 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00 }, // U+002E (.) 50 | { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 }, // U+002F (/) 51 | { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00 }, // U+0030 (0) 52 | { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00 }, // U+0031 (1) 53 | { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00 }, // U+0032 (2) 54 | { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00 }, // U+0033 (3) 55 | { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00 }, // U+0034 (4) 56 | { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00 }, // U+0035 (5) 57 | { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00 }, // U+0036 (6) 58 | { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00 }, // U+0037 (7) 59 | { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00 }, // U+0038 (8) 60 | { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00 }, // U+0039 (9) 61 | { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00 }, // U+003A (:) 62 | { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06 }, // U+003B (;) 63 | { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00 }, // U+003C (<) 64 | { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00 }, // U+003D (=) 65 | { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00 }, // U+003E (>) 66 | { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00 }, // U+003F (?) 67 | { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00 }, // U+0040 (@) 68 | { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00 }, // U+0041 (A) 69 | { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00 }, // U+0042 (B) 70 | { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00 }, // U+0043 (C) 71 | { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00 }, // U+0044 (D) 72 | { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00 }, // U+0045 (E) 73 | { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00 }, // U+0046 (F) 74 | { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00 }, // U+0047 (G) 75 | { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00 }, // U+0048 (H) 76 | { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, // U+0049 (I) 77 | { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00 }, // U+004A (J) 78 | { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00 }, // U+004B (K) 79 | { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00 }, // U+004C (L) 80 | { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00 }, // U+004D (M) 81 | { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00 }, // U+004E (N) 82 | { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00 }, // U+004F (O) 83 | { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00 }, // U+0050 (P) 84 | { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00 }, // U+0051 (Q) 85 | { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00 }, // U+0052 (R) 86 | { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00 }, // U+0053 (S) 87 | { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, // U+0054 (T) 88 | { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00 }, // U+0055 (U) 89 | { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00 }, // U+0056 (V) 90 | { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00 }, // U+0057 (W) 91 | { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00 }, // U+0058 (X) 92 | { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00 }, // U+0059 (Y) 93 | { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00 }, // U+005A (Z) 94 | { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00 }, // U+005B ([) 95 | { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00 }, // U+005C (\) 96 | { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00 }, // U+005D (]) 97 | { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00 }, // U+005E (^) 98 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, // U+005F (_) 99 | { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+0060 (`) 100 | { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00 }, // U+0061 (a) 101 | { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00 }, // U+0062 (b) 102 | { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00 }, // U+0063 (c) 103 | { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00 }, // U+0064 (d) 104 | { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00 }, // U+0065 (e) 105 | { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00 }, // U+0066 (f) 106 | { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F }, // U+0067 (g) 107 | { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00 }, // U+0068 (h) 108 | { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, // U+0069 (i) 109 | { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E }, // U+006A (j) 110 | { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00 }, // U+006B (k) 111 | { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00 }, // U+006C (l) 112 | { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00 }, // U+006D (m) 113 | { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00 }, // U+006E (n) 114 | { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00 }, // U+006F (o) 115 | { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F }, // U+0070 (p) 116 | { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78 }, // U+0071 (q) 117 | { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00 }, // U+0072 (r) 118 | { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00 }, // U+0073 (s) 119 | { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00 }, // U+0074 (t) 120 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00 }, // U+0075 (u) 121 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00 }, // U+0076 (v) 122 | { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00 }, // U+0077 (w) 123 | { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00 }, // U+0078 (x) 124 | { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F }, // U+0079 (y) 125 | { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00 }, // U+007A (z) 126 | { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00 }, // U+007B ({) 127 | { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 }, // U+007C (|) 128 | { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00 }, // U+007D (}) 129 | { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // U+007E (~) 130 | }; -------------------------------------------------------------------------------- /os/font.h: -------------------------------------------------------------------------------- 1 | #ifndef FONT_H 2 | #define FONT_H 3 | #include 4 | 5 | extern const char SysFont[0x7F][8]; 6 | #endif -------------------------------------------------------------------------------- /os/helper.s: -------------------------------------------------------------------------------- 1 | [BITS 64] 2 | 3 | section .helper 4 | 5 | global DrawCall 6 | DrawCall: 7 | push rbx 8 | push rcx 9 | push rsi 10 | mov rbx, 4 11 | mov rsi, rdi 12 | int 0x80 13 | pop rsi 14 | pop rcx 15 | pop rbx 16 | ret 17 | 18 | global GetMS 19 | GetMS: 20 | push rbx 21 | push rcx 22 | push rsi 23 | mov rbx, 5 24 | mov rsi, rdi 25 | int 0x80 26 | pop rsi 27 | pop rcx 28 | pop rbx 29 | ret 30 | 31 | global PollScancode 32 | PollScancode: 33 | push rbx 34 | push rcx 35 | push rsi 36 | mov rbx, 6 37 | mov rsi, rdi 38 | int 0x80 39 | pop rsi 40 | pop rcx 41 | pop rbx 42 | ret 43 | 44 | global _malloc 45 | _malloc: 46 | push rbx 47 | push rcx 48 | push rsi 49 | mov rbx, 1 50 | mov rcx, rsi 51 | mov rsi, rdi 52 | int 0x80 53 | pop rsi 54 | pop rcx 55 | pop rbx 56 | ret 57 | 58 | global _free 59 | _free: 60 | push rbx 61 | push rcx 62 | push rsi 63 | mov rbx, 0 64 | mov rsi, rdi 65 | int 0x80 66 | pop rsi 67 | pop rcx 68 | pop rbx 69 | ret 70 | 71 | global _StartProc 72 | _StartProc: 73 | push rbx 74 | push rcx 75 | push rsi 76 | mov rbx, 2 77 | mov rcx, rsi 78 | mov rsi, rdi 79 | int 0x80 80 | pop rsi 81 | pop rcx 82 | pop rbx 83 | ret 84 | 85 | global _ExitProc 86 | _ExitProc: 87 | mov rbx, 3 88 | int 0x80 89 | 90 | global ReadFile 91 | ReadFile: 92 | push rbx 93 | push rcx 94 | push rsi 95 | mov rbx, 11 96 | mov rcx, rsi 97 | mov rsi, rdi 98 | int 0x80 99 | pop rsi 100 | pop rcx 101 | pop rbx 102 | ret 103 | 104 | global WriteFile 105 | WriteFile: 106 | push rbx 107 | push rcx 108 | push rsi 109 | mov rbx, 10 110 | mov rcx, rsi 111 | mov rsi, rdi 112 | int 0x80 113 | pop rsi 114 | pop rcx 115 | pop rbx 116 | ret 117 | global GetFileSize 118 | GetFileSize: 119 | push rbx 120 | push rcx 121 | push rsi 122 | mov rbx, 12 123 | mov rcx, rsi 124 | mov rsi, rdi 125 | int 0x80 126 | pop rsi 127 | pop rcx 128 | pop rbx 129 | ret 130 | global ListFiles 131 | ListFiles: 132 | push rbx 133 | push rcx 134 | push rsi 135 | mov rbx, 13 136 | mov rcx, rsi 137 | mov rsi, rdi 138 | int 0x80 139 | pop rsi 140 | pop rcx 141 | pop rbx 142 | ret 143 | global MakeDir 144 | MakeDir: 145 | push rbx 146 | push rcx 147 | push rsi 148 | mov rbx, 7 149 | mov rsi, rdi 150 | int 0x80 151 | pop rsi 152 | pop rcx 153 | pop rbx 154 | ret 155 | global MakeFile 156 | MakeFile: 157 | push rbx 158 | push rcx 159 | push rsi 160 | mov rbx, 8 161 | mov rsi, rdi 162 | int 0x80 163 | pop rsi 164 | pop rcx 165 | pop rbx 166 | ret 167 | global RemoveFileOrDir 168 | RemoveFileOrDir: 169 | push rbx 170 | push rcx 171 | push rsi 172 | mov rbx, 9 173 | mov rsi, rdi 174 | int 0x80 175 | pop rsi 176 | pop rcx 177 | pop rbx 178 | ret -------------------------------------------------------------------------------- /os/include.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include -------------------------------------------------------------------------------- /os/log.c: -------------------------------------------------------------------------------- 1 | #include "log.h" 2 | #include "../kernel/draw.h" 3 | #include "drawcall.h" 4 | #include "timer.h" 5 | 6 | static int CurY = 0; 7 | static int CurX = 0; 8 | static Draw_TextEntry LogTextPair[2]; 9 | static bool DoLogging = true; 10 | 11 | void Log(char* Msg, LogSeverity Severity) 12 | { 13 | if (!DoLogging) return; 14 | 15 | Draw_TextEntry text; 16 | text.text = Msg; 17 | text.x = 8 * 21 + CurX; 18 | text.y = CurY; 19 | if (Severity == LOG_SEVERE) text.col = 0x00FF6565; 20 | if (Severity == LOG_WARNING) text.col = 0x00FFAA33; 21 | if (Severity == LOG_INFO) text.col = 0x00FFFFFF; 22 | if (Severity == LOG_SUCCESS) text.col = 0x0065FF65; 23 | 24 | char Buff[200]; 25 | for (int i = 0;i < 200;i++) 26 | { 27 | Buff[i] = ' '; 28 | } 29 | Buff[0] = '['; 30 | Buff[14] = '.'; 31 | Buff[19] = ']'; 32 | Buff[199] = 0; 33 | 34 | float MS; 35 | GetMS(&MS); 36 | 37 | MS /= 1000.0f; 38 | 39 | float Mul = 10.0f; 40 | for (int i = 0;i < 4;i++) 41 | { 42 | int Val = (int)(MS * Mul) % 10; 43 | Buff[i + 15] = '0' + Val; 44 | Mul *= 10.0f; 45 | } 46 | 47 | Mul = 1.0f; 48 | for (int i = 0;i < 7;i++) 49 | { 50 | if ((int)(MS * Mul) == 0) break; 51 | int Val = (int)(MS * Mul) % 10; 52 | Buff[13 - i] = '0' + Val; 53 | Mul /= 10.0f; 54 | } 55 | 56 | Draw_TextEntry textTime; 57 | textTime.text = Buff; 58 | textTime.x = 0; 59 | textTime.y = CurY; 60 | textTime.col = 0xFFFFFF; 61 | 62 | LogTextPair[0] = textTime; 63 | LogTextPair[1] = text; 64 | 65 | Draw_Packet packet; 66 | packet.linesSize = 0; 67 | packet.rectsSize = 0; 68 | packet.pointsSize = 0; 69 | packet.textsSize = 2; 70 | packet.imagesSize = 0; 71 | 72 | packet.texts = LogTextPair; 73 | 74 | DrawCall(&packet); 75 | 76 | CurY += 10; 77 | CurY = CurY % 400; 78 | CurX = 0; 79 | } 80 | 81 | void LogChar(char Char, LogSeverity Severity) 82 | { 83 | if (!DoLogging) return; 84 | 85 | if (Char != '\n') 86 | { 87 | char Buf[2]; 88 | Buf[0] = Char; 89 | Buf[1] = 0; 90 | 91 | Draw_TextEntry text; 92 | text.text = Buf; 93 | text.x = 8 * 21 + CurX; 94 | text.y = CurY; 95 | if (Severity == LOG_SEVERE) text.col = 0x00FF6565; 96 | if (Severity == LOG_WARNING) text.col = 0x00FFAA33; 97 | if (Severity == LOG_INFO) text.col = 0x00FFFFFF; 98 | if (Severity == LOG_SUCCESS) text.col = 0x0065FF65; 99 | 100 | char Buff[200]; 101 | for (int i = 0;i < 200;i++) 102 | { 103 | Buff[i] = ' '; 104 | } 105 | Buff[0] = '['; 106 | Buff[14] = '.'; 107 | Buff[19] = ']'; 108 | Buff[20] = 0; 109 | 110 | float MS; 111 | GetMS(&MS); 112 | 113 | MS /= 1000.0f; 114 | 115 | float Mul = 10.0f; 116 | for (int i = 0;i < 4;i++) 117 | { 118 | int Val = (int)(MS * Mul) % 10; 119 | Buff[i + 15] = '0' + Val; 120 | Mul *= 10.0f; 121 | } 122 | 123 | Mul = 1.0f; 124 | for (int i = 0;i < 7;i++) 125 | { 126 | if ((int)(MS * Mul) == 0) break; 127 | int Val = (int)(MS * Mul) % 10; 128 | Buff[13 - i] = '0' + Val; 129 | Mul /= 10.0f; 130 | } 131 | 132 | Draw_TextEntry textTime; 133 | textTime.text = Buff; 134 | textTime.x = 0; 135 | textTime.y = CurY; 136 | textTime.col = 0xFFFFFF; 137 | 138 | LogTextPair[0] = textTime; 139 | LogTextPair[1] = text; 140 | 141 | Draw_Packet packet; 142 | packet.linesSize = 0; 143 | packet.rectsSize = 0; 144 | packet.pointsSize = 0; 145 | packet.textsSize = 2; 146 | packet.imagesSize = 0; 147 | 148 | packet.texts = LogTextPair; 149 | 150 | DrawCall(&packet); 151 | 152 | CurX += 8; 153 | } 154 | if (Char == '\n') 155 | { 156 | CurX = 0; 157 | CurY += 10; 158 | CurY = CurY % 400; 159 | } 160 | } 161 | 162 | void LogDisable() 163 | { 164 | DoLogging = false; 165 | } 166 | 167 | void LogEnable() 168 | { 169 | DoLogging = true; 170 | } -------------------------------------------------------------------------------- /os/log.h: -------------------------------------------------------------------------------- 1 | #ifndef LOG_H 2 | #define LOG_H 3 | 4 | #include "include.h" 5 | 6 | typedef enum 7 | { 8 | LOG_SEVERE, 9 | LOG_WARNING, 10 | LOG_INFO, 11 | LOG_SUCCESS 12 | } LogSeverity; 13 | 14 | void Log(char* Msg, LogSeverity Severity); 15 | void LogChar(char Char, LogSeverity Severity); 16 | void LogDisable(); 17 | void LogEnable(); 18 | 19 | #endif // LOG_H -------------------------------------------------------------------------------- /os/mem.c: -------------------------------------------------------------------------------- 1 | #include "mem.h" 2 | 3 | extern void _malloc(void** _Ptr, uint64_t _Bytes); 4 | extern void _free(void* _Ptr); 5 | 6 | void* malloc(uint64_t _Bytes) 7 | { 8 | void* _Ptr; 9 | _malloc(&_Ptr, _Bytes); 10 | return _Ptr; 11 | } 12 | 13 | void free(void* _Block) 14 | { 15 | _free(_Block); 16 | } 17 | 18 | void memcpy(void* _Dst, void* _Src, size_t _Bytes) 19 | { 20 | for (size_t i = 0;i < _Bytes;i++) 21 | { 22 | ((char*)_Dst)[i] = ((char*)_Src)[i]; 23 | } 24 | } 25 | 26 | void memset(void* _Dst, char _Val, size_t _Bytes) 27 | { 28 | for (size_t i = 0;i < _Bytes;i++) 29 | { 30 | ((char*)_Dst)[i] = _Val; 31 | } 32 | } -------------------------------------------------------------------------------- /os/mem.h: -------------------------------------------------------------------------------- 1 | #ifndef MEM_H 2 | #define MEM_H 3 | 4 | #include "include.h" 5 | 6 | void* volatile malloc(uint64_t _Bytes); 7 | void volatile free(void* _Block); 8 | void memcpy(void* _Dst, void* _Src, size_t _Bytes); 9 | void memset(void* _Dst, char _Val, size_t _Bytes); 10 | 11 | #endif // MEM_H -------------------------------------------------------------------------------- /os/modules/helpers/bf/bf.h: -------------------------------------------------------------------------------- 1 | #ifndef TOS_BFLANG_H 2 | #define TOS_BFLANG_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "string.h" 9 | #include "linked_list.h" 10 | 11 | typedef enum 12 | { 13 | BFASSIGN, 14 | BFADD, 15 | BFSUB, 16 | BFMUL, 17 | BFDIV, 18 | BFSHR, 19 | BFSHL, 20 | BFMODULO, 21 | BFLESSTHAN, 22 | BFMORETHAN, 23 | BFEQUALS, 24 | BFFUNCCALL, 25 | BFRETURN, 26 | BFIF, 27 | BFWHILE, 28 | BFFOR, 29 | BFPRINT, 30 | BFMEMBERACCESS, 31 | BFCAST, 32 | BFUNKNOWN 33 | } bf_token_type; 34 | 35 | typedef struct { 36 | uint8_t* Name; 37 | size_t Len; 38 | } bf_name; 39 | 40 | typedef enum { 41 | BFBITS8 = 8, 42 | BFBITS16 = 16, 43 | BFBITS32 = 32 44 | } bf_bits; 45 | 46 | struct _bf_token; 47 | 48 | typedef struct _bf_type { 49 | bool IsStruct; 50 | bool IsFloat; 51 | LinkedList StructMembers; 52 | void* ArrData; 53 | struct _bf_token* ArrSize; // if 0, not an array 54 | bf_bits Bits; 55 | String Name; 56 | } bf_type; 57 | 58 | typedef struct _bf_member { 59 | bf_type Type; 60 | String Name; 61 | } bf_member; 62 | 63 | typedef struct _bf_type_name { 64 | String Name; 65 | bf_type Type; 66 | } bf_type_name; 67 | 68 | typedef struct { 69 | bool isReturn; 70 | bf_type type; 71 | float floatVal; 72 | char byteVal; 73 | int16_t shortVal; 74 | int32_t intVal; 75 | void* assignDest; // only for array indexing 76 | } bf_constant; 77 | 78 | typedef struct { 79 | bf_constant Val; 80 | bf_name Name; 81 | bf_type Type; 82 | bool Ref; 83 | } bf_variable; 84 | 85 | 86 | 87 | typedef struct _bf_scope { 88 | LinkedList Lines; 89 | bf_variable** Vars; // First vars are the arguments... 90 | size_t ArgsCount; 91 | size_t VarsCount; 92 | struct _bf_scope* Parent; 93 | } bf_scope; 94 | 95 | typedef struct { 96 | bf_scope RootScope; 97 | bf_name Name; 98 | bf_type Type; 99 | LinkedList Params; 100 | } bf_function; 101 | 102 | typedef struct _bf_token { 103 | bf_token_type Type; 104 | bf_variable* Var; 105 | bool IsFinalMember; 106 | bf_member* Member; 107 | bf_constant Const; 108 | struct _bf_token** Params; 109 | size_t NumParams; 110 | struct _bf_token* First; 111 | struct _bf_token* Second; 112 | struct _bf_token* Third; 113 | bf_type CastTo; 114 | bf_scope* NextScope; 115 | bf_function* CallFunction; 116 | bool IsConstant; 117 | bool IsVar; 118 | int Val; 119 | } bf_token; 120 | 121 | typedef struct 122 | { 123 | uint8_t* Code; 124 | size_t Size; 125 | size_t At; 126 | bf_function** Functions; 127 | size_t BFNumFunctions; 128 | LinkedList Types; 129 | } bf_tokenizer; 130 | 131 | typedef struct 132 | { 133 | bf_type Type; 134 | } bf_compiled_token; 135 | 136 | bf_constant BFRunSource(String Code); 137 | 138 | #endif -------------------------------------------------------------------------------- /os/modules/helpers/bf/linked_list.c: -------------------------------------------------------------------------------- 1 | #include "linked_list.h" 2 | 3 | LinkedList LinkedListCreate(size_t elemSize) 4 | { 5 | LinkedList list; 6 | list.data = malloc(elemSize * 256); 7 | list.elemSize = elemSize; 8 | list.size = 0; 9 | return list; 10 | } 11 | 12 | void LinkedListPushBack(LinkedList* me, void* val) 13 | { 14 | if ((me->size % 256) == 255) 15 | { 16 | void* new = malloc(me->size * me->elemSize + 1 + 256); 17 | memcpy(new, me->data, me->size * me->elemSize); 18 | free(me->data); 19 | me->data = new; 20 | } 21 | memcpy(me->data + me->elemSize * (me->size++), val, me->elemSize); 22 | } 23 | 24 | void LinkedListPopBack(LinkedList* me) 25 | { 26 | if (me->size == 0) 27 | { 28 | return; 29 | } 30 | me->size--; 31 | } 32 | 33 | void* LinkedListGet(LinkedList* me, int I) 34 | { 35 | return me->data + me->elemSize * I; 36 | } -------------------------------------------------------------------------------- /os/modules/helpers/bf/linked_list.h: -------------------------------------------------------------------------------- 1 | #ifndef H_LINKED_LIST 2 | #define H_LINKED_LIST 3 | 4 | #include 5 | #include 6 | #include "../../../mem.h" 7 | 8 | typedef struct 9 | { 10 | void* data; 11 | size_t elemSize; 12 | size_t size; 13 | } LinkedList; 14 | 15 | LinkedList LinkedListCreate(size_t elemSize); 16 | void LinkedListPushBack(LinkedList* me, void* val); 17 | void LinkedListPopBack(LinkedList* me); 18 | void* LinkedListGet(LinkedList* me, int I); 19 | 20 | #endif // H_LINKED_LIST -------------------------------------------------------------------------------- /os/modules/helpers/bf/string.c: -------------------------------------------------------------------------------- 1 | #include "string.h" 2 | 3 | String StrFromCStr(const char *str) 4 | { 5 | int size = 0; 6 | char* tmp = str; 7 | while (*tmp) 8 | { 9 | size++; 10 | tmp++; 11 | } 12 | 13 | String out; 14 | out.data = malloc(size); 15 | out.size = size; 16 | memcpy(out.data, str, size); 17 | return out; 18 | } 19 | 20 | String StrFromArray(char *str, size_t size) 21 | { 22 | String out; 23 | out.data = malloc(size); 24 | out.size = size; 25 | memcpy(out.data, str, size); 26 | return out; 27 | } 28 | 29 | String StrAppend(String x, String y) 30 | { 31 | String out; 32 | out.data = malloc(x.size + y.size); 33 | memcpy(out.data, x.data, x.size); 34 | memcpy(out.data + x.size, y.data, y.size); 35 | out.size = x.size + y.size; 36 | return out; 37 | } 38 | 39 | bool StrStartsWith(String str, String startswith) 40 | { 41 | if (startswith.size > str.size) 42 | return false; 43 | for (int i = 0; i < str.size; i++) 44 | { 45 | if (str.data[i] == ' ') 46 | return true; 47 | if (str.data[i] != startswith.data[i]) 48 | return false; 49 | } 50 | return true; 51 | } 52 | 53 | bool StrEqualsWith(String x, String y) 54 | { 55 | if (x.size != y.size) 56 | return false; 57 | for (int i = 0; i < x.size; i++) 58 | { 59 | if (x.data[i] != y.data[i]) 60 | return false; 61 | } 62 | return true; 63 | } 64 | 65 | bool CStrEqualsWith(char* x, size_t xSize, char* y, size_t ySize) 66 | { 67 | if (xSize != ySize) return false; 68 | while (xSize--) 69 | { 70 | if (x[xSize] != y[ySize]) return false; 71 | } 72 | return true; 73 | } 74 | 75 | bool StrHas(String str, char what) 76 | { 77 | for (int I = 0;I < str.size;I++) 78 | { 79 | if (str.data[I] == what) return true; 80 | } 81 | return false; 82 | } 83 | 84 | String NewStr() 85 | { 86 | String out; 87 | out.size = 0; 88 | out.data = malloc(256); 89 | return out; 90 | } 91 | void StrPushBack(String* str, char c) 92 | { 93 | 94 | if ((str->size % 256) == 255) 95 | { 96 | void* new = malloc(str->size + 1 + 256); 97 | memcpy(new, str->data, str->size); 98 | free(str->data); 99 | str->data = new; 100 | } 101 | str->data[str->size++] = c; 102 | } -------------------------------------------------------------------------------- /os/modules/helpers/bf/string.h: -------------------------------------------------------------------------------- 1 | #ifndef H_STRING 2 | #define H_STRING 3 | 4 | #include 5 | #include 6 | #include "linked_list.h" 7 | 8 | typedef struct 9 | { 10 | char* data; 11 | size_t size; 12 | } String; 13 | 14 | String NewStr(); 15 | void StrPushBack(String* str, char c); 16 | String StrFromCStr(const char* str); 17 | String StrFromArray(char* str, size_t size); 18 | bool StrStartsWith(String str, String startswith); 19 | bool StrHas(String str, char what); 20 | bool StrEqualsWith(String x, String y); 21 | bool CStrEqualsWith(char* x, size_t xSize, char* y, size_t ySize); 22 | String StrAppend(String x, String y); 23 | 24 | #endif // H_STRING -------------------------------------------------------------------------------- /os/modules/helpers/shell.c: -------------------------------------------------------------------------------- 1 | #include "shell.h" 2 | #include "../../filecall.h" 3 | #include "../../drawman.h" 4 | #include "../../proc.h" 5 | #include "../../log.h" 6 | #include "bf/bf.h" 7 | 8 | void ShellCmd_Ls(ShellContext* Ctx, char* Dir) 9 | { 10 | Ctx->ScanY++; 11 | FileListResponse Response; 12 | ListFiles(Dir, &Response); 13 | for (int i = 0;i < Response.NumEntries;i++) 14 | { 15 | DrawText(0, (Ctx->ScanY++) * 8, Response.Data[i].Name, Response.Data[i].IsDir ? 0xFF00FF00 : 0xFF3333FF); 16 | } 17 | } 18 | 19 | bool IsCharacter(char C) 20 | { 21 | return C >= 32 || C == '\n' || C == '\t'; 22 | } 23 | 24 | void ShellCmd_Cat(ShellContext* Ctx, char* Dir) 25 | { 26 | Ctx->ScanY++; 27 | FileResponse Response; 28 | ReadFile(Dir, &Response); 29 | if (Response.Data == 0) return; 30 | int CharsPrinted = 0; 31 | for (int i = 0;i < Response.BytesRead;i++) 32 | { 33 | if (IsCharacter(((char*)Response.Data)[i])) 34 | { 35 | CharsPrinted++; 36 | char Buf[2]; 37 | Buf[0] = ((char*)Response.Data)[i]; 38 | Buf[1] = 0; 39 | if (Buf[0] == '\n') 40 | { 41 | Ctx->ScanY++; 42 | CharsPrinted = 0; 43 | } 44 | else if (Buf[0] == '\t') 45 | { 46 | CharsPrinted += 4; 47 | } 48 | else 49 | { 50 | DrawText(((CharsPrinted - 1) % 256) * 8, Ctx->ScanY * 8, Buf, 0xFFFFFFFF); 51 | if (CharsPrinted % 256 == 0) Ctx->ScanY++; 52 | } 53 | } 54 | } 55 | free(Response.Data); 56 | Ctx->ScanY++; 57 | } 58 | 59 | void ShellCmd_Write(ShellContext* Ctx, char* Dir) 60 | { 61 | Ctx->ScanY++; 62 | 63 | int DirSize = 0; 64 | while (Dir[DirSize] && Dir[DirSize] != ' ') DirSize++; 65 | char Old = Dir[DirSize]; 66 | Dir[DirSize] = 0; 67 | if (Old == 0) DirSize--; 68 | 69 | int Bytes = 0; 70 | while (Dir[DirSize + 1 + Bytes]) Bytes++; 71 | 72 | FileRequest Request; 73 | Request.Bytes = Bytes; 74 | Request.Data = Dir + DirSize + 1; 75 | WriteFile(Dir, &Request); 76 | } 77 | 78 | void ShellCmd_Mkdir(ShellContext* Ctx, char* Dir) 79 | { 80 | Ctx->ScanY++; 81 | MakeDir(Dir); 82 | } 83 | void ShellCmd_Touch(ShellContext* Ctx, char* Dir) 84 | { 85 | Ctx->ScanY++; 86 | MakeFile(Dir); 87 | } 88 | 89 | static FileResponse BFResponse; 90 | 91 | void _BFHandler() 92 | { 93 | Log("Running BF file...", LOG_INFO); 94 | BFRunSource(StrFromArray(BFResponse.Data, BFResponse.BytesRead)); 95 | //ExitProc(); 96 | } 97 | 98 | void ShellCmd_Bf(ShellContext* Ctx, char* Dir) 99 | { 100 | Ctx->ScanY++; 101 | FileResponse Response; 102 | ReadFile(Dir, &Response); 103 | if (Response.Data == 0) return; 104 | BFResponse = Response; 105 | 106 | _BFHandler(); 107 | //StartProc(_BFHandler, 0x40000ULL | 0x100000000ULL); 108 | } 109 | void ShellCmd_Rm(ShellContext* Ctx, char* Dir) 110 | { 111 | Ctx->ScanY++; 112 | RemoveFileOrDir(Dir); 113 | } 114 | void ShellCmdNotFound(ShellContext* Ctx) 115 | { 116 | Ctx->ScanY++; 117 | DrawText(0, (Ctx->ScanY++) * 8, "Command not found", 0xFFFFAAAA); 118 | } 119 | static uint32_t Random(uint32_t seed) 120 | { 121 | return seed * 1664525 + 1013904223; 122 | } 123 | // returns next X coordinate 124 | static int PrintInt(ShellContext* Ctx, int num, int x) 125 | { 126 | int NumLen = 0; 127 | int Temp = num; 128 | // quick and lazy 129 | do {NumLen++;} while (Temp /= 10); 130 | 131 | char Buf[2]; 132 | Buf[1] = 0; 133 | Temp = NumLen; 134 | do 135 | { 136 | Buf[0] = '0' + (num % 10); 137 | DrawText(x + (--NumLen) * 8, Ctx->ScanY * 8, Buf, 0xFFFFFFFF); 138 | } while (num /= 10); 139 | return x + Temp * 8; 140 | } 141 | void ShellCmd_Gamble(ShellContext* Ctx, char* Params) 142 | { 143 | FileResponse res; 144 | ReadFile("sys/gamble.conf", &res); 145 | if (!res.Data) 146 | { 147 | MakeFile("sys/gamble.conf"); 148 | FileRequest req; 149 | const int StartBalance = 100; 150 | const uint32_t StartRandSeed = 6439857843; 151 | int Store[2]; 152 | Store[0] = StartBalance; 153 | Store[1] = StartRandSeed; 154 | req.Data = Store; 155 | req.Bytes = 8; 156 | WriteFile("sys/gamble.conf", &req); 157 | ReadFile("sys/gamble.conf", &res); 158 | } 159 | 160 | int balance = ((int*)res.Data)[0]; 161 | uint32_t randseed = ((uint32_t*)res.Data)[1]; 162 | free(res.Data); 163 | balance -= 10; 164 | 165 | Ctx->ScanY++; 166 | DrawText(0, (Ctx->ScanY) * 8, "Your balance is now: ", 0xFFFFFFFF); 167 | int NextX = PrintInt(Ctx, balance, 22 * 8); 168 | DrawText(NextX, (Ctx->ScanY++) * 8, "$ (-10$)", 0xFFFFFFFF); 169 | DrawText(0, (Ctx->ScanY++) * 8, "|WEAR |WEAPON |SKIN |STATTRAK", 0xFFFFFFFF); 170 | 171 | // Wear 172 | uint32_t newseed = Random(randseed); 173 | randseed = newseed; 174 | newseed %= 1000; 175 | if (newseed < 4) DrawText(0, (Ctx->ScanY) * 8, "|FACNEW", 0xFFFFFFFF); 176 | else if (newseed < 50) DrawText(0, (Ctx->ScanY) * 8, "|MINWEAR", 0xFFFFFFFF); 177 | else if (newseed < 300) DrawText(0, (Ctx->ScanY) * 8, "|TESTED", 0xFFFFFFFF); 178 | else DrawText(0, (Ctx->ScanY) * 8, "|BATSCAR", 0xFFFFFFFF); 179 | /* 180 | // Weapon 181 | 182 | */ 183 | const char* weapons[9] = { 184 | "|AK-47", 185 | "|M4A4", 186 | "|M4A1-S", 187 | "|USP-S", 188 | "|GLOCK", 189 | "|AWP", 190 | "|SSG", 191 | "|SCAR-50", 192 | "|MP5" 193 | }; 194 | 195 | const char* knives[4] = { 196 | "|GutKnif", 197 | "|Bayonet", 198 | "|Karamb ", 199 | "|Talon" 200 | }; 201 | 202 | newseed = Random(randseed); 203 | randseed = newseed; 204 | if (newseed % 100 == 0) 205 | { 206 | // Knife 207 | newseed %= 4; 208 | DrawText(8 * 8, (Ctx->ScanY) * 8, knives[newseed], 0xFFFFFF00); 209 | } 210 | else 211 | { 212 | newseed %= 9; 213 | DrawText(8 * 8, (Ctx->ScanY) * 8, weapons[newseed], 0xFF777777); 214 | } 215 | 216 | // Skin 217 | 218 | const char* skins[7] = { 219 | "|DDPAT", 220 | "|Safari", 221 | "|Doppler", 222 | "|Camo", 223 | "|Gamma", 224 | "|Lore", 225 | "|Dragon" 226 | }; 227 | 228 | newseed = Random(randseed); 229 | randseed = newseed; 230 | newseed %= 7; 231 | DrawText(16 * 8, (Ctx->ScanY) * 8, skins[newseed], 0xFFFFFFFF); 232 | 233 | // Stattrak 234 | 235 | newseed = Random(randseed); 236 | randseed = newseed; 237 | 238 | if (newseed % 10 == 0) 239 | { 240 | DrawText(24 * 8, (Ctx->ScanY) * 8, "Stattrak", 0xFF00FF00); 241 | } 242 | else 243 | { 244 | DrawText(24 * 8, (Ctx->ScanY) * 8, "No", 0xFFFF7777); 245 | } 246 | Ctx->ScanY++; 247 | 248 | FileRequest req; 249 | int Store[2]; 250 | Store[0] = balance; 251 | Store[1] = randseed; 252 | req.Data = Store; 253 | req.Bytes = 8; 254 | WriteFile("sys/gamble.conf", &req); 255 | } 256 | bool ShellStrcmp(char* x, char* y) 257 | { 258 | int xlen = 0, ylen = 0; 259 | while (x[xlen] && x[xlen] != ' ') xlen++; 260 | while (y[ylen] && x[ylen] != ' ') ylen++; 261 | 262 | if (xlen != ylen) return false; 263 | 264 | for (int i = 0;i < xlen;i++) 265 | { 266 | if (x[i] != y[i]) return false; 267 | } 268 | return true; 269 | } 270 | void ShellProcessCommand(char* Cmd, ShellContext* Ctx) 271 | { 272 | int CmdSize = 0; 273 | while (Cmd[CmdSize] && Cmd[CmdSize] != ' ') CmdSize++; 274 | if (Cmd[CmdSize] == 0) CmdSize--; 275 | if (ShellStrcmp(Cmd, "ls")) ShellCmd_Ls(Ctx, Cmd + CmdSize + 1); 276 | else if (ShellStrcmp(Cmd, "rm")) ShellCmd_Rm(Ctx, Cmd + CmdSize + 1); 277 | else if (ShellStrcmp(Cmd, "mkdir")) ShellCmd_Mkdir(Ctx, Cmd + CmdSize + 1); 278 | else if (ShellStrcmp(Cmd, "touch")) ShellCmd_Touch(Ctx, Cmd + CmdSize + 1); 279 | else if (ShellStrcmp(Cmd, "write")) ShellCmd_Write(Ctx, Cmd + CmdSize + 1); 280 | else if (ShellStrcmp(Cmd, "cat")) ShellCmd_Cat(Ctx, Cmd + CmdSize + 1); 281 | else if (ShellStrcmp(Cmd, "bf")) ShellCmd_Bf(Ctx, Cmd + CmdSize + 1); 282 | else if (ShellStrcmp(Cmd, "gamble")) ShellCmd_Gamble(Ctx, Cmd + CmdSize + 1); 283 | else ShellCmdNotFound(Ctx); 284 | } -------------------------------------------------------------------------------- /os/modules/helpers/shell.h: -------------------------------------------------------------------------------- 1 | #ifndef SHELL_H 2 | #define SHELL_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef struct 9 | { 10 | char Directory[512]; 11 | int ScanY; 12 | } ShellContext; 13 | 14 | void ShellProcessCommand(char* Cmd, ShellContext* Ctx); 15 | 16 | #endif // SHELL_H -------------------------------------------------------------------------------- /os/modules/keyboard.c: -------------------------------------------------------------------------------- 1 | #include "keyboard.h" 2 | #include "../log.h" 3 | #include "../mem.h" 4 | 5 | KeyboardKey* KeyEventQueue = 0; 6 | size_t KeyEventQueueIdx = 0; 7 | Keyboard* KeyboardState = 0; 8 | 9 | extern void PollScancode(uint8_t* Out); 10 | 11 | static char TransLo[128] = 12 | { 13 | 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, '\t', 14 | 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 15 | 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 16 | 'b', 'n', 'm', ',', '.', '/', 0, 0, 0, ' ' 17 | }; 18 | 19 | static char TransHi[128] = 20 | { 21 | 0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, '\t', 22 | 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', 23 | 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', 24 | 'B', 'N', 'M', '<', '>', '?', 0, 0, 0, ' ' 25 | }; 26 | 27 | uint8_t TransformScancode(uint8_t Scancode) { 28 | if (Scancode >= 128) return 0; 29 | uint8_t tl = TransLo[Scancode]; 30 | 31 | if (KeyboardState->LShift || KeyboardState->RShift) 32 | { 33 | if (KeyboardState->CapsLock && tl >= 'a' && tl <= 'z') 34 | { 35 | return tl; 36 | } 37 | return TransHi[Scancode]; 38 | } 39 | if (KeyboardState->CapsLock && tl >= 'a' && tl <= 'z') 40 | { 41 | return TransHi[Scancode]; 42 | } 43 | return TransLo[Scancode]; 44 | } 45 | 46 | static void ProcessScancode(uint8_t Scancode) 47 | { 48 | uint8_t Alternative = 0; 49 | 50 | if (Scancode == 0xE0) 51 | { 52 | Alternative = 1; 53 | PollScancode(&Scancode); 54 | } 55 | 56 | uint8_t Released = Scancode >= 128; 57 | if (Released) Scancode -= 128; 58 | if (Alternative) Scancode += 128; 59 | 60 | switch (Scancode) 61 | { 62 | case KEY_LSHIFT: case KEY_FKLSHIFT: 63 | KeyboardState->LShift = !Released; 64 | break; 65 | case KEY_RSHIFT: case KEY_FKRSHIFT: 66 | KeyboardState->RShift = !Released; 67 | break; 68 | case KEY_LCTRL: KeyboardState->LCtrl = !Released; break; 69 | case KEY_RCTRL: KeyboardState->RCtrl = !Released; break; 70 | case KEY_LALT: KeyboardState->LAlt = !Released; break; 71 | case KEY_RALT: KeyboardState->RAlt = !Released; break; 72 | case KEY_CAPS_LOCK: if (!Released) KeyboardState->CapsLock = KeyboardState->CapsLock; break; 73 | 74 | case 0: return; 75 | } 76 | 77 | 78 | KeyEventQueue[KeyEventQueueIdx++] = (KeyboardKey) 79 | { 80 | 1, 81 | KeyboardState->CapsLock, 82 | KeyboardState->LShift, 83 | KeyboardState->RShift, 84 | KeyboardState->LCtrl, 85 | KeyboardState->RCtrl, 86 | KeyboardState->LAlt, 87 | KeyboardState->RAlt, 88 | KeyboardState->LShift || KeyboardState->RShift, 89 | KeyboardState->LCtrl || KeyboardState->RCtrl, 90 | KeyboardState->LAlt || KeyboardState->RAlt, 91 | Released, Scancode, 92 | TransformScancode(Scancode), 93 | Scancode < 128 ? TransLo[Scancode] : 0 94 | }; 95 | if (KeyEventQueueIdx >= KEYBOARD_QUEUE_SIZE) KeyEventQueueIdx = KEYBOARD_QUEUE_SIZE - 1; 96 | Alternative = 0; 97 | } 98 | 99 | void StartKeyboard() 100 | { 101 | Log("Keyboard started", LOG_SUCCESS); 102 | 103 | KeyEventQueue = (KeyboardKey*)malloc(sizeof(KeyboardKey) * KEYBOARD_QUEUE_SIZE); 104 | KeyboardState = (Keyboard*)malloc(sizeof(Keyboard)); 105 | KeyEventQueueIdx = 0; 106 | KeyboardState->CapsLock = 0; 107 | KeyboardState->LAlt = 0; 108 | KeyboardState->LCtrl = 0; 109 | KeyboardState->LShift = 0; 110 | KeyboardState->RAlt = 0; 111 | KeyboardState->RCtrl = 0; 112 | KeyboardState->RShift = 0; 113 | while (1) 114 | { 115 | uint8_t Scancode; 116 | PollScancode(&Scancode); 117 | if (Scancode != 0) 118 | { 119 | ProcessScancode(Scancode); 120 | } 121 | } 122 | } 123 | 124 | KeyboardKey KeyboardPollKey() 125 | { 126 | if (KeyEventQueueIdx == 0) return (KeyboardKey){ 0 }; 127 | KeyboardKey Key = KeyEventQueue[0]; 128 | for (int i = 0;i < KEYBOARD_QUEUE_SIZE - 1;i++) 129 | { 130 | KeyEventQueue[i] = KeyEventQueue[i + 1]; 131 | } 132 | KeyEventQueueIdx--; 133 | return Key; 134 | } -------------------------------------------------------------------------------- /os/modules/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef KEYBOARD_H 2 | #define KEYBOARD_H 3 | 4 | #include "../include.h" 5 | 6 | #define KEYBOARD_QUEUE_SIZE 32 7 | 8 | 9 | #define KEY_ESC 0x01 10 | #define KEY_BACKSPACE 0x0E 11 | #define KEY_LCTRL 0x1D 12 | #define KEY_RCTRL 0x1D+128 13 | #define KEY_LSHIFT 0x2A 14 | #define KEY_RSHIFT 0x36 15 | #define KEY_FKLSHIFT 0x2A+128 16 | #define KEY_FKRSHIFT 0x36+128 17 | #define KEY_CAPS_LOCK 0x3A 18 | #define KEY_LALT 0x38 19 | #define KEY_RALT 0x38+128 20 | #define KEY_LEFT 0x4B+128 21 | #define KEY_RIGHT 0x4D+128 22 | #define KEY_UP 0x48+128 23 | #define KEY_DOWN 0x50+128 24 | 25 | typedef struct { 26 | uint8_t CapsLock; 27 | uint8_t LShift; 28 | uint8_t RShift; 29 | uint8_t LCtrl; 30 | uint8_t RCtrl; 31 | uint8_t LAlt; 32 | uint8_t RAlt; 33 | } Keyboard; 34 | 35 | typedef struct { 36 | uint8_t Valid; 37 | uint8_t CapsLock; 38 | uint8_t LShift; 39 | uint8_t RShift; 40 | uint8_t LCtrl; 41 | uint8_t RCtrl; 42 | uint8_t LAlt; 43 | uint8_t RAlt; 44 | uint8_t Shift, Ctrl, Alt; 45 | uint8_t Released; 46 | uint8_t Scancode; 47 | uint8_t ASCII; 48 | uint8_t ASCIIOriginal; 49 | } KeyboardKey; 50 | 51 | extern KeyboardKey* KeyEventQueue; 52 | extern size_t KeyEventQueueIdx; 53 | extern Keyboard* KeyboardState; 54 | 55 | void StartKeyboard(); 56 | volatile KeyboardKey KeyboardPollKey(); 57 | 58 | #endif // KEYBOARD_H -------------------------------------------------------------------------------- /os/modules/winman.c: -------------------------------------------------------------------------------- 1 | #include "winman.h" 2 | #include "keyboard.h" 3 | #include "../drawman.h" 4 | #include "helpers/shell.h" 5 | 6 | uint32_t* BackBuffer; 7 | 8 | static int CmdLen = 0; 9 | 10 | static char CurCmd[256] = { 0 }; 11 | 12 | static char* CurCmdPrefix = "> "; 13 | 14 | static int CurY = 0; 15 | 16 | void EventHandling() 17 | { 18 | KeyboardKey Key; 19 | Key = KeyboardPollKey(); 20 | while (Key.Valid) 21 | { 22 | if (!Key.Released) 23 | { 24 | if (Key.Scancode == KEY_BACKSPACE) 25 | { 26 | CmdLen--; 27 | if (CmdLen < 0) CmdLen = 0; 28 | CurCmd[CmdLen] = 0; 29 | } 30 | else if (Key.ASCII) 31 | { 32 | if (Key.ASCII == '\n') 33 | { 34 | CurY++; 35 | } 36 | else if (CmdLen < 255) 37 | { 38 | CurCmd[CmdLen] = Key.ASCII; 39 | CmdLen++; 40 | } 41 | } 42 | } 43 | Key = KeyboardPollKey(); 44 | } 45 | } 46 | 47 | void NewFrame(ShellContext* ShellCtx) 48 | { 49 | float Ms; 50 | GetMS(&Ms); 51 | 52 | DrawRect(0, 0, 1920, 1, 0xFFFFFFFF); 53 | 54 | int OldY = CurY; 55 | EventHandling(); 56 | CurY %= 100; 57 | DrawRect(0, CurY * 8, 1920, 8, 0xFF000000); 58 | DrawText(0, OldY * 8, CurCmdPrefix, 0xFFFFFFFF); 59 | DrawText(8 * 3, OldY * 8, CurCmd, 0xFFFFFFFF); 60 | if (OldY != CurY) 61 | { 62 | ShellCtx->ScanY = OldY; 63 | ShellProcessCommand(CurCmd, ShellCtx); 64 | CurY = ShellCtx->ScanY; 65 | CmdLen = 0; 66 | for (int i = 0;i < 256;i++) CurCmd[i] = 0; 67 | } 68 | } 69 | 70 | void WMPrintStr(char* Str) 71 | { 72 | Log(Str, LOG_WARNING); 73 | } 74 | 75 | void WMPrintChar(char Char) 76 | { 77 | LogChar(Char, LOG_INFO); 78 | } 79 | 80 | void StartWindowManager() 81 | { 82 | BackBuffer = (uint32_t*)malloc(1920 * (1080 - 200) * 4); 83 | 84 | DrawSetContext(BackBuffer, 1920, 1080 - 200); 85 | DrawClearFrame(); 86 | 87 | Log("Window manager started", LOG_SUCCESS); 88 | 89 | ShellContext ShellCtx; 90 | 91 | while (1) 92 | { 93 | NewFrame(&ShellCtx); 94 | 95 | DrawUpdate(0, 400); 96 | } 97 | 98 | ExitProc(); 99 | } -------------------------------------------------------------------------------- /os/modules/winman.h: -------------------------------------------------------------------------------- 1 | #ifndef WINMAN_H 2 | #define WINMAN_H 3 | 4 | #include "../include.h" 5 | #include "../log.h" 6 | #include "../proc.h" 7 | #include "../mem.h" 8 | #include "../timer.h" 9 | 10 | void StartWindowManager(); 11 | 12 | #endif // WINMAN_H -------------------------------------------------------------------------------- /os/os.c: -------------------------------------------------------------------------------- 1 | #include "include.h" 2 | #include "log.h" 3 | #include "proc.h" 4 | #include "filecall.h" 5 | #include "mem.h" 6 | #include "timer.h" 7 | 8 | // MODULE INCLUDES 9 | #include "modules/winman.h" 10 | #include "modules/keyboard.h" 11 | 12 | volatile void __attribute__((section(".startos"))) main() 13 | { 14 | for (int i = 0;i < 0x50000;i++) 15 | { 16 | *(volatile uint8_t*)(0xB50000 + i) = 0; 17 | } 18 | 19 | Log("Starting keyboard...", LOG_INFO); 20 | StartProc((uint64_t)StartKeyboard, 0x40000ULL | 0x100000000ULL); 21 | 22 | Log("Starting window manager...", LOG_INFO); 23 | StartProc((uint64_t)StartWindowManager, 0x40000ULL | 0x100000000ULL); 24 | 25 | Log("Welcome to this OS!", LOG_SUCCESS); 26 | 27 | while (1) 28 | { 29 | 30 | } 31 | } -------------------------------------------------------------------------------- /os/proc.c: -------------------------------------------------------------------------------- 1 | #include "proc.h" 2 | #include "timer.h" 3 | 4 | extern volatile void _StartProc(uint64_t, uint64_t); 5 | extern volatile void _ExitProc(); 6 | 7 | void StartProc(uint64_t Addr, uint64_t Size) 8 | { 9 | _StartProc(Addr, Size); 10 | } 11 | 12 | 13 | void ExitProc(uint64_t Addr, uint64_t Size) 14 | { 15 | _ExitProc(); 16 | } -------------------------------------------------------------------------------- /os/proc.h: -------------------------------------------------------------------------------- 1 | #ifndef PROC_H 2 | #define PROC_H 3 | 4 | #include "include.h" 5 | 6 | void StartProc(uint64_t Addr, uint64_t Size); 7 | void ExitProc(); 8 | 9 | #endif // PROC_H 10 | -------------------------------------------------------------------------------- /os/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef TIMER_H 2 | #define TIMER_H 3 | 4 | volatile extern void GetMS(void*); 5 | 6 | #endif // TIMER_H -------------------------------------------------------------------------------- /run.bat: -------------------------------------------------------------------------------- 1 | qemu-system-x86_64 -hda bin/boot.img -drive file=bin/storage.disk,format=raw,if=none,id=nvm -device nvme,serial=deadbeef,id=nvme-ctrl-0 -device nvme-ns,drive=nvm,nsid=1 -m 4G -smp 1 -device qemu-xhci -device usb-mouse --------------------------------------------------------------------------------