├── .gitignore ├── software ├── shell │ ├── config.asm │ ├── data.asm │ └── prompt.asm ├── free │ └── data.asm ├── hello.asm ├── console │ ├── config.asm │ ├── init.asm │ └── data.asm ├── console.asm ├── shell.asm └── free.asm ├── kernel ├── init │ ├── serial.asm │ ├── ipc.asm │ ├── apic.asm │ ├── boot.asm │ ├── video.asm │ ├── network.asm │ ├── task.asm │ ├── rtc.asm │ ├── storage.asm │ ├── idt.asm │ ├── multiboot.asm │ ├── services.asm │ ├── vfs.asm │ ├── page.asm │ ├── smp.asm │ ├── memory.asm │ ├── ap.asm │ ├── gdt.asm │ ├── ps2.asm │ ├── long_mode.asm │ ├── data.asm │ └── acpi.asm ├── service │ ├── visual │ │ ├── gfx │ │ │ └── cursor.data │ │ ├── sleep.asm │ │ ├── panic.asm │ │ ├── cursor.asm │ │ ├── keyboard.asm │ │ ├── init.asm │ │ ├── ipc.asm │ │ ├── service.asm │ │ ├── config.asm │ │ ├── data.asm │ │ ├── event.asm │ │ ├── fill.asm │ │ └── zone.asm │ ├── date │ │ ├── event.asm │ │ ├── ipc.asm │ │ ├── config.asm │ │ ├── clock.asm │ │ ├── ipc │ │ │ ├── desu.asm │ │ │ └── render.asm │ │ ├── data.asm │ │ ├── init.asm │ │ └── taskbar.asm │ ├── date.asm │ ├── network │ │ ├── data.asm │ │ ├── checksum.asm │ │ ├── arp.asm │ │ ├── icmp.asm │ │ └── wrap.asm │ ├── tx.asm │ ├── render.asm │ ├── tresher.asm │ ├── http.asm │ └── network.asm ├── macro │ ├── debug.asm │ ├── lock.asm │ ├── apic.asm │ └── copy.asm ├── panic.asm ├── io_apic.asm ├── data.asm ├── apic.asm ├── thread.asm ├── init.asm ├── kernel.asm ├── idt.asm ├── driver │ ├── rtc.asm │ ├── pci.asm │ ├── serial.asm │ └── storage │ │ └── ide.asm ├── ipc.asm ├── config.asm ├── exec.asm └── service.asm ├── .github └── banner.png ├── include ├── page_align_up.asm ├── page_from_size.asm ├── string_cut.asm ├── unit │ ├── data.asm │ └── config.asm ├── string_compare.asm ├── string_digits.asm ├── string_to_integer.asm ├── integer_to_string.asm ├── string_word_next.asm ├── string_trim.asm ├── color.asm └── input.asm ├── aiden ├── storage.asm ├── protected_mode.asm ├── floppy.asm ├── kernel.asm ├── long_mode.asm └── aiden.asm ├── make.sh ├── README.md └── config.asm /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | backup/ 3 | -------------------------------------------------------------------------------- /software/shell/config.asm: -------------------------------------------------------------------------------- 1 | SHELL_CACHE_SIZE_byte equ 128 2 | -------------------------------------------------------------------------------- /kernel/init/serial.asm: -------------------------------------------------------------------------------- 1 | kernel_init_serial: 2 | call driver_serial 3 | -------------------------------------------------------------------------------- /.github/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slowy07/aiden/HEAD/.github/banner.png -------------------------------------------------------------------------------- /kernel/service/visual/gfx/cursor.data: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/slowy07/aiden/HEAD/kernel/service/visual/gfx/cursor.data -------------------------------------------------------------------------------- /kernel/macro/debug.asm: -------------------------------------------------------------------------------- 1 | %MACRO macro_debug 1 2 | %ifdef DEBUG 3 | jmp %%skip 4 | 5 | db "^ ", %1 6 | 7 | %%skip: 8 | %endif 9 | %ENDMACRO 10 | -------------------------------------------------------------------------------- /kernel/panic.asm: -------------------------------------------------------------------------------- 1 | kernel_panic_memory: 2 | mov rsi, kernel_init_string_error_memory_low 3 | 4 | kernel_panic: 5 | call driver_serial_send 6 | jmp $ 7 | 8 | macro_debug "kernel_panic" 9 | -------------------------------------------------------------------------------- /kernel/macro/lock.asm: -------------------------------------------------------------------------------- 1 | %MACRO macro_lock 2 2 | push rax 3 | 4 | .1: 5 | mov al, STATIC_TRUE 6 | lock xchg byte [%1 + %2], al 7 | test al, al 8 | jz .1 9 | 10 | pop rax 11 | %ENDMACRO 12 | -------------------------------------------------------------------------------- /kernel/macro/apic.asm: -------------------------------------------------------------------------------- 1 | %MACRO macro_apic_id_get 0 2 | mov rax, qword [kernel_apic_base_address] 3 | mov dword [rax + KERNEL_APIC_TP_register], STATIC_EMPTY 4 | mov eax, dword [rax + KERNEL_APIC_ID_register] 5 | shr eax, 24 6 | %ENDMACRO 7 | -------------------------------------------------------------------------------- /kernel/service/visual/sleep.asm: -------------------------------------------------------------------------------- 1 | service_render_sleep: 2 | cmp qword [service_render_object_list_records], STATIC_EMPTY 3 | je .end 4 | 5 | jmp service_render_sleep 6 | 7 | .end: 8 | ret 9 | 10 | macro_debug "service RENDER sleep" 11 | -------------------------------------------------------------------------------- /kernel/init/ipc.asm: -------------------------------------------------------------------------------- 1 | kernel_init_ipc: 2 | mov ecx, KERNEL_IPC_SIZE_page_default 3 | call kernel_memory_alloc 4 | 5 | call kernel_page_drain_few 6 | 7 | mov qword [kernel_ipc_base_address], rdi 8 | 9 | mov qword [rdi + STATIC_STRUCTURE_BLOCK.link], rdi 10 | -------------------------------------------------------------------------------- /include/page_align_up.asm: -------------------------------------------------------------------------------- 1 | include_page_align_up: 2 | push rdi 3 | 4 | and di, KERNEL_PAGE_mask 5 | 6 | cmp rdi, qword [rsp] 7 | je .end 8 | 9 | add rdi, KERNEL_PAGE_SIZE_byte 10 | 11 | .end: 12 | add rsp, STATIC_QWORD_SIZE_byte 13 | 14 | ret 15 | 16 | -------------------------------------------------------------------------------- /include/page_from_size.asm: -------------------------------------------------------------------------------- 1 | include_page_from_size: 2 | push rcx 3 | 4 | and cx, KERNEL_PAGE_mask 5 | 6 | cmp rcx, qword [rsp] 7 | je .ready 8 | 9 | add rcx, KERNEL_PAGE_SIZE_byte 10 | 11 | .ready: 12 | shr rcx, STATIC_DIVIDE_BY_PAGE_shift 13 | 14 | add rsp, STATIC_QWORD_SIZE_byte 15 | 16 | ret 17 | -------------------------------------------------------------------------------- /include/string_cut.asm: -------------------------------------------------------------------------------- 1 | include_string_cut: 2 | push rsi 3 | push rcx 4 | 5 | .loop: 6 | cmp byte [rsi], STATIC_ASCII_TERMINATOR 7 | je .end 8 | 9 | cmp byte [rsi], al 10 | je .end 11 | 12 | inc rsi 13 | 14 | dec rcx 15 | jnz .loop 16 | 17 | .end: 18 | sub qword [rsp], rcx 19 | 20 | pop rcx 21 | pop rsi 22 | 23 | ret 24 | 25 | -------------------------------------------------------------------------------- /kernel/service/date/event.asm: -------------------------------------------------------------------------------- 1 | service_date_event_console: 2 | push rcx 3 | push rsi 4 | 5 | mov ecx, service_date_event_console_file_end - service_date_event_console_file 6 | mov rsi, service_date_event_console_file 7 | call kernel_vfs_path_resolve 8 | call kernel_vfs_file_find 9 | call kernel_exec 10 | 11 | pop rsi 12 | pop rcx 13 | 14 | ret 15 | -------------------------------------------------------------------------------- /software/free/data.asm: -------------------------------------------------------------------------------- 1 | free_string_table db STATIC_COLOR_ASCII_GRAY, " total used free paged", STATIC_ASCII_NEW_LINE 2 | db STATIC_COLOR_ASCII_GRAY_LIGHT, "Memory: ", STATIC_COLOR_ASCII_WHITE 3 | 4 | free_string_table_end: 5 | 6 | free_string_kib db STATIC_COLOR_ASCII_GRAY_LIGHT, " KiB", STATIC_COLOR_ASCII_WHITE 7 | 8 | free_string_kib_end: 9 | -------------------------------------------------------------------------------- /include/unit/data.asm: -------------------------------------------------------------------------------- 1 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 2 | 3 | include_unit_element_entry: 4 | .null: 5 | dq STATIC_EMPTY 6 | 7 | .header: 8 | dq include_unit_element_header 9 | 10 | .label: 11 | dq include_unit_element_label 12 | 13 | .draw: 14 | dq STATIC_EMPTY 15 | 16 | .chain: 17 | dq STATIC_EMPTY 18 | 19 | .button: 20 | dq include_unit_element_button 21 | -------------------------------------------------------------------------------- /include/string_compare.asm: -------------------------------------------------------------------------------- 1 | include_string_compare: 2 | push rax 3 | push rcx 4 | push rsi 5 | push rdi 6 | 7 | .loop: 8 | lodsb 9 | 10 | cmp al, byte [rdi] 11 | jne .error 12 | 13 | inc rdi 14 | 15 | dec rcx 16 | jnz .loop 17 | 18 | clc 19 | 20 | jmp .end 21 | 22 | .error: 23 | stc 24 | 25 | .end: 26 | pop rdi 27 | pop rsi 28 | pop rcx 29 | pop rax 30 | 31 | ret 32 | 33 | -------------------------------------------------------------------------------- /include/string_digits.asm: -------------------------------------------------------------------------------- 1 | include_string_digits: 2 | push rsi 3 | push rcx 4 | 5 | .loop: 6 | cmp byte [rsi], STATIC_ASCII_DIGIT_0 7 | jb .error 8 | cmp byte [rsi], STATIC_ASCII_DIGIT_9 9 | ja .error 10 | 11 | inc rsi 12 | 13 | dec rcx 14 | jnz .loop 15 | 16 | clc 17 | 18 | jmp .end 19 | 20 | .error: 21 | stc 22 | 23 | .end: 24 | pop rcx 25 | pop rsi 26 | 27 | ret 28 | 29 | -------------------------------------------------------------------------------- /kernel/service/visual/panic.asm: -------------------------------------------------------------------------------- 1 | service_render_string_error_memory_low db "RENDER: no enough memory." 2 | 3 | service_render_string_error_memory_low_end: 4 | 5 | service_render_panic_memory_low: 6 | mov ecx, service_render_string_error_memory_low_end - service_render_string_error_memory_low 7 | mov rsi, service_render_string_error_memory_low 8 | call kernel_video_string 9 | 10 | jmp $ 11 | -------------------------------------------------------------------------------- /software/hello.asm: -------------------------------------------------------------------------------- 1 | %include "config.asm" 2 | %include "kernel/config.asm" 3 | 4 | [BITS 64] 5 | 6 | [DEFAULT REL] 7 | 8 | [ORG SOFTWARE_base_address] 9 | 10 | hello: 11 | mov ax, KERNEL_SERVICE_VIDEO_string 12 | mov ecx, hello_string_end - hello_string 13 | mov rsi, hello_string 14 | int KERNEL_SERVICE 15 | 16 | xor ax, ax 17 | int KERNEL_SERVICE 18 | 19 | hello_string db "Wello Aiden" 20 | 21 | hello_string_end: 22 | -------------------------------------------------------------------------------- /include/string_to_integer.asm: -------------------------------------------------------------------------------- 1 | include_string_to_integer: 2 | push rbx 3 | push rcx 4 | push rdx 5 | push rsi 6 | push r8 7 | push rax 8 | 9 | mov ebx, 1 10 | 11 | xor r8, r8 12 | 13 | .loop: 14 | movzx eax, byte [rsi + rcx - 0x01] 15 | sub al, STATIC_ASCII_DIGIT_0 16 | mul rbx 17 | 18 | add r8, rax 19 | 20 | mov eax, 10 21 | mul rbx 22 | mov rbx, rax 23 | 24 | dec rcx 25 | jnz .loop 26 | 27 | mov qword [rsp], r8 28 | 29 | pop rax 30 | pop r8 31 | pop rsi 32 | pop rdx 33 | pop rcx 34 | pop rbx 35 | 36 | ret 37 | 38 | -------------------------------------------------------------------------------- /kernel/service/date.asm: -------------------------------------------------------------------------------- 1 | %include "kernel/service/date/config.asm" 2 | 3 | service_date: 4 | %include "kernel/service/date/init.asm" 5 | 6 | .loop: 7 | call service_date_ipc 8 | call service_date_taskbar 9 | call service_date_clock 10 | 11 | jmp .loop 12 | 13 | %include "kernel/service/date/data.asm" 14 | %include "kernel/service/date/clock.asm" 15 | %include "kernel/service/date/ipc.asm" 16 | %include "kernel/service/date/event.asm" 17 | %include "kernel/service/date/taskbar.asm" 18 | 19 | %include "include/unit.asm" 20 | %include "include/font.asm" 21 | -------------------------------------------------------------------------------- /aiden/storage.asm: -------------------------------------------------------------------------------- 1 | aiden_storage: 2 | push es 3 | 4 | mov ax, 0x1000 5 | mov es, ax 6 | xor bx, bx 7 | 8 | mov si, aiden_string_header 9 | call aiden_print_string 10 | mov si, aiden_string_loading 11 | call aiden_print_string 12 | 13 | mov cl, (((aiden_end - aiden) + 0x200) / 0x200) + 0x01 14 | mov di, KERNEL_FILE_SIZE_bytes / 0x0200 15 | call aiden_floppy 16 | jnc .end 17 | 18 | mov si, aiden_string_error_kernel 19 | call kernel_print_string 20 | 21 | jmp $ 22 | 23 | %include "aiden/floopy.asm" 24 | 25 | aiden_storage_end: 26 | pop es 27 | -------------------------------------------------------------------------------- /kernel/service/date/ipc.asm: -------------------------------------------------------------------------------- 1 | service_date_ipc: 2 | push rax 3 | push rsi 4 | push rdi 5 | push r8 6 | push r9 7 | 8 | mov rdi, service_date_ipc_data 9 | call kernel_ipc_receive 10 | jc .end 11 | 12 | mov rax, qword [service_render_pid] 13 | cmp qword [rdi + KERNEL_IPC_STRUCTURE.pid_source], rax 14 | jne .no_render 15 | 16 | call service_date_ipc_render 17 | 18 | .no_render: 19 | 20 | .end: 21 | pop r9 22 | pop r8 23 | pop rdi 24 | pop rsi 25 | pop rax 26 | 27 | ret 28 | 29 | macro_debug "service_date_ipc" 30 | 31 | %include "kernel/service/date/ipc/render.asm" 32 | -------------------------------------------------------------------------------- /software/console/config.asm: -------------------------------------------------------------------------------- 1 | %include "kernel/config.asm" 2 | %include "config.asm" 3 | 4 | ; Define console window dimensions based on font size 5 | CONSOLE_WINDOW_WIDTH_pixel equ INCLUDE_FONT_WIDTH_pixel * 40 6 | CONSOLE_WINDOW_HEIGHT_pixel equ INCLUDE_FONT_HEIGHT_pixel * 12 7 | 8 | ; Define console window background color 9 | CONSOLE_WINDOW_BACKGROUND_color equ 0x00000000 10 | 11 | [BITS 64]; Set 64-bit mode 12 | 13 | ; Using relative addressing for position-independent code 14 | [DEFAULT REL] 15 | ; Set origin to software base address 16 | [ORG SOFTWARE_base_address] 17 | -------------------------------------------------------------------------------- /kernel/service/visual/cursor.asm: -------------------------------------------------------------------------------- 1 | service_render_cursor: 2 | push rsi 3 | 4 | test qword [service_render_object_cursor + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags], SERVICE_RENDER_OBJECT_FLAG_flush 5 | jz .no 6 | 7 | mov rsi, service_render_object_cursor 8 | call service_render_fill_insert_by_object 9 | call service_render_fill 10 | 11 | and qword [service_render_object_cursor + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags], ~SERVICE_RENDER_OBJECT_FLAG_flush 12 | 13 | .no: 14 | pop rsi 15 | 16 | ret 17 | 18 | macro_debug "service_render_cursor" 19 | -------------------------------------------------------------------------------- /make.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | 3 | WIDTH=640 4 | HEIGHT=480 5 | 6 | nasm -f bin software/init.asm -o build/init 7 | nasm -f bin software/shell.asm -o build/shell 8 | nasm -f bin software/hello.asm -o build/hello 9 | nasm -f bin software/free.asm -o build/free 10 | nasm -f bin software/console.asm -o build/console 11 | 12 | nasm -f bin kernel/init/boot.asm -o build/boot 13 | nasm -f bin kernel/kernel.asm -o build/kernel \ 14 | -dMULTIBOOT_VIDEO_WIDTH_pixel=${WIDTH} \ 15 | -dMULTIBOOT_VIDEO_HEIGHT_pixel=${HEIGHT} 16 | nasm -f bin aiden/aiden.asm -o build/disk.raw \ 17 | -dMULTIBOOT_VIDEO_WIDTH_pixel=${WIDTH} \ 18 | -dMULTIBOOT_VIDEO_HEIGHT_pixel=${HEIGHT} 19 | 20 | -------------------------------------------------------------------------------- /software/shell/data.asm: -------------------------------------------------------------------------------- 1 | shell_string_prompt_with_new_line db STATIC_ASCII_NEW_LINE 2 | shell_string_prompt db STATIC_COLOR_ASCII_RED_LIGHT 3 | shell_string_prompt_type db "# " 4 | shell_string_prompt_type_end db STATIC_COLOR_ASCII_DEFAULT 5 | 6 | shell_string_prompt_end: 7 | 8 | shell_exec_path db "/bin/" 9 | 10 | shell_exec_path_end: 11 | 12 | shell_cache: 13 | times SHELL_CACHE_SIZE_byte db STATIC_EMPTY 14 | 15 | shell_command_clean db "clean" 16 | 17 | shell_command_clean_end: 18 | shell_command_exit db "exit" 19 | 20 | shell_command_exit_end: 21 | 22 | shell_command_unknown db STATIC_COLOR_ASCII_RED_LIGHT, "unknwon command", STATIC_ASCII_NEW_LINE 23 | 24 | shell_command_unknown_end: 25 | -------------------------------------------------------------------------------- /kernel/service/network/data.asm: -------------------------------------------------------------------------------- 1 | service_network_pid dq STATIC_EMPTY ; Process ID associated with the service network 2 | 3 | service_network_rx_count dq STATIC_EMPTY ; Received packet count 4 | service_network_tx_count dq STATIC_EMPTY ; Transmitted packet count 5 | 6 | service_network_port_semaphore db STATIC_FALSE ; Semaphore for controlling port access 7 | service_network_port_table dq STATIC_EMPTY ; Table storing network port information 8 | 9 | service_network_stack_address dq STATIC_EMPTY ; Stack address for network operations 10 | 11 | ; IPC Message Buffer 12 | ; This buffer is used for inter-process communication (IPC) within the kernel 13 | service_network_ipc_message: 14 | times KERNEL_IPC_STRUCTURE.SIZE db STATIC_EMPTY -------------------------------------------------------------------------------- /kernel/service/visual/keyboard.asm: -------------------------------------------------------------------------------- 1 | service_render_keyboard: 2 | call driver_ps2_keyboard_read 3 | jz .end 4 | 5 | mov rsi, qword [service_render_object_selected_pointer] 6 | 7 | test rsi, rsi 8 | jz .leave 9 | 10 | mov cl, SERVICE_RENDER_IPC_KEYBOARD 11 | call service_render_ipc_keyboard 12 | 13 | .leave: 14 | cmp ax, DRIVER_PS2_KEYBOARD_PRESS_ALT_LEFT 15 | jne .no_press_alt_left 16 | 17 | mov byte [service_render_keyboard_alt_left_semaphore], STATIC_TRUE 18 | 19 | .no_press_alt_left: 20 | cmp ax, DRIVER_PS2_KEYBOARD_RELEASE_ALT_LEFT 21 | jne .end 22 | 23 | mov byte [service_render_keyboard_alt_left_semaphore], STATIC_FALSE 24 | 25 | .end: 26 | ret 27 | 28 | macro_debug "service_render_keyboard" 29 | -------------------------------------------------------------------------------- /kernel/service/tx.asm: -------------------------------------------------------------------------------- 1 | service_tx_pid dq STATIC_EMPTY 2 | 3 | service_tx_ipc_message: 4 | times KERNEL_IPC_STRUCTURE.SIZE db STATIC_EMPTY 5 | 6 | service_tx: 7 | call kernel_task_active 8 | mov rax, qword [rdi + KERNEL_TASK_STRUCTURE.pid] 9 | 10 | mov qword [service_tx_pid], rax 11 | 12 | .loop: 13 | mov rdi, service_tx_ipc_message 14 | call kernel_ipc_receive 15 | jc .loop 16 | 17 | mov rcx, qword [rdi + KERNEL_IPC_STRUCTURE.size] 18 | 19 | test rcx, rcx 20 | jz .loop 21 | 22 | mov rax, rcx 23 | mov rdi, qword [rdi + KERNEL_IPC_STRUCTURE.pointer] 24 | call driver_nic_i82540em_transfer 25 | 26 | call include_page_from_size 27 | call kernel_memory_release 28 | 29 | jmp .loop 30 | 31 | macro_debug "service_tx" 32 | -------------------------------------------------------------------------------- /kernel/service/render.asm: -------------------------------------------------------------------------------- 1 | %include "kernel/service/visual/config.asm" 2 | 3 | service_render: 4 | %include "kernel/service/visual/init.asm" 5 | 6 | .loop: 7 | call service_render_object 8 | call service_render_event 9 | call service_render_zone 10 | call service_render_fill 11 | call service_render_cursor 12 | 13 | jmp .loop 14 | %include "kernel/service/visual/data.asm" 15 | %include "kernel/service/visual/zone.asm" 16 | %include "kernel/service/visual/cursor.asm" 17 | %include "kernel/service/visual/object.asm" 18 | %include "kernel/service/visual/fill.asm" 19 | %include "kernel/service/visual/event.asm" 20 | %include "kernel/service/visual/service.asm" 21 | %include "kernel/service/visual/ipc.asm" 22 | %include "kernel/service/visual/keyboard.asm" 23 | 24 | service_render_end: 25 | -------------------------------------------------------------------------------- /aiden/protected_mode.asm: -------------------------------------------------------------------------------- 1 | aiden_protected_mode: 2 | cli 3 | 4 | lgdt [aiden_protected_mode_header_gdt32bit] 5 | 6 | mov eax, cr0 7 | bts eax, 9 8 | mov cr0, eax 9 | 10 | jmp long 0x008:aiden_protected_mode_entry 11 | 12 | align 0x10 13 | aiden_protected_mode_table_gdt_32bit: 14 | dq 0x0000000000000000 15 | dq 0000000011001111100110000000000000000000000000001111111111111111b 16 | dq 0000000011001111100100100000000000000000000000001111111111111111b 17 | aiden_protected_mode_table_gdt_32bit_end: 18 | 19 | aiden_protected_mode_header_gdt32bit: 20 | dw aiden_protected_mode_table_gdt_32bit_end - aiden_protected_mode_table_gdt_32bit - 0x01 21 | dd aiden_protected_mode_table_gdt_32bit 22 | 23 | [bits 32] 24 | aiden_protected_mode_entry: 25 | mov ax, 0x10 26 | mov ds, ax 27 | mov es, ax 28 | mov ss, ax 29 | -------------------------------------------------------------------------------- /aiden/floppy.asm: -------------------------------------------------------------------------------- 1 | aiden_floppy: 2 | push ax 3 | push bx 4 | push cx 5 | push dx 6 | push di 7 | push bp 8 | push es 9 | 10 | mov al, 0x01 11 | mov ch, 0x00 12 | mov dh, 0x00 13 | 14 | .reload: 15 | mov bp, 0x03 16 | 17 | .loop: 18 | mov ah, 0x02 19 | int 0x13 20 | jc .reset 21 | 22 | dec di 23 | jz .end 24 | 25 | inc cl 26 | 27 | add bx, 0x0200 28 | 29 | cmp cl, 18 30 | jbe .reload 31 | 32 | not dh 33 | and dh, 00000001b 34 | 35 | mov cl, 1 36 | 37 | test dh, dh 38 | jnz .reload 39 | 40 | inc ch 41 | 42 | cmp ch, 80 43 | jb .reload 44 | 45 | stc 46 | 47 | jmp .end 48 | 49 | .reset: 50 | mov ah, 0x00 51 | int 0x13 52 | jnc .loop 53 | 54 | .end: 55 | pop es 56 | pop bp 57 | pop di 58 | pop dx 59 | pop cx 60 | pop bx 61 | pop ax 62 | 63 | ret 64 | -------------------------------------------------------------------------------- /kernel/init/apic.asm: -------------------------------------------------------------------------------- 1 | kernel_init_apic: 2 | mov rsi, qword [kernel_apic_base_address] 3 | 4 | mov dword [rsi + KERNEL_APIC_TP_register], STATIC_EMPTY 5 | 6 | mov dword [rsi + KERNEL_APIC_DF_register], KERNEL_APIC_DF_FLAG_flat_mode 7 | 8 | mov dword [rsi + KERNEL_APIC_LD_register], KERNEL_APIC_LD_FLAG_target_cpu 9 | 10 | mov eax, dword [rsi + KERNEL_APIC_SIV_register] 11 | or eax, KERNEL_APIC_SIV_FLAG_enable_apic | KERNEL_APIC_SIV_FLAG_spurious_vector 12 | mov dword [rsi + KERNEL_APIC_SIV_register], eax 13 | 14 | mov eax, dword [rsi + KERNEL_APIC_LVT_TR_register] 15 | and eax, ~KERNEL_APIC_LVT_TR_FLAG_mask_interrupts 16 | mov dword [rsi + KERNEL_APIC_LVT_TR_register], eax 17 | 18 | mov dword [rsi + KERNEL_APIC_LVT_TR_register], KERNEL_APIC_IRQ_number 19 | 20 | mov dword [rsi + KERNEL_APIC_TDC_register], KERNEL_APIC_TDC_divide_by_16 21 | 22 | ret 23 | -------------------------------------------------------------------------------- /kernel/init/boot.asm: -------------------------------------------------------------------------------- 1 | [BITS 16] 2 | 3 | [ORG 0x8000] 4 | 5 | boot: 6 | cli 7 | 8 | jmp 0x0000:.repair_cs 9 | 10 | .repair_cs: 11 | xor ax, ax 12 | mov ds, ax 13 | mov es, ax 14 | 15 | cld 16 | 17 | lgdt [boot_header_gdt_32bit] 18 | 19 | mov eax, cr0 20 | bts eax, 0 21 | mov cr0, eax 22 | 23 | jmp long 0x0008:boot_protected_mode 24 | 25 | [BITS 32] 26 | 27 | boot_protected_mode: 28 | mov ax, 0x10 29 | mov ds, ax 30 | mov es, ax 31 | 32 | jmp 0x00100000 33 | 34 | align 0x10 35 | 36 | boot_table_gdt_32bit: 37 | dq 0x0000000000000000 38 | dq 0000000011001111100110000000000000000000000000001111111111111111b 39 | dq 0000000011001111100100100000000000000000000000001111111111111111b 40 | 41 | boot_table_gdt_32bit_end: 42 | 43 | boot_header_gdt_32bit: 44 | dw boot_table_gdt_32bit_end - boot_table_gdt_32bit - 0x01 45 | dd boot_table_gdt_32bit 46 | 47 | boot_end: 48 | -------------------------------------------------------------------------------- /include/integer_to_string.asm: -------------------------------------------------------------------------------- 1 | include_integer_to_string: 2 | push rax 3 | push rcx 4 | push rdx 5 | push rdi 6 | push rbp 7 | push r9 8 | 9 | cmp rbx, 2 10 | jb .error 11 | cmp rbx, 36 12 | ja .error 13 | 14 | mov r9, rdx 15 | 16 | xor rdx, rdx 17 | 18 | mov rbp, rsp 19 | 20 | .loop: 21 | div rbx 22 | 23 | add rdx, STATIC_ASCII_DIGIT_0 24 | push rdx 25 | 26 | dec rcx 27 | 28 | xor rdx, rdx 29 | 30 | test rax, rax 31 | jnz .loop 32 | 33 | cmp rcx, STATIC_EMPTY 34 | jle .return 35 | 36 | .prefix: 37 | push r9 38 | 39 | dec rcx 40 | jnz .prefix 41 | 42 | .return: 43 | cmp rsp, rbp 44 | je .end 45 | 46 | pop rax 47 | 48 | cmp al, 0x3A 49 | jb .no 50 | 51 | add al, 0x07 52 | 53 | .no: 54 | stosb 55 | 56 | jmp .return 57 | 58 | .error: 59 | stc 60 | 61 | .end: 62 | pop r9 63 | pop rbp 64 | pop rdi 65 | pop rdx 66 | pop rcx 67 | pop rax 68 | 69 | ret 70 | -------------------------------------------------------------------------------- /kernel/init/video.asm: -------------------------------------------------------------------------------- 1 | KERNEL_INIT_MEMORY_MULTIBOOT_FLAG_video equ 12 2 | 3 | kernel_init_video: 4 | push rbx 5 | 6 | mov rsi, kernel_init_string_error_video_header 7 | 8 | bt dword [ebx + MULTIBOOT_HEADER.flags], KERNEL_INIT_MEMORY_MULTIBOOT_FLAG_video 9 | jnc kernel_panic 10 | 11 | mov edi, dword [ebx + MULTIBOOT_HEADER.framebuffer_addr] 12 | mov qword [kernel_video_base_address], rdi 13 | 14 | mov eax, dword [ebx + MULTIBOOT_HEADER.framebuffer_width] 15 | mov qword [kernel_video_width_pixel], rax 16 | mov eax, dword [ebx + MULTIBOOT_HEADER.framebuffer_height] 17 | mov qword [kernel_video_height_pixel], rax 18 | 19 | mul qword [kernel_video_width_pixel] 20 | shl rax, KERNEL_VIDEO_DEPTH_shift 21 | mov qword [kernel_video_size_byte], rax 22 | 23 | mov rax, qword [kernel_video_width_pixel] 24 | shl rax, KERNEL_VIDEO_DEPTH_shift 25 | mov qword [kernel_video_scanline_byte], rax 26 | 27 | pop rbx 28 | -------------------------------------------------------------------------------- /aiden/kernel.asm: -------------------------------------------------------------------------------- 1 | aiden_kernel: 2 | call kernel_pic_disable 3 | 4 | cli 5 | 6 | mov ecx, KERNEL_FILE_SIZE_bytes 7 | mov esi, 0x00010000 8 | mov edi, 0x00100000 9 | rep movsb 10 | 11 | mov ecx, aiden_file_ap_end - aiden_file_ap 12 | mov esi, aiden_file_ap 13 | mov edi, aiden 14 | rep movsb 15 | 16 | mov ebx, dword [aiden_memory_map_address] 17 | 18 | mov edx, dword [aiden_graphics_mode_info_block_address] 19 | 20 | mov rax, "A I D E N" 21 | mov esi, 0x00100000 22 | mov ecx, KERNEL_FILE_SIZE_bytes / 0x08 23 | 24 | .search: 25 | sub ecx, 0x08 26 | js .error 27 | 28 | add esi, 0x08 29 | 30 | cmp qword [rsi - 0x08], rax 31 | 32 | jne .search 33 | 34 | mov ecx, KERNEL_FILE_SIZE_bytes 35 | 36 | mov rax, qword [rsi] 37 | 38 | xor esi, esi 39 | xor edi, edi 40 | xor ebp, ebp 41 | 42 | mov esp, aiden 43 | 44 | jmp rax 45 | 46 | .error: 47 | hlt 48 | jmp .error 49 | -------------------------------------------------------------------------------- /kernel/io_apic.asm: -------------------------------------------------------------------------------- 1 | KERNEL_IO_APIC_ioregsel equ 0x00 2 | KERNEL_IO_APIC_iowin equ 0x10 3 | KERNEL_IO_APIC_iowin_low equ 0x00 4 | KERNEL_IO_APIC_iowin_high equ 0x01 5 | 6 | KERNEL_IO_APIC_TRIGER_MODE_level equ 1000000000000000b 7 | 8 | kernel_io_apic_base_address dq STATIC_EMPTY 9 | 10 | kernel_io_apic_connect: 11 | push rax 12 | push rbx 13 | push rdi 14 | 15 | mov rdi, qword [kernel_io_apic_base_address] 16 | 17 | add ebx, KERNEL_IO_APIC_iowin_low 18 | mov dword [rdi + KERNEL_IO_APIC_ioregsel], ebx 19 | 20 | mov dword [rdi + KERNEL_IO_APIC_iowin], eax 21 | 22 | add ebx, KERNEL_IO_APIC_iowin_high - KERNEL_IO_APIC_iowin_low 23 | mov dword [rdi + KERNEL_IO_APIC_ioregsel], ebx 24 | 25 | shr rax, STATIC_MOVE_HIGH_TO_EAX_shift 26 | mov dword [rdi + KERNEL_IO_APIC_iowin], eax 27 | 28 | pop rdi 29 | pop rbx 30 | pop rax 31 | 32 | ret 33 | 34 | macro_debug "kernel_io_apic_connect" 35 | -------------------------------------------------------------------------------- /kernel/data.asm: -------------------------------------------------------------------------------- 1 | kernel_init_semaphore db STATIC_TRUE 2 | 3 | kernel_init_exec db "/bin/init" 4 | 5 | kernel_init_exec_end: 6 | 7 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 8 | kernel_gdt_header dw KERNEL_PAGE_SIZE_byte 9 | dq STATIC_EMPTY 10 | 11 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 12 | kernel_gdt_tss_bsp_selector dw STATIC_EMPTY 13 | kernel_gdt_tss_cpu_selector dw STATIC_EMPTY 14 | 15 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 16 | 17 | kernel_gdt_tss_table: 18 | dd STATIC_EMPTY 19 | dq KERNEL_STACK_pointer 20 | times 92 db STATIC_EMPTY 21 | 22 | kernel_gdt_tss_table_end: 23 | 24 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 25 | 26 | kernel_idt_header: 27 | dw KERNEL_PAGE_SIZE_byte 28 | dq STATIC_EMPTY 29 | 30 | macro_debug "kernel_data" 31 | 32 | kernel_video_width_pixel dq STATIC_EMPTY 33 | kernel_video_height_pixel dq STATIC_EMPTY 34 | kernel_video_base_address dq STATIC_EMPTY 35 | kernel_video_size_byte dq STATIC_EMPTY 36 | kernel_video_scanline_byte dq STATIC_EMPTY 37 | -------------------------------------------------------------------------------- /software/console.asm: -------------------------------------------------------------------------------- 1 | %include "software/console/config.asm" 2 | 3 | console: 4 | %include "software/console/init.asm" 5 | 6 | .loop: 7 | mov ax, KERNEL_SERVICE_PROCESS_ipc_receive 8 | mov rdi, console_ipc_data 9 | int KERNEL_SERVICE 10 | jc .loop 11 | 12 | cmp byte [rdi + KERNEL_IPC_STRUCTURE.data + SERVICE_RENDER_STRUCTURE_IPC.type], SERVICE_RENDER_IPC_KEYBOARD 13 | jne .loop 14 | 15 | mov rax, qword [rdi + KERNEL_IPC_STRUCTURE.data + SERVICE_RENDER_STRUCTURE_IPC.value0] 16 | 17 | cmp rax, STATIC_ASCII_SPACE 18 | jb .loop 19 | cmp rax, STATIC_ASCII_DELETE 20 | jae .loop 21 | 22 | mov ecx, 1 23 | call include_terminal_char 24 | 25 | mov al, SERVICE_RENDER_WINDOW_update 26 | or qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.flags], INCLUDE_UNIT_WINDOW_FLAG_visible | INCLUDE_UNIT_WINDOW_FLAG_flush 27 | 28 | jmp .loop 29 | 30 | %include "software/console/data.asm" 31 | %include "include/unit.asm" 32 | %include "include/font.asm" 33 | %include "include/page_from_size.asm" 34 | %include "include/terminal.asm" 35 | -------------------------------------------------------------------------------- /include/string_word_next.asm: -------------------------------------------------------------------------------- 1 | include_string_word_next: 2 | push rax 3 | push rcx 4 | 5 | test rcx, rcx 6 | jz .not_found 7 | 8 | .find: 9 | cmp byte [rsi], STATIC_ASCII_TERMINATOR 10 | je .not_found 11 | 12 | cmp byte [rsi], STATIC_ASCII_NEW_LINE 13 | je .leave 14 | 15 | cmp byte [rsi], STATIC_ASCII_SPACE 16 | je .leave 17 | 18 | cmp byte [rsi], STATIC_ASCII_TAB 19 | jne .char 20 | 21 | .leave: 22 | inc rsi 23 | 24 | dec rcx 25 | jnz .find 26 | 27 | jmp .not_found 28 | 29 | .char: 30 | push rsi 31 | 32 | xor rax, rax 33 | 34 | .count: 35 | cmp byte [rsi], STATIC_ASCII_TERMINATOR 36 | je .ready 37 | 38 | cmp byte [rsi], STATIC_ASCII_NEW_LINE 39 | je .ready 40 | 41 | cmp byte [rsi], STATIC_ASCII_SPACE 42 | je .ready 43 | 44 | cmp byte [rsi], STATIC_ASCII_TAB 45 | je .ready 46 | 47 | inc rsi 48 | 49 | inc rax 50 | 51 | dec rcx 52 | jnz .count 53 | 54 | .ready: 55 | pop rsi 56 | 57 | mov rbx, rax 58 | 59 | clc 60 | 61 | jmp .end 62 | 63 | .not_found: 64 | stc 65 | 66 | .end: 67 | pop rcx 68 | pop rax 69 | 70 | ret 71 | -------------------------------------------------------------------------------- /kernel/service/date/config.asm: -------------------------------------------------------------------------------- 1 | ; Define number of windows managed by service date system 2 | ; this determine how many UI element 3 | SERVICE_DATE_WINDOW_count equ 3 4 | 5 | ; Define the background color of the Workbench window in ARGB format. 6 | ; The workbench acts as the primary desktop background and holds 7 | ; other UI components like icons and menus. 8 | 9 | ; 0x00101010 represents: 10 | ; - Alpha (opacity): 0x00 (fully transparent in some systems) 11 | ; - Red: 0x10 (dim dark gray) 12 | ; - Green: 0x10 (dim dark gray) 13 | ; - Blue: 0x10 (dim dark gray) 14 | 15 | ; This results in a nearly black but slightly visible dark gray background. 16 | SERVICE_DATE_WINDOW_WORKBENCH_BACKGROUND_color equ 0x00101010 17 | 18 | ; Define the height of the taskbar in pixels. 19 | ; The taskbar serves as a system status bar, usually displaying 20 | ; open applications, system tray, and time. 21 | 22 | ; This height is determined by the font height to ensure proper 23 | ; text rendering and alignment of elements. 24 | SERVICE_DATE_WINDOW_TASKBAR_HEIGHT_pixel equ INCLUDE_FONT_HEIGHT_pixel 25 | -------------------------------------------------------------------------------- /include/string_trim.asm: -------------------------------------------------------------------------------- 1 | include_string_trim: 2 | push rcx 3 | push rsi 4 | 5 | test rcx, rcx 6 | jz .error 7 | 8 | .prefix: 9 | cmp byte [rsi], STATIC_ASCII_SPACE 10 | je .prefix_found 11 | 12 | cmp byte [rsi], STATIC_ASCII_TAB 13 | je .prefix_found 14 | 15 | cmp byte [rsi], STATIC_EMPTY 16 | jne .prefix_ready 17 | 18 | .prefix_found: 19 | inc rsi 20 | 21 | dec rcx 22 | jnz .prefix 23 | 24 | jmp .error 25 | 26 | .prefix_ready: 27 | add rsi, rcx 28 | 29 | .suffix: 30 | cmp byte [rsi - STATIC_BYTE_SIZE_byte], STATIC_ASCII_SPACE 31 | je .suffix_found 32 | 33 | cmp byte [rsi - STATIC_BYTE_SIZE_byte], STATIC_ASCII_TAB 34 | je .suffix_found 35 | 36 | cmp byte [rsi - STATIC_BYTE_SIZE_byte], STATIC_EMPTY 37 | jne .suffix_ready 38 | 39 | .suffix_found: 40 | dec rsi 41 | 42 | dec rcx 43 | jnz .suffix 44 | 45 | jmp .error 46 | 47 | .suffix_ready: 48 | sub rsi, rcx 49 | 50 | mov qword [rsp], rsi 51 | mov qword [rsp + STATIC_QWORD_SIZE_byte], rcx 52 | 53 | clc 54 | 55 | jmp .end 56 | 57 | .error: 58 | stc 59 | 60 | .end: 61 | pop rsi 62 | pop rcx 63 | 64 | ret 65 | 66 | -------------------------------------------------------------------------------- /kernel/init/network.asm: -------------------------------------------------------------------------------- 1 | ; Initializes the network subsystem 2 | kernel_init_network: 3 | ; Load PCI network class/subclass 4 | mov eax, DRIVER_PCI_CLASS_SUBCLASS_network 5 | call driver_pci_find_class_and_subclass ; Find network device 6 | jc .end ; If not found, exit 7 | 8 | mov eax, DRIVER_PCI_REGISTER_vendor_and_device ; Load vendor/device register 9 | call driver_pci_read ; Read vendor and device ID 10 | 11 | cmp eax, DRIVER_NIC_I82540EM_VENDOR_AND_DEVICE ; Check if NIC is i82540EM 12 | jne .end ; If not, exit 13 | 14 | call driver_nic_i82540em ; Initialize NIC driver 15 | 16 | call kernel_memory_alloc_page ; Allocate memory for port table 17 | jc kernel_panic ; Panic if allocation fails 18 | 19 | call kernel_page_drain ; Ensure memory is cleared 20 | mov qword [service_network_port_table], rdi ; Store port table address 21 | 22 | call kernel_memory_alloc_page ; Allocate memory for network stack 23 | jc kernel_panic ; Panic if allocation fails 24 | 25 | call kernel_page_drain ; Ensure memory is cleared 26 | mov qword [service_network_stack_address], rdi ; Store stack address 27 | 28 | .end: 29 | -------------------------------------------------------------------------------- /kernel/init/task.asm: -------------------------------------------------------------------------------- 1 | kernel_init_task: 2 | movzx ecx, byte [kernel_init_apic_id_highest] 3 | inc cx 4 | 5 | shl ecx, STATIC_MULTIPLE_BY_8_shift 6 | 7 | call include_page_from_size 8 | 9 | call kernel_memory_alloc 10 | jc kernel_panic_memory 11 | 12 | mov qword [kernel_task_active_list], rdi 13 | 14 | mov rsi, rdi 15 | 16 | call kernel_memory_alloc_page 17 | jc kernel_panic_memory 18 | 19 | call kernel_page_drain 20 | 21 | mov qword [kernel_task_address], rdi 22 | 23 | mov qword [rdi + STATIC_STRUCTURE_BLOCK.link], rdi 24 | 25 | call kernel_apic_id_get 26 | 27 | shl rax, STATIC_MULTIPLE_BY_8_shift 28 | mov qword [rsi + rax], rdi 29 | 30 | mov ebx, KERNEL_TASK_FLAG_active | KERNEL_TASK_FLAG_secured | KERNEL_TASK_FLAG_processing 31 | mov ecx, kernel_init_string_name_end - kernel_init_string_name 32 | mov rsi, kernel_init_string_name 33 | mov r11, qword [kernel_page_pml4_address] 34 | call kernel_task_add 35 | 36 | mov qword [rdi + KERNEL_TASK_STRUCTURE.knot], kernel_vfs_magicknot 37 | 38 | mov rax, KERNEL_APIC_IRQ_number 39 | mov bx, KERNEL_IDT_TYPE_irq 40 | mov rdi, kernel_task 41 | call kernel_idt_mount 42 | -------------------------------------------------------------------------------- /kernel/init/rtc.asm: -------------------------------------------------------------------------------- 1 | kernel_init_rtc: 2 | mov al, DRIVER_RTC_PORT_STATUS_REGISTER_A 3 | out DRIVER_RTC_PORT_command, al 4 | in al, DRIVER_RTC_PORT_data 5 | 6 | test al, DRIVER_RTC_PORT_STATUS_REGISTER_A_update_in_progress 7 | jne kernel_init_rtc 8 | 9 | mov al, DRIVER_RTC_PORT_STATUS_REGISTER_A 10 | out DRIVER_RTC_PORT_command, al 11 | mov al, DRIVER_RTC_PORT_STATUS_REGISTER_A_rate | DRIVER_RTC_PORT_STATUS_REGISTER_A_divider 12 | out DRIVER_RTC_PORT_data, al 13 | 14 | mov al, DRIVER_RTC_PORT_STATUS_REGISTER_B 15 | out DRIVER_RTC_PORT_command, al 16 | mov al, DRIVER_RTC_PORT_STATUS_REGISTER_B_24_hour_mode | DRIVER_RTC_PORT_STATUS_REGISTER_B_binary_mode | DRIVER_RTC_PORT_STATUS_REGISTER_B_periodic_interrupt 17 | out DRIVER_RTC_PORT_data, al 18 | 19 | mov al, DRIVER_RTC_PORT_STATUS_REGISTER_C 20 | out DRIVER_RTC_PORT_command, al 21 | 22 | in al, DRIVER_RTC_PORT_data 23 | 24 | mov eax, KERNEL_IDT_IRQ_offset + DRIVER_RTC_IRQ_number 25 | mov bx, KERNEL_IDT_TYPE_irq 26 | mov rdi, driver_rtc 27 | call kernel_idt_mount 28 | 29 | mov eax, KERNEL_IDT_IRQ_offset + DRIVER_RTC_IRQ_number 30 | mov ebx, DRIVER_RTC_IO_APIC_register 31 | call kernel_io_apic_connect 32 | 33 | sti 34 | -------------------------------------------------------------------------------- /kernel/init/storage.asm: -------------------------------------------------------------------------------- 1 | kernel_init_storage: 2 | mov eax, DRIVER_PCI_CLASS_SUBCLASS_ide 3 | call driver_pci_find_class_and_subclass 4 | jc .ide_end 5 | 6 | call driver_ide_init 7 | 8 | cmp byte [driver_ide_devices_count], STATIC_EMPTY 9 | je .ide_end 10 | 11 | mov cl, 0x04 12 | mov rdi, driver_ide_devices 13 | 14 | .ide_loop: 15 | cmp word [rdi + DRIVER_IDE_STRUCTURE_DEVICE.channel], STATIC_EMPTY 16 | je .ide_next 17 | 18 | push rax 19 | push rcx 20 | push rsi 21 | push rdi 22 | 23 | mov rax, qword [rdi + DRIVER_IDE_STRUCTURE_DEVICE.size_sectors] 24 | shl rax, STATIC_MULTIPLE_BY_512_shift 25 | 26 | mov ecx, kernel_init_string_storage_ide_hd_end - kernel_init_string_storage_ide_hd_path 27 | mov rsi, kernel_init_string_storage_ide_hd_path 28 | call kernel_vfs_path_resolve 29 | mov rbx, qword [rsp] 30 | mov dl, KERNEL_VFS_FILE_TYPE_block_device 31 | call kernel_vfs_file_touch 32 | 33 | mov qword [rdi + KERNEL_VFS_STRUCTURE_KNOT.size], rax 34 | 35 | pop rdi 36 | pop rsi 37 | pop rcx 38 | pop rax 39 | 40 | .ide_next: 41 | inc byte [kernel_init_string_storage_ide_hd_letter] 42 | 43 | add rdi, DRIVER_IDE_STRUCTURE_DEVICE.SIZE 44 | 45 | dec cl 46 | jnz .ide_loop 47 | 48 | .ide_end: 49 | -------------------------------------------------------------------------------- /kernel/init/idt.asm: -------------------------------------------------------------------------------- 1 | struc KERNEL_STRUCTURE_IDT_HEADER 2 | .limit resb 2 3 | .address resb 8 4 | endstruc 5 | 6 | kernel_init_idt: 7 | call kernel_memory_alloc_page 8 | jc kernel_panic_memory 9 | 10 | call kernel_page_drain 11 | mov qword [kernel_idt_header + KERNEL_STRUCTURE_IDT_HEADER.address], rdi 12 | 13 | mov rax, kernel_idt_exception_default 14 | mov bx, KERNEL_IDT_TYPE_exception 15 | mov ecx, 32 16 | call kernel_idt_update 17 | 18 | mov rax, kernel_idt_interrupt_hardware 19 | mov bx, KERNEL_IDT_TYPE_irq 20 | mov ecx, 16 21 | call kernel_idt_update 22 | 23 | mov rax, kernel_idt_interrupt_software 24 | mov bx, KERNEL_IDT_TYPE_isr 25 | mov ecx, 208 26 | call kernel_idt_update 27 | 28 | mov eax, 0x0D 29 | mov bx, KERNEL_IDT_TYPE_exception 30 | mov rdi, kernel_idt_exception_general_protection_fault 31 | 32 | mov eax, 0x0E 33 | mov bx, KERNEL_IDT_TYPE_exception 34 | mov rdi, kernel_idt_exception_page_fault 35 | 36 | mov eax, 0x40 37 | mov bx, KERNEL_IDT_TYPE_isr 38 | mov rdi, kernel_service 39 | call kernel_idt_mount 40 | 41 | mov eax, 0xFF 42 | mov bx, KERNEL_IDT_TYPE_irq 43 | mov rdi, kernel_idt_spurious_interrupt 44 | call kernel_idt_mount 45 | 46 | lidt [kernel_idt_header] 47 | -------------------------------------------------------------------------------- /kernel/apic.asm: -------------------------------------------------------------------------------- 1 | KERNEL_APIC_ID_register equ 0x0020 2 | KERNEL_APIC_TP_register equ 0x0080 3 | KERNEL_APIC_EOI_register equ 0x00B0 4 | KERNEL_APIC_LD_register equ 0x00D0 5 | KERNEL_APIC_LD_FLAG_target_cpu equ 0x01000000 6 | KERNEL_APIC_DF_register equ 0x00E0 7 | KERNEL_APIC_DF_FLAG_flat_mode equ 0xFFFFFFFF 8 | KERNEL_APIC_SIV_register equ 0x00F0 9 | KERNEL_APIC_SIV_FLAG_enable_apic equ 00000000000000000000000100000000b 10 | KERNEL_APIC_SIV_FLAG_spurious_vector equ 00000000000000000000000011111111b 11 | KERNEL_APIC_ICL_register equ 0x0300 12 | KERNEL_APIC_ICL_COMMAND_COMPLETE_bit equ 12 13 | KERNEL_APIC_ICH_register equ 0x0310 14 | KERNEL_APIC_LVT_TR_register equ 0x0320 15 | KERNEL_APIC_LVT_TR_FLAG_mask_interrupts equ 00000000000000010000000000000000b 16 | KERNEL_APIC_TICR_register equ 0x0380 17 | KERNEL_APIC_TDC_register equ 0x03E0 18 | KERNEL_APIC_TDC_divide_by_1 equ 0x0B 19 | KERNEL_APIC_TDC_divide_by_16 equ 0x03 20 | 21 | KERNEL_APIC_IRQ_number equ 0x20 22 | 23 | kernel_apic_base_address dq STATIC_EMPTY 24 | kernel_apic_size dq STATIC_EMPTY 25 | 26 | kernel_apic_count db STATIC_EMPTY 27 | 28 | kernel_apic_id_table times 0x0100 db STATIC_EMPTY 29 | 30 | kernel_apic_id_get: 31 | macro_apic_id_get 32 | 33 | ret 34 | 35 | macro_debug "kernel_apic_id_get" 36 | -------------------------------------------------------------------------------- /kernel/init/multiboot.asm: -------------------------------------------------------------------------------- 1 | MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 2 | 3 | MULTIBOOT_HEADER_FLAG_align equ 1 << 0 4 | MULTIBOOT_HEADER_FLAG_memory_map equ 1 << 1 5 | MULTIBOOT_HEADER_FLAG_video equ 1 << 2 6 | MULTIBOOT_HEADER_FLAG_header equ 1 << 16 7 | MULTIBOOT_HEADER_FLAG_default equ MULTIBOOT_HEADER_FLAG_align | MULTIBOOT_HEADER_FLAG_memory_map | MULTIBOOT_HEADER_FLAG_video | MULTIBOOT_HEADER_FLAG_header 8 | 9 | MULTIBOOT_HEADER_CHECKSUM equ -(MULTIBOOT_HEADER_FLAG_default + MULTIBOOT_HEADER_MAGIC) 10 | 11 | struc MULTIBOOT_HEADER 12 | .flags resb 4 13 | .unsupported0 resb 40 14 | .mmap_length resb 4 15 | .mmap_addr resb 4 16 | .unsupported1 resb 36 17 | .framebuffer_addr resb 8 18 | .framebuffer_pitch resb 4 19 | .framebuffer_width resb 4 20 | .framebuffer_height resb 4 21 | .framebuffer_bpp resb 1 22 | .framebuffer_type resb 1 23 | .color_info resb 6 24 | endstruc 25 | 26 | align 0x04 27 | 28 | multiboot_header: 29 | dd MULTIBOOT_HEADER_MAGIC 30 | dd MULTIBOOT_HEADER_FLAG_default 31 | dd MULTIBOOT_HEADER_CHECKSUM 32 | dd multiboot_header 33 | dd init 34 | dd STATIC_EMPTY 35 | dd STATIC_EMPTY 36 | dd init 37 | dd STATIC_EMPTY 38 | dd MULTIBOOT_VIDEO_WIDTH_pixel 39 | dd MULTIBOOT_VIDEO_HEIGHT_pixel 40 | dd KERNEL_VIDEO_DEPTH_bit 41 | 42 | align 0x10 43 | 44 | header_end: 45 | -------------------------------------------------------------------------------- /kernel/thread.asm: -------------------------------------------------------------------------------- 1 | kernel_thread: 2 | push rax 3 | push rbx 4 | push rcx 5 | push rdx 6 | push rdi 7 | push r8 8 | push r11 9 | 10 | call kernel_memory_alloc_page 11 | jc .end 12 | 13 | call kernel_page_drain 14 | 15 | mov rax, KERNEL_STACK_address 16 | mov ebx, KERNEL_PAGE_FLAG_available | KERNEL_PAGE_FLAG_write 17 | mov ecx, KERNEL_STACK_SIZE_byte >> STATIC_DIVIDE_BY_PAGE_shift 18 | mov r11, rdi 19 | call kernel_page_map_logical 20 | 21 | mov rdi, qword [r8] 22 | and di, KERNEL_PAGE_mask 23 | add rdi, KERNEL_PAGE_SIZE_byte - ( STATIC_QWORD_SIZE_byte * 0x05 ) 24 | 25 | mov rax, qword [rsp + STATIC_QWORD_SIZE_byte * 0x02] 26 | stosq 27 | 28 | mov rax, KERNEL_STRUCTURE_GDT.cs_ring0 29 | stosq 30 | 31 | mov rax, KERNEL_TASK_EFLAGS_default 32 | stosq 33 | 34 | mov rax, KERNEL_STACK_pointer 35 | stosq 36 | 37 | mov rax, KERNEL_STRUCTURE_GDT.ds_ring0 38 | stosq 39 | 40 | mov qword [rdi - STATIC_QWORD_SIZE_byte * 0x0B], rsi 41 | 42 | mov rsi, cr3 43 | mov rdi, r11 44 | call kernel_page_merge 45 | 46 | mov bx, KERNEL_TASK_FLAG_active | KERNEL_TASK_FLAG_thread | KERNEL_TASK_FLAG_secured 47 | call kernel_task_add 48 | 49 | .end: 50 | pop rdi 51 | pop r8 52 | pop rdi 53 | pop rdx 54 | pop rcx 55 | pop rbx 56 | pop rax 57 | 58 | ret 59 | 60 | macro_debug "kernel_thread" 61 | -------------------------------------------------------------------------------- /software/shell.asm: -------------------------------------------------------------------------------- 1 | %include "config.asm" 2 | %include "kernel/config.asm" 3 | %include "software/shell/config.asm" 4 | 5 | [BITS 64] 6 | 7 | [DEFAULT REL] 8 | 9 | [ORG SOFTWARE_base_address] 10 | 11 | shell: 12 | mov ecx, shell_string_prompt_end - shell_string_prompt_with_new_line 13 | mov rsi, shell_string_prompt_with_new_line 14 | 15 | mov ax, KERNEL_SERVICE_VIDEO_cursor 16 | int KERNEL_SERVICE 17 | 18 | cmp ebx, STATIC_EMPTY 19 | jne .prompt 20 | 21 | mov ecx, shell_string_prompt_end - shell_string_prompt 22 | mov rsi, shell_string_prompt 23 | 24 | .prompt: 25 | mov ax, KERNEL_SERVICE_VIDEO_string 26 | int KERNEL_SERVICE 27 | 28 | .restart: 29 | xor ebx, ebx 30 | 31 | mov ecx, SHELL_CACHE_SIZE_byte 32 | 33 | mov rsi, shell_cache 34 | 35 | call include_input 36 | jc shell 37 | 38 | call include_string_trim 39 | jc shell 40 | 41 | push rcx 42 | 43 | cmp rsi, shell_cache 44 | je .begin 45 | 46 | mov rdi, shell_cache 47 | rep movsb 48 | 49 | .begin: 50 | pop rcx 51 | 52 | mov rsi, shell_cache 53 | call include_string_word_next 54 | 55 | jmp shell_prompt 56 | 57 | %include "software/shell/data.asm" 58 | %include "software/shell/prompt.asm" 59 | %include "include/input.asm" 60 | %include "include/string_trim.asm" 61 | %include "include/string_word_next.asm" 62 | %include "include/string_compare.asm" 63 | -------------------------------------------------------------------------------- /kernel/macro/copy.asm: -------------------------------------------------------------------------------- 1 | %MACRO macro_copy 0 2 | align STATIC_DWORD_SIZE_byte 3 | 4 | prefetchnta [rsi + 256] 5 | prefetchnta [rsi + 288] 6 | prefetchnta [rsi + 320] 7 | prefetchnta [rsi + 352] 8 | prefetchnta [rsi + 384] 9 | prefetchnta [rsi + 416] 10 | prefetchnta [rsi + 448] 11 | prefetchnta [rsi + 480] 12 | 13 | movdqa xmm0, [rsi] 14 | movdqa xmm1, [rsi + 0x10] 15 | movdqa xmm2, [rsi + 0x20] 16 | movdqa xmm3, [rsi + 0x30] 17 | movdqa xmm4, [rsi + 0x40] 18 | movdqa xmm5, [rsi + 0x50] 19 | movdqa xmm6, [rsi + 0x60] 20 | movdqa xmm7, [rsi + 0x70] 21 | movdqa xmm8, [rsi + 0x80] 22 | movdqa xmm9, [rsi + 0x90] 23 | movdqa xmm10, [rsi + 0xA0] 24 | movdqa xmm11, [rsi + 0xB0] 25 | movdqa xmm12, [rsi + 0xC0] 26 | movdqa xmm13, [rsi + 0xD0] 27 | movdqa xmm14, [rsi + 0xE0] 28 | movdqa xmm15, [rsi + 0xF0] 29 | 30 | movntdq [rdi], xmm0 31 | movntdq [rdi + 0x10], xmm1 32 | movntdq [rdi + 0x20], xmm2 33 | movntdq [rdi + 0x30], xmm3 34 | movntdq [rdi + 0x40], xmm4 35 | movntdq [rdi + 0x50], xmm5 36 | movntdq [rdi + 0x60], xmm6 37 | movntdq [rdi + 0x70], xmm7 38 | movntdq [rdi + 0x80], xmm8 39 | movntdq [rdi + 0x90], xmm9 40 | movntdq [rdi + 0xA0], xmm10 41 | movntdq [rdi + 0xB0], xmm11 42 | movntdq [rdi + 0xC0], xmm12 43 | movntdq [rdi + 0xD0], xmm13 44 | movntdq [rdi + 0xE0], xmm14 45 | movntdq [rdi + 0xF0], xmm15 46 | %ENDMACRO 47 | -------------------------------------------------------------------------------- /kernel/init.asm: -------------------------------------------------------------------------------- 1 | cmp byte [kernel_init_smp_semaphore], STATIC_FALSE 2 | je .entry 3 | 4 | %include "kernel/init/ap.asm" 5 | 6 | .entry: 7 | %include "kernel/init/long_mode.asm" 8 | %include "kernel/init/data.asm" 9 | %include "kernel/init/multiboot.asm" 10 | [BITS 64] 11 | 12 | %include "kernel/init/apic.asm" 13 | 14 | kernel_init: 15 | %include "kernel/init/serial.asm" 16 | %include "kernel/init/video.asm" 17 | %include "kernel/init/memory.asm" 18 | %include "kernel/init/acpi.asm" 19 | %include "kernel/init/page.asm" 20 | %include "kernel/init/gdt.asm" 21 | %include "kernel/init/idt.asm" 22 | %include "kernel/init/rtc.asm" 23 | %include "kernel/init/ps2.asm" 24 | %include "kernel/init/ipc.asm" 25 | %include "kernel/init/vfs.asm" 26 | %include "kernel/init/storage.asm" 27 | %include "kernel/init/network.asm" 28 | %include "kernel/init/task.asm" 29 | %include "kernel/init/services.asm" 30 | 31 | call kernel_init_apic 32 | 33 | mov dword [rsi + KERNEL_APIC_TICR_register], DRIVER_RTC_Hz 34 | 35 | mov dword [rsi + KERNEL_APIC_EOI_register], STATIC_EMPTY 36 | 37 | %include "kernel/init/smp.asm" 38 | 39 | .wait: 40 | mov al, byte [kernel_init_ap_count] 41 | inc al 42 | 43 | cmp al, byte [kernel_apic_count] 44 | jne .wait 45 | 46 | mov byte [kernel_init_semaphore], STATIC_FALSE 47 | 48 | jmp clean 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![aiden banner](.github/banner.png) 2 | 3 | simple operating system written with assembly x86_64 4 | 5 | ## requirements system 6 | - cpu with dual core 7 | - 2MiB RAM 8 | - 3MiB storage 9 | 10 | run test: 11 | 12 | ``` 13 | nasm -f bin kernel/init/boot.asm -o build/boot 14 | nasm -f bin kernel/kernel asm -o build/kernel -dMULTIBOOT_VIDEO_WIDTH_pixel=640 -dMULTIBOOT_VIDEO_HEIGHT_pixel=480 15 | nasm -f bin aiden/aiden -o build/disk.raw -dMULTIBOOT_VIDEO_WIDTH_pixel=640 -dMULTIBOOT_VIDEO_HEIGHT_pixel=480 16 | ``` 17 | 18 | running on qemu: 19 | ``` 20 | qemu-system-x86_64 -drive file=build/disk.raw,media=disk,format=raw -m 2 21 | ``` 22 | 23 | running qemu with configuration 2MiB RAM, 2 logic processor, and disk connected to AHCI controller in port 0 24 | ``` 25 | qemu-system-x86_64 -m 2 -smp 2 -rtc base=localtime -drive file=build/disk.raw,if=none,id=sata0,format=raw -device ich9-ahci,id=ahci -device ide-drive,drive=sata0,bus=ahci.0 26 | ``` 27 | 28 | running qemu with configuration 2MiB RAM, 2 logic processor, and IDE controller 29 | ``` 30 | qemu-system-x86_64 -hda file=build/disk.raw -m 2 -smp 2 -rtc base=localtime 31 | ``` 32 | 33 | 34 | reference: 35 | 36 | - [os dev](https://wiki.osdev.org/Expanded_Main_Page) 37 | - [ascii table](https://www.freecodecamp.org/news/ascii-table-hex-to-ascii-value-character-code-chart-2/) 38 | - [font: canele](addy-dclxvi.github.io) 39 | -------------------------------------------------------------------------------- /kernel/service/date/clock.asm: -------------------------------------------------------------------------------- 1 | service_date_clock: 2 | push rax 3 | push rbx 4 | push rcx 5 | push rdx 6 | push rsi 7 | push rdi 8 | 9 | call driver_rtc_get_date_and_time 10 | mov rax, qword [driver_rtc_date_and_time] 11 | 12 | cmp qword [service_date_clock_last_state], rax 13 | je .end 14 | 15 | mov qword [service_date_clock_last_state], rax 16 | 17 | mov bl, byte [service_date_clock_colon] 18 | xchg bl, byte [service_date_window_taskbar.element_label_clock_char_colon] 19 | mov byte [service_date_clock_colon], bl 20 | 21 | shr rax, STATIC_MOVE_HIGH_TO_AL_shift 22 | and eax, 0xFF 23 | mov ebx, STATIC_NUMBER_SYSTEM_decimal 24 | mov ecx, 0x02 25 | mov dl, STATIC_ASCII_DIGIT_0 26 | mov rdi, service_date_window_taskbar.element_label_clock_string_minute 27 | call include_integer_to_string 28 | 29 | mov rax, qword [service_date_clock_last_state] 30 | 31 | shr rax, STATIC_MOVE_HIGH_TO_AX_shift 32 | and rax, 0xFF 33 | mov dl, STATIC_ASCII_SPACE 34 | mov rdi, service_date_window_taskbar.element_label_clock_string_hour 35 | call include_integer_to_string 36 | 37 | mov rdi, service_date_window_taskbar 38 | mov rsi, service_date_window_taskbar.element_label_clock 39 | call include_unit_element_label 40 | 41 | mov al, SERVICE_RENDER_WINDOW_update 42 | mov rsi, service_date_window_taskbar 43 | int SERVICE_RENDER_IRQ 44 | 45 | .end: 46 | pop rdi 47 | pop rsi 48 | pop rdx 49 | pop rcx 50 | pop rbx 51 | pop rax 52 | 53 | ret 54 | -------------------------------------------------------------------------------- /kernel/init/services.asm: -------------------------------------------------------------------------------- 1 | struc KERNEL_INIT_STRUCTURE_SERVICE 2 | .pointer resb 8 3 | .length resb 1 4 | 5 | .name: 6 | endstruc 7 | 8 | kernel_init_services: 9 | mov rsi, kernel_init_services_list 10 | 11 | .loop: 12 | call kernel_memory_alloc_page 13 | jc kernel_panic_memory 14 | 15 | call kernel_page_drain 16 | 17 | mov rax, KERNEL_STACK_address 18 | mov rbx, KERNEL_PAGE_FLAG_available | KERNEL_PAGE_FLAG_write 19 | mov rcx, KERNEL_STACK_SIZE_byte >> STATIC_DIVIDE_BY_PAGE_shift 20 | mov r11, rdi 21 | call kernel_page_map_logical 22 | 23 | mov rdi, qword [r8] 24 | and di, KERNEL_PAGE_mask 25 | add rdi, KERNEL_PAGE_SIZE_byte - ( STATIC_QWORD_SIZE_byte * 0x05 ) 26 | 27 | mov rax, qword [rsi + KERNEL_INIT_STRUCTURE_SERVICE.pointer] 28 | stosq 29 | 30 | mov rax, KERNEL_STRUCTURE_GDT.cs_ring0 31 | stosq 32 | 33 | mov rax, KERNEL_TASK_EFLAGS_default 34 | stosq 35 | 36 | mov rax, KERNEL_STACK_pointer 37 | stosq 38 | 39 | mov rax, KERNEL_STRUCTURE_GDT.ds_ring0 40 | stosq 41 | 42 | push rsi 43 | 44 | mov rsi, qword [kernel_page_pml4_address] 45 | mov rdi, r11 46 | call kernel_page_merge 47 | 48 | pop rsi 49 | 50 | mov bx, KERNEL_TASK_FLAG_active | KERNEL_TASK_FLAG_service | KERNEL_TASK_FLAG_secured 51 | movzx ecx, byte [rsi + KERNEL_INIT_STRUCTURE_SERVICE.length] 52 | add rsi, KERNEL_INIT_STRUCTURE_SERVICE.name 53 | push rcx 54 | call kernel_task_add 55 | 56 | pop rcx 57 | add rsi, rcx 58 | cmp qword [rsi], STATIC_EMPTY 59 | jne .loop 60 | -------------------------------------------------------------------------------- /kernel/service/tresher.asm: -------------------------------------------------------------------------------- 1 | service_tresher: 2 | call service_tresher_search 3 | 4 | mov r11, qword [rsi + KERNEL_TASK_STRUCTURE.cr3] 5 | 6 | mov rax, KERNEL_MEMORY_HIGH_VIRTUAL_address 7 | 8 | movzx ecx, word [rsi + KERNEL_TASK_STRUCTURE.stack] 9 | 10 | shl rcx, KERNEL_PAGE_SIZE_shift 11 | sub rax, rcx 12 | 13 | shr rcx, KERNEL_PAGE_SIZE_shift 14 | call kernel_memory_release_foreign 15 | 16 | test word [rsi + KERNEL_TASK_STRUCTURE.flags], KERNEL_TASK_FLAG_thread 17 | jnz .pml4 18 | 19 | mov rax, KERNEL_MEMORY_HIGH_VIRTUAL_address 20 | mov rcx, STATIC_MAX_unsigned 21 | call kernel_memory_release_foreign 22 | 23 | .pml4: 24 | mov rdi, r11 25 | call kernel_memory_release_page 26 | 27 | dec qword [kernel_page_paged_count] 28 | 29 | mov word [rsi + KERNEL_TASK_STRUCTURE.flags], STATIC_EMPTY 30 | 31 | dec qword [kernel_task_count] 32 | 33 | inc qword [kernel_task_free] 34 | 35 | jmp service_tresher 36 | 37 | macro_debug "service_tresher" 38 | 39 | service_tresher_search: 40 | push rcx 41 | 42 | mov rsi, qword [kernel_task_address] 43 | 44 | .restart: 45 | mov rcx, STATIC_STRUCTURE_BLOCK.link / KERNEL_TASK_STRUCTURE.SIZE 46 | 47 | .next: 48 | test word [rsi + KERNEL_TASK_STRUCTURE.flags], KERNEL_TASK_FLAG_closed 49 | jnz .found 50 | 51 | add rsi, KERNEL_TASK_STRUCTURE.SIZE 52 | 53 | dec rcx 54 | jnz .next 55 | 56 | and si, KERNEL_PAGE_mask 57 | mov rsi, qword [rsi + STATIC_STRUCTURE_BLOCK.link] 58 | jmp .restart 59 | 60 | .found: 61 | pop rcx 62 | 63 | ret 64 | 65 | macro_debug "service_tresher_search" 66 | -------------------------------------------------------------------------------- /software/shell/prompt.asm: -------------------------------------------------------------------------------- 1 | shell_prompt_clean: 2 | 3 | add rsi, rbx 4 | sub r8, rbx 5 | 6 | mov rcx, r8 7 | call include_string_trim 8 | 9 | mov r8, rcx 10 | 11 | .error: 12 | ret 13 | 14 | shell_prompt: 15 | mov r8, rcx 16 | 17 | cmp rbx, shell_command_clean_end - shell_command_clean 18 | jne .no_clean 19 | 20 | mov ecx, ebx 21 | mov rdi, shell_command_clean 22 | call include_string_compare 23 | jc .no_clean 24 | 25 | mov ax, KERNEL_SERVICE_VIDEO_clean 26 | int KERNEL_SERVICE 27 | 28 | jmp shell 29 | 30 | .no_clean: 31 | cmp rbx, shell_command_exit_end - shell_command_exit 32 | jne .no_exit 33 | 34 | mov ecx, ebx 35 | mov rdi, shell_command_exit 36 | call include_string_compare 37 | jc .no_exit 38 | 39 | xor ax, ax 40 | int KERNEL_SERVICE 41 | 42 | .no_exit: 43 | mov ax, KERNEL_SERVICE_VFS_exist 44 | add r8, shell_exec_path_end - shell_exec_path 45 | mov rcx, r8 46 | mov rsi, shell_exec_path 47 | int KERNEL_SERVICE 48 | jc .error 49 | 50 | mov ax, KERNEL_SERVICE_VIDEO_char 51 | mov ecx, 0x01 52 | mov dx, STATIC_ASCII_NEW_LINE 53 | int KERNEL_SERVICE 54 | 55 | mov ax, KERNEL_SERVICE_PROCESS_run 56 | mov rcx, r8 57 | int KERNEL_SERVICE 58 | jc .end 59 | 60 | mov ax, KERNEL_SERVICE_PROCESS_check 61 | 62 | .wait_for_end: 63 | int KERNEL_SERVICE 64 | jnc .wait_for_end 65 | 66 | .end: 67 | jmp shell 68 | 69 | .error: 70 | mov ax, KERNEL_SERVICE_VIDEO_string 71 | mov ecx, shell_command_unknown_end - shell_command_unknown 72 | mov rsi, shell_command_unknown 73 | int KERNEL_SERVICE 74 | 75 | jmp shell 76 | -------------------------------------------------------------------------------- /software/free.asm: -------------------------------------------------------------------------------- 1 | %include "config.asm" 2 | %include "kernel/config.asm" 3 | 4 | [BITS 64] 5 | 6 | [DEFAULT REL] 7 | 8 | [ORG SOFTWARE_base_address] 9 | 10 | free: 11 | mov ax, KERNEL_SERVICE_VIDEO_string 12 | mov ecx, free_string_table_end - free_string_table 13 | mov rsi, free_string_table 14 | int KERNEL_SERVICE 15 | 16 | mov ax, KERNEL_SERVICE_SYSTEM_memory 17 | int KERNEL_SERVICE 18 | 19 | mov ax, KERNEL_SERVICE_VIDEO_cursor 20 | int KERNEL_SERVICE 21 | 22 | mov r15, rbx 23 | 24 | mov ax, KERNEL_SERVICE_VIDEO_number 25 | mov bl, STATIC_NUMBER_SYSTEM_decimal 26 | xor ecx, ecx 27 | shl r8, STATIC_MULTIPLE_BY_4_shift 28 | int KERNEL_SERVICE 29 | 30 | call free_column_fill 31 | 32 | shl r9, STATIC_MULTIPLE_BY_4_shift 33 | sub r8, r9 34 | int KERNEL_SERVICE 35 | 36 | call free_column_fill 37 | 38 | mov r8, r9 39 | int KERNEL_SERVICE 40 | 41 | call free_column_fill 42 | 43 | mov r8, r10 44 | shl r8, STATIC_MULTIPLE_BY_4_shift 45 | int KERNEL_SERVICE 46 | 47 | call free_column_fill 48 | 49 | xor ax, ax 50 | int KERNEL_SERVICE 51 | 52 | free_column_fill: 53 | push rax 54 | push rcx 55 | push rbx 56 | 57 | mov ax, KERNEL_SERVICE_VIDEO_string 58 | mov ecx, free_string_kib_end - free_string_kib 59 | mov rsi, free_string_kib 60 | int KERNEL_SERVICE 61 | 62 | add r15, 14 63 | 64 | mov ax, KERNEL_SERVICE_VIDEO_cursor_set 65 | mov rbx, r15 66 | int KERNEL_SERVICE 67 | 68 | pop rbx 69 | pop rcx 70 | pop rax 71 | 72 | ret 73 | 74 | %include "software/free/data.asm" 75 | -------------------------------------------------------------------------------- /kernel/service/visual/init.asm: -------------------------------------------------------------------------------- 1 | call kernel_task_active_pid 2 | mov qword [service_render_pid], rax 3 | 4 | mov ecx, service_render_object_cursor.end - service_render_object_cursor.data 5 | mov rsi, service_render_object_cursor.data 6 | call include_color_alpha_invert 7 | 8 | mov rbx, qword [kernel_video_width_pixel] 9 | mov rcx, qword [kernel_video_size_byte] 10 | mov rdx, qword [kernel_video_height_pixel] 11 | 12 | mov qword [service_render_object_framebuffer + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.size], rcx 13 | mov qword [service_render_object_framebuffer + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.width], rbx 14 | mov qword [service_render_object_framebuffer + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.height], rdx 15 | 16 | mov rdi, qword [kernel_video_base_address] 17 | 18 | mov qword [service_render_object_framebuffer + SERVICE_RENDER_STRUCTURE_OBJECT.address], rdi 19 | 20 | call kernel_memory_alloc_page 21 | call kernel_page_drain 22 | mov qword [service_render_object_list_address], rdi 23 | 24 | call kernel_memory_alloc_page 25 | call kernel_page_drain 26 | mov qword [service_render_fill_list_address], rdi 27 | 28 | call kernel_memory_alloc_page 29 | call kernel_page_drain 30 | mov qword [service_render_zone_list_address], rdi 31 | 32 | mov rax, SERVICE_RENDER_IRQ 33 | mov bx, KERNEL_IDT_TYPE_isr 34 | mov rdi, service_render_irq 35 | call kernel_idt_mount 36 | 37 | mov byte [service_render_semaphore], STATIC_TRUE 38 | 39 | .wait: 40 | cmp qword [service_render_object_list_records], STATIC_EMPTY 41 | je .wait 42 | -------------------------------------------------------------------------------- /kernel/init/vfs.asm: -------------------------------------------------------------------------------- 1 | struc KERNEL_INIT_STRUCTURE_VFS_FILE 2 | .data_pointer resb 8 3 | .size resb 8 4 | .length resb 1 5 | .path: 6 | .SIZE: 7 | endstruc 8 | 9 | kernel_init_vfs: 10 | call kernel_memory_alloc_page 11 | jc kernel_panic_memory 12 | 13 | call kernel_page_drain 14 | mov qword [kernel_vfs_magicknot + KERNEL_VFS_STRUCTURE_MAGICKNOT.root], rdi 15 | 16 | mov rdi, kernel_vfs_magicknot 17 | 18 | mov rsi, rdi 19 | call kernel_vfs_dir_symlinks 20 | 21 | mov rsi, kernel_init_vfs_directory_structure 22 | 23 | .dir: 24 | movzx ecx, byte [rsi] 25 | 26 | test cl, cl 27 | jz .next 28 | 29 | inc rsi 30 | 31 | push rcx 32 | push rsi 33 | 34 | call kernel_vfs_path_resolve 35 | 36 | mov dl, KERNEL_VFS_FILE_TYPE_directory 37 | call kernel_vfs_file_touch 38 | 39 | pop rsi 40 | pop rcx 41 | 42 | add rsi, rcx 43 | 44 | jmp .dir 45 | 46 | .next: 47 | mov rsi, kernel_init_vfs_files 48 | 49 | .file: 50 | cmp qword [rsi], STATIC_EMPTY 51 | je .end 52 | 53 | push rsi 54 | 55 | movzx ecx, byte [rsi + KERNEL_INIT_STRUCTURE_VFS_FILE.length] 56 | mov dl, KERNEL_VFS_FILE_TYPE_regular_file 57 | add rsi, KERNEL_INIT_STRUCTURE_VFS_FILE.path 58 | call kernel_vfs_path_resolve 59 | call kernel_vfs_file_touch 60 | 61 | mov rsi, qword [rsp] 62 | mov rcx, qword [rsi + KERNEL_INIT_STRUCTURE_VFS_FILE.size] 63 | mov rsi, qword [rsi + KERNEL_INIT_STRUCTURE_VFS_FILE.data_pointer] 64 | call kernel_vfs_file_append 65 | 66 | pop rsi 67 | 68 | movzx ecx, byte [rsi + KERNEL_INIT_STRUCTURE_VFS_FILE.length] 69 | add rsi, rcx 70 | add rsi, KERNEL_INIT_STRUCTURE_VFS_FILE.SIZE 71 | 72 | jmp .file 73 | 74 | .end: 75 | -------------------------------------------------------------------------------- /kernel/init/page.asm: -------------------------------------------------------------------------------- 1 | kernel_init_page: 2 | call kernel_memory_alloc_page 3 | jc kernel_panic_memory 4 | 5 | call kernel_page_drain 6 | mov qword [kernel_page_pml4_address], rdi 7 | 8 | inc qword [kernel_page_paged_count] 9 | 10 | mov eax, KERNEL_BASE_address 11 | mov bx, KERNEL_PAGE_FLAG_available | KERNEL_PAGE_FLAG_write 12 | mov rcx, qword [kernel_page_total_count] 13 | mov r11, rdi 14 | call kernel_page_map_physical 15 | jc kernel_panic_memory 16 | 17 | mov rax, KERNEL_STACK_address 18 | mov ecx, KERNEL_STACK_SIZE_byte >> STATIC_DIVIDE_BY_PAGE_shift 19 | call kernel_page_map_logical 20 | jc kernel_panic_memory 21 | 22 | mov rax, qword [kernel_video_base_address] 23 | or bx, KERNEL_PAGE_FLAG_write_through | KERNEL_PAGE_FLAG_cache_disable 24 | mov rcx, qword [kernel_video_size_byte] 25 | call include_page_from_size 26 | call kernel_page_map_physical 27 | jc kernel_panic_memory 28 | 29 | mov rax, qword [kernel_apic_base_address] 30 | mov bx, KERNEL_PAGE_FLAG_available | KERNEL_PAGE_FLAG_write 31 | mov ecx, dword [kernel_apic_size] 32 | call include_page_from_size 33 | call kernel_page_map_physical 34 | jc kernel_panic_memory 35 | 36 | mov eax, dword [kernel_io_apic_base_address] 37 | mov ecx, KERNEL_PAGE_SIZE_byte >> KERNEL_PAGE_SIZE_shift 38 | call kernel_page_map_physical 39 | jc kernel_panic_memory 40 | 41 | mov eax, 0x8000 42 | mov ecx, kernel_init_boot_file_end - kernel_init_boot_file 43 | call include_page_from_size 44 | call kernel_page_map_physical 45 | jc kernel_panic_memory 46 | 47 | mov rax, rdi 48 | mov cr3, rax 49 | 50 | mov rsp, KERNEL_STACK_pointer 51 | -------------------------------------------------------------------------------- /kernel/init/smp.asm: -------------------------------------------------------------------------------- 1 | kernel_init_smp: 2 | cmp word [kernel_apic_count], STATIC_TRUE 3 | jbe .finish 4 | 5 | mov ecx, kernel_init_boot_file_end - kernel_init_boot_file 6 | mov rsi, kernel_init_boot_file 7 | mov rdi, 0x8000 8 | rep movsb 9 | 10 | mov byte [kernel_init_smp_semaphore], STATIC_TRUE 11 | 12 | mov rdi, qword [kernel_apic_base_address] 13 | mov eax, dword [rdi + KERNEL_APIC_ID_register] 14 | shr eax, 24 15 | 16 | mov dl, al 17 | 18 | mov rsi, kernel_apic_id_table 19 | 20 | mov cx, word [kernel_apic_count] 21 | 22 | .init: 23 | dec cx 24 | js .init_done 25 | 26 | lodsb 27 | 28 | cmp al, dl 29 | je .init 30 | 31 | shl eax, 24 32 | mov dword [rdi + KERNEL_APIC_ICH_register], eax 33 | mov eax, 0x00004500 34 | mov dword [rdi + KERNEL_APIC_ICL_register], eax 35 | 36 | .init_wait: 37 | bt dword [rdi + KERNEL_APIC_ICL_register], KERNEL_APIC_ICL_COMMAND_COMPLETE_bit 38 | jc .init_wait 39 | 40 | jmp .init 41 | 42 | .init_done: 43 | mov rax, qword [driver_rtc_microtime] 44 | add rax, 10 45 | 46 | .init_wait_for_ipi: 47 | cmp rax, qword [driver_rtc_microtime] 48 | ja .init_wait_for_ipi 49 | 50 | mov rsi, kernel_apic_id_table 51 | 52 | mov cx, word [kernel_apic_count] 53 | 54 | .start: 55 | dec cx 56 | js .finish 57 | 58 | lodsb 59 | 60 | cmp al, dl 61 | je .start 62 | 63 | shl eax, 24 64 | mov dword [rdi + KERNEL_APIC_ICH_register], eax 65 | mov eax, 0x00004608 66 | mov dword [rdi + KERNEL_APIC_ICL_register], eax 67 | 68 | .start_wait: 69 | bt dword [rdi + KERNEL_APIC_ICL_register], KERNEL_APIC_ICL_COMMAND_COMPLETE_bit 70 | jc .start_wait 71 | 72 | jmp .start 73 | 74 | .finish: 75 | -------------------------------------------------------------------------------- /include/color.asm: -------------------------------------------------------------------------------- 1 | include_color_alpha: 2 | push rbx 3 | push rcx 4 | push rdx 5 | 6 | push STATIC_EMPTY 7 | 8 | movzx rbx, byte [rsi + 0x03] 9 | 10 | not bl 11 | inc bl 12 | 13 | movzx rax, byte [rsi + 0x02] 14 | 15 | mul bl 16 | mov cl, STATIC_BYTE_mask 17 | xor dl, dl 18 | div cl 19 | 20 | mov byte [rsp + 0x02], al 21 | 22 | mov al, byte [rsi + 0x01] 23 | 24 | mul bl 25 | xor dl, dl 26 | div cl 27 | 28 | mov byte [rsp + 0x01], al 29 | 30 | mov al, byte [rsi] 31 | 32 | mul bl 33 | xor dl, dl 34 | div cl 35 | 36 | mov byte [rsp], al 37 | 38 | sub bl, STATIC_BYTE_mask 39 | not bl 40 | inc bl 41 | 42 | mov al, byte [rdi + 0x02] 43 | 44 | mul bl 45 | xor dl, dl 46 | div cl 47 | 48 | add byte [rsp + 0x02], al 49 | 50 | mov al, byte [rdi + 0x01] 51 | 52 | mul bl 53 | xor dl, dl 54 | div cl 55 | 56 | add byte [rsp + 0x01], al 57 | 58 | mov al, byte [rdi] 59 | 60 | mul bl 61 | xor dl, dl 62 | div cl 63 | 64 | add byte [rsp], al 65 | 66 | pop rax 67 | 68 | pop rdx 69 | pop rcx 70 | pop rbx 71 | 72 | ret 73 | 74 | macro_debug "include_color_alpha" 75 | 76 | include_color_alpha_invert: 77 | push rax 78 | push rcx 79 | push rsi 80 | 81 | shr rcx, KERNEL_VIDEO_DEPTH_shift 82 | 83 | .loop: 84 | mov al, byte [rsi + 0x03] 85 | 86 | test al, al 87 | jz .invisible 88 | 89 | dec al 90 | 91 | .invisible: 92 | not al 93 | 94 | mov byte [rsi + 0x03], al 95 | 96 | add rsi, KERNEL_VIDEO_DEPTH_byte 97 | 98 | dec rcx 99 | jnz .loop 100 | 101 | pop rsi 102 | pop rcx 103 | pop rax 104 | 105 | ret 106 | 107 | macro_debug "include_color_alpha_invert" 108 | -------------------------------------------------------------------------------- /kernel/service/visual/ipc.asm: -------------------------------------------------------------------------------- 1 | service_render_ipc_mouse: 2 | push rax 3 | push rbx 4 | push rcx 5 | push rsi 6 | 7 | mov rax, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.id] 8 | mov rbx, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.pid] 9 | 10 | sub r8, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.x] 11 | sub r9, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.y] 12 | 13 | mov rsi, service_render_ipc_data 14 | 15 | mov byte [rsi + SERVICE_RENDER_STRUCTURE_IPC.type], cl 16 | 17 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_IPC.id], rax 18 | 19 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_IPC.value0], r8 20 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_IPC.value1], r9 21 | 22 | xor ecx, ecx 23 | call kernel_ipc_insert 24 | 25 | pop rsi 26 | pop rcx 27 | pop rbx 28 | pop rax 29 | 30 | ret 31 | 32 | macro_debug "service_render_ipc_mouse" 33 | 34 | service_render_ipc_keyboard: 35 | push rbx 36 | push rcx 37 | push rdx 38 | push rsi 39 | 40 | mov rdx, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.id] 41 | mov rbx, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.pid] 42 | 43 | mov rsi, service_render_ipc_data 44 | 45 | mov byte [rsi + SERVICE_RENDER_STRUCTURE_IPC.type], cl 46 | 47 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_IPC.id], rdx 48 | 49 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_IPC.value0],rax 50 | 51 | xor ecx, ecx 52 | call kernel_ipc_insert 53 | 54 | pop rsi 55 | pop rdx 56 | pop rcx 57 | pop rbx 58 | 59 | ret 60 | 61 | macro_debug "service_render_ipc_keyboard" 62 | -------------------------------------------------------------------------------- /kernel/init/memory.asm: -------------------------------------------------------------------------------- 1 | KERNEL_INIT_MEMORY_MULTIBOOT_FLAG_memory_map equ 6 2 | 3 | struc KERNEL_INIT_MEMORY_MULTIBOOT_STRUCTURE_MEMORY_MAP 4 | .size resb 4 5 | .address resb 8 6 | .limit resb 8 7 | .type resb 4 8 | 9 | .SIZE: 10 | endstruc 11 | 12 | kernel_init_memory: 13 | mov rsi, kernel_init_string_error_memory_header 14 | 15 | bt dword [ebx + MULTIBOOT_HEADER.flags], KERNEL_INIT_MEMORY_MULTIBOOT_FLAG_memory_map 16 | jnc kernel_panic 17 | 18 | mov ecx, dword [ebx + MULTIBOOT_HEADER.mmap_length] 19 | mov ebx, dword [ebx + MULTIBOOT_HEADER.mmap_addr] 20 | 21 | .search: 22 | cmp qword [ebx + KERNEL_INIT_MEMORY_MULTIBOOT_STRUCTURE_MEMORY_MAP.address], KERNEL_BASE_address 23 | je .found 24 | 25 | add ebx, KERNEL_INIT_MEMORY_MULTIBOOT_STRUCTURE_MEMORY_MAP.SIZE 26 | 27 | sub ecx, KERNEL_INIT_MEMORY_MULTIBOOT_STRUCTURE_MEMORY_MAP.SIZE 28 | jnz .search 29 | 30 | mov rsi, kernel_init_string_error_memory 31 | call kernel_panic 32 | 33 | .found: 34 | mov rcx, qword [rbx + KERNEL_INIT_MEMORY_MULTIBOOT_STRUCTURE_MEMORY_MAP.limit] 35 | shr rcx, STATIC_DIVIDE_BY_PAGE_shift 36 | 37 | mov qword [kernel_page_total_count], rcx 38 | mov qword [kernel_page_free_count], rcx 39 | 40 | mov rdi, kernel_end 41 | call include_page_align_up 42 | 43 | mov qword [kernel_memory_map_address], rdi 44 | 45 | shr rcx, STATIC_DIVIDE_BY_8_shift 46 | 47 | push rcx 48 | 49 | call include_page_from_size 50 | call kernel_page_drain_few 51 | 52 | pop rcx 53 | 54 | mov al, STATIC_MAX_unsigned 55 | rep stosb 56 | 57 | mov qword [kernel_memory_map_address_end], rdi 58 | 59 | call include_page_align_up 60 | sub rdi, KERNEL_BASE_address 61 | shr rdi, STATIC_DIVIDE_BY_PAGE_shift 62 | 63 | mov rcx, rdi 64 | mov rsi, qword [kernel_memory_map_address] 65 | call kernel_memory_secure 66 | -------------------------------------------------------------------------------- /kernel/kernel.asm: -------------------------------------------------------------------------------- 1 | %include "config.asm" 2 | %include "kernel/config.asm" 3 | %include "kernel/macro/apic.asm" 4 | 5 | [BITS 32] 6 | 7 | [ORG KERNEL_BASE_address] 8 | 9 | init: 10 | %include "kernel/init.asm" 11 | 12 | align KERNEL_PAGE_SIZE_byte, db STATIC_NOTHING 13 | 14 | clean: 15 | mov ecx, clean - $$ 16 | mov rdi, KERNEL_BASE_address 17 | call include_page_from_size 18 | call kernel_memory_release 19 | 20 | kernel: 21 | call kernel_task_active 22 | 23 | mov word [rdi + KERNEL_TASK_STRUCTURE.flags], STATIC_EMPTY 24 | call include_page_from_size 25 | call kernel_memory_release 26 | 27 | jmp $ 28 | %include "kernel/macro/lock.asm" 29 | %include "kernel/macro/debug.asm" 30 | %include "kernel/macro/copy.asm" 31 | %include "kernel/ipc.asm" 32 | %include "kernel/panic.asm" 33 | %include "kernel/page.asm" 34 | %include "kernel/memory.asm" 35 | %include "kernel/apic.asm" 36 | %include "kernel/io_apic.asm" 37 | %include "kernel/data.asm" 38 | %include "kernel/idt.asm" 39 | %include "kernel/task.asm" 40 | %include "kernel/vfs.asm" 41 | %include "kernel/exec.asm" 42 | %include "kernel/service.asm" 43 | %include "kernel/driver/rtc.asm" 44 | %include "kernel/driver/ps2.asm" 45 | %include "kernel/driver/pci.asm" 46 | %include "kernel/driver/network/i82540em.asm" 47 | %include "kernel/driver/storage/ide.asm" 48 | %include "kernel/driver/serial.asm" 49 | %include "kernel/service/tresher.asm" 50 | %include "kernel/service/http.asm" 51 | %include "kernel/service/tx.asm" 52 | %include "kernel/service/network.asm" 53 | %include "kernel/service/render.asm" 54 | %include "kernel/service/date.asm" 55 | %include "include/color.asm" 56 | %include "include/integer_to_string.asm" 57 | %include "include/page_align_up.asm" 58 | %include "include/page_from_size.asm" 59 | %include "include/string_compare.asm" 60 | %include "include/string_cut.asm" 61 | 62 | kernel_end: 63 | -------------------------------------------------------------------------------- /kernel/init/ap.asm: -------------------------------------------------------------------------------- 1 | lgdt [kernel_gdt_header] 2 | 3 | mov eax, 1010100000b 4 | mov cr4, eax 5 | 6 | mov eax, dword [kernel_page_pml4_address] 7 | mov cr3, eax 8 | 9 | mov ecx, 0xC0000080 10 | rdmsr 11 | or eax, 100000000b 12 | wrmsr 13 | 14 | mov eax, cr0 15 | or eax, 0x80000001 16 | mov cr0, eax 17 | 18 | jmp 0x0008:.long_mode 19 | 20 | [BITS 64] 21 | 22 | .long_mode: 23 | mov rax, qword [kernel_apic_base_address] 24 | mov dword [rax + KERNEL_APIC_TP_register], STATIC_EMPTY 25 | mov eax, dword [rax + KERNEL_APIC_ID_register] 26 | shr eax, 24 27 | 28 | shl eax, STATIC_MULTIPLE_BY_16_shift 29 | add ax, word [kernel_gdt_tss_bsp_selector] 30 | mov word [kernel_gdt_tss_cpu_selector], ax 31 | ltr word [kernel_gdt_tss_cpu_selector] 32 | 33 | lidt [kernel_idt_header] 34 | 35 | .wait: 36 | mov al, STATIC_TRUE 37 | lock xchg byte [kernel_init_ap_semaphore], al 38 | test al, al 39 | jz .wait 40 | 41 | mov rsp, KERNEL_STACK_TEMPORARY_pointer 42 | 43 | call kernel_memory_alloc_page 44 | jc kernel_panic_memory 45 | 46 | call kernel_page_drain 47 | 48 | inc qword [kernel_page_paged_count] 49 | 50 | mov rax, KERNEL_STACK_address 51 | mov ebx, KERNEL_PAGE_FLAG_available | KERNEL_PAGE_FLAG_write 52 | mov ecx, KERNEL_STACK_SIZE_byte >> STATIC_DIVIDE_BY_PAGE_shift 53 | mov r11, rdi 54 | xor ebp, ebp 55 | call kernel_page_map_logical 56 | 57 | mov rsi, qword [kernel_page_pml4_address] 58 | call kernel_page_merge 59 | 60 | mov rax, rdi 61 | mov cr3, rax 62 | 63 | mov rsp, KERNEL_STACK_pointer 64 | 65 | mov byte [kernel_init_ap_semaphore], STATIC_FALSE 66 | 67 | call kernel_init_apic 68 | 69 | cld 70 | 71 | call kernel_apic_id_get 72 | 73 | mov rbx, rax 74 | shl rbx, STATIC_MULTIPLE_BY_8_shift 75 | mov rsi, qword [kernel_task_active_list] 76 | 77 | mov rdi, qword [kernel_task_address] 78 | 79 | inc byte [kernel_init_ap_count] 80 | 81 | jmp kernel_task.ap_entry 82 | -------------------------------------------------------------------------------- /software/console/init.asm: -------------------------------------------------------------------------------- 1 | ; Initialize video properties and adjust the console window position 2 | mov ax, KERNEL_SERVICE_VIDEO_properties 3 | int KERNEL_SERVICE 4 | 5 | shr r8, STATIC_DIVIDE_BY_2_shift ; Divide screen width by 2 6 | shr r9, STATIC_DIVIDE_BY_2_shift ; Divide screen height by 2 7 | 8 | ; Calculate window's X position and center it 9 | mov rax, qword [console_window + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 10 | shr rax, STATIC_DIVIDE_BY_2_shift 11 | sub r8, rax 12 | mov qword [console_window + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.x], r8 13 | 14 | ; Calculate window's Y position and center it 15 | mov rax, qword [console_window + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.height] 16 | shr rax, STATIC_DIVIDE_BY_2_shift 17 | sub r9, rax 18 | mov qword [console_window + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.y], r9 19 | 20 | ; Initialize the unit structure for the console window 21 | mov rsi, console_window 22 | call include_unit 23 | 24 | ; Compute the starting address of the terminal buffer 25 | mov rax, qword [console_window.element_terminal + INCLUDE_UNIT_STRUCTURE_ELEMENT_DRAW.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.field + INCLUDE_UNIT_STRUCTURE_FIELD.y] 26 | mul qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.scanline] 27 | add rax, qword [console_window + INCLUDE_UNIT_STRUCTURE_WINDOW.address] 28 | 29 | mov qword [console_terminal_table + INCLUDE_TERMINAL_STRUCTURE.address], rax 30 | 31 | ; Initialize the terminal structure 32 | mov r8, console_terminal_table 33 | call include_terminal 34 | 35 | ; Render the window and make it visible 36 | mov al, SERVICE_RENDER_WINDOW_update 37 | or qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.flags], INCLUDE_UNIT_WINDOW_FLAG_visible | INCLUDE_UNIT_WINDOW_FLAG_flush 38 | int SERVICE_RENDER_IRQ 39 | -------------------------------------------------------------------------------- /kernel/init/gdt.asm: -------------------------------------------------------------------------------- 1 | struc KERNEL_STRUCTURE_GDT_HEADER 2 | .limit resb 2 3 | .address resb 8 4 | endstruc 5 | 6 | struc KERNEL_STRUCTURE_GDT 7 | .null resb 8 8 | .cs_ring0 resb 8 9 | .ds_ring0 resb 8 10 | .cs_ring3 resb 8 11 | .ds_ring3 resb 8 12 | .tss resb 8 13 | 14 | .SIZE: 15 | endstruc 16 | 17 | kernel_init_gdt: 18 | call kernel_memory_alloc_page 19 | jc kernel_panic_memory 20 | 21 | call kernel_page_drain 22 | mov qword [kernel_gdt_header + KERNEL_STRUCTURE_GDT_HEADER.address], rdi 23 | 24 | xor eax, eax 25 | stosq 26 | 27 | mov rax, 0000000000100000100110000000000000000000000000000000000000000000b 28 | stosq 29 | 30 | mov rax, 0000000000100000100100100000000000000000000000000000000000000000b 31 | stosq 32 | 33 | mov rax, 0000000000100000111110000000000000000000000000000000000000000000b 34 | stosq 35 | 36 | mov rax, 0000000000100000111100100000000100000000000000000000000000000000b 37 | stosq 38 | 39 | and di, ~KERNEL_PAGE_mask 40 | mov word [kernel_gdt_tss_bsp_selector], di 41 | 42 | mov cx, word [kernel_apic_count] 43 | mov rsi, kernel_apic_id_table 44 | 45 | .loop: 46 | lodsb 47 | 48 | and eax, STATIC_BYTE_mask 49 | shl eax, STATIC_MULTIPLE_BY_16_shift 50 | 51 | mov rdi, qword [kernel_gdt_header + KERNEL_STRUCTURE_GDT_HEADER.address] 52 | add rdi, rax 53 | add di, word [kernel_gdt_tss_bsp_selector] 54 | 55 | mov ax, kernel_gdt_tss_table_end - kernel_gdt_tss_table 56 | stosw 57 | 58 | mov rax, kernel_gdt_tss_table 59 | stosw 60 | shr rax, 16 61 | stosb 62 | 63 | push rax 64 | 65 | mov al, 10001001b 66 | stosb 67 | xor al, al 68 | stosb 69 | 70 | pop rax 71 | 72 | shr rax, 8 73 | stosb 74 | 75 | shr rax, 8 76 | stosd 77 | 78 | xor rax, rax 79 | stosd 80 | 81 | dec cx 82 | jnz .loop 83 | 84 | lgdt [kernel_gdt_header] 85 | 86 | ltr word [kernel_gdt_tss_bsp_selector] 87 | 88 | mov fs, ax 89 | mov gs, ax 90 | 91 | mov ax, KERNEL_STRUCTURE_GDT.ds_ring0 92 | mov ds, ax 93 | mov es, ax 94 | mov ss, ax 95 | -------------------------------------------------------------------------------- /kernel/service/http.asm: -------------------------------------------------------------------------------- 1 | %define SERVICE_HTTP_version "1" 2 | %define SERVICE_HTTP_revision "0" 3 | 4 | %MACRO service_http_macro_foot 0 5 | db "
", STATIC_ASCII_NEW_LINE 6 | db "Aiden Operating System v", KERNEL_version, ".", KERNEL_revision, " (HTTP Service v", SERVICE_HTTP_version, ".", SERVICE_HTTP_revision, ")" 7 | db "", STATIC_ASCII_NEW_LINE 8 | %ENDMACRO 9 | 10 | service_http_ipc_message: 11 | times KERNEL_IPC_STRUCTURE.SIZE db STATIC_EMPTY 12 | 13 | service_http: 14 | mov cx, 80 15 | call service_network_tcp_port_assign 16 | jc service_http 17 | 18 | .loop: 19 | mov rdi, service_http_ipc_message 20 | call kernel_ipc_receive 21 | jc .loop 22 | 23 | mov rbx, qword [rdi + KERNEL_IPC_STRUCTURE.other] 24 | 25 | mov ecx, service_http_get_root_end - service_http_get_root 26 | mov rsi, qword [rdi + KERNEL_IPC_STRUCTURE.pointer] 27 | mov rdi, service_http_get_root 28 | call include_string_compare 29 | jc .no 30 | 31 | mov ecx, service_http_200_default_end - service_http_200_default 32 | mov rsi, service_http_200_default 33 | 34 | jmp .answer 35 | 36 | .no: 37 | mov ecx, service_http_404_end - service_http_404 38 | mov rsi, service_http_404 39 | 40 | .answer: 41 | call service_network_tcp_port_send 42 | 43 | jmp $ 44 | 45 | service_http_get_root db "GET / " 46 | 47 | service_http_get_root_end: 48 | 49 | service_http_200_default db "HTTP/1.0 200 OK", STATIC_ASCII_NEW_LINE 50 | db "Content-Type: text/html", STATIC_ASCII_NEW_LINE 51 | db STATIC_ASCII_NEW_LINE 52 | db 'Hello, World!', STATIC_ASCII_NEW_LINE 53 | service_http_macro_foot 54 | 55 | service_http_200_default_end: 56 | 57 | service_http_404 db "HTTP/1.0 404 Not Found", STATIC_ASCII_NEW_LINE 58 | db "Content-Type: text/html", STATIC_ASCII_NEW_LINE 59 | db STATIC_ASCII_NEW_LINE 60 | db "404 Content not found.", STATIC_ASCII_NEW_LINE 61 | service_http_macro_foot 62 | 63 | service_http_404_end: 64 | -------------------------------------------------------------------------------- /kernel/service/network/checksum.asm: -------------------------------------------------------------------------------- 1 | service_network_checksum: 2 | ; Save registers 3 | push rbx 4 | push rcx 5 | push rdi 6 | 7 | ; Clear RBX and exchange RAX with RBX (RAX now holds the initial checksum value, RBX is cleared) 8 | xor ebx, ebx 9 | xchg rbx, rax 10 | 11 | .calculate: 12 | ; Load a word (2 bytes) from the memory pointed to by RDI into AX 13 | mov ax, word [rdi] 14 | ; Rotate the bits in AX left by 8 (swap high and low bytes) 15 | rol ax, STATIC_REPLACE_AL_WITH_HIGH_shift 16 | 17 | ; Add the rotated word to the checksum in RBX 18 | add rbx, rax 19 | 20 | ; Move RDI to the next word (2 bytes) in memory 21 | add rdi, STATIC_WORD_SIZE_byte 22 | 23 | ; Loop until RCX reaches 0 24 | loop .calculate 25 | 26 | ; Fold the 32-bit checksum in RBX into a 16-bit checksum in AX 27 | mov ax, bx ; Move the lower 16 bits of RBX into AX 28 | shr ebx, STATIC_MOVE_HIGH_TO_AX_shift ; Shift the upper 16 bits of RBX into BX 29 | add rax, rbx ; Add the upper 16 bits to AX 30 | 31 | ; Take the one's complement of the checksum in AX 32 | not ax 33 | 34 | ; Restore registers 35 | pop rdi 36 | pop rcx 37 | pop rbx 38 | 39 | ; Return from the function 40 | ret 41 | 42 | ; Debug macro to mark the end of the checksum function 43 | macro_debug "service_network_checksum" 44 | 45 | service_network_checksum_part: 46 | ; Save registers 47 | push rbx 48 | push rcx 49 | push rdi 50 | 51 | ; Clear RBX 52 | xor ebx, ebx 53 | 54 | .calculate: 55 | ; Load a word (2 bytes) from the memory pointed to by RDI into BX 56 | mov bx, word [rdi] 57 | ; Rotate the bits in BX left by 8 (swap high and low bytes) 58 | rol bx, STATIC_REPLACE_AL_WITH_HIGH_shift 59 | 60 | ; Add the rotated word to the checksum in RAX 61 | add rax, rbx 62 | 63 | ; Move RDI to the next word (2 bytes) in memory 64 | add rdi, STATIC_WORD_SIZE_byte 65 | 66 | ; Loop until RCX reaches 0 67 | loop .calculate 68 | 69 | ; Restore registers 70 | pop rdi 71 | pop rcx 72 | pop rbx 73 | 74 | ; Return from the function 75 | ret 76 | 77 | ; Debug macro to mark the end of the partial checksum function 78 | macro_debug "service_network_checksum_part" -------------------------------------------------------------------------------- /kernel/service/visual/service.asm: -------------------------------------------------------------------------------- 1 | service_render_irq: 2 | cmp byte [service_render_semaphore], STATIC_FALSE 3 | je service_render_irq 4 | 5 | push rax 6 | 7 | cld 8 | 9 | cmp al, SERVICE_RENDER_WINDOW_create 10 | je .window_create 11 | 12 | cmp al, SERVICE_RENDER_WINDOW_update 13 | je .window_update 14 | 15 | .error: 16 | stc 17 | 18 | .end: 19 | pushf 20 | pop rax 21 | 22 | and ax, KERNEL_TASK_EFLAGS_cf | KERNEL_TASK_EFLAGS_zf 23 | or word [rsp + KERNEL_TASK_STRUCTURE_IRETQ.eflags + STATIC_QWORD_SIZE_byte], ax 24 | 25 | pop rax 26 | 27 | iretq 28 | 29 | macro_debug "service_render_irq" 30 | 31 | .window_create: 32 | push rsi 33 | push rdi 34 | 35 | mov rcx, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.size] 36 | call include_page_from_size 37 | call kernel_memory_alloc 38 | 39 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.address], rdi 40 | 41 | call kernel_memory_mark 42 | 43 | call service_render_object_id_new 44 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.id], rcx 45 | 46 | call service_render_object_insert 47 | 48 | pop rdi 49 | pop rsi 50 | 51 | jmp service_render_irq.end 52 | 53 | macro_debug "service_render_irq.window_create" 54 | 55 | .window_update: 56 | push rax 57 | push rbx 58 | push rsi 59 | 60 | mov rbx, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.id] 61 | call service_render_object_by_id 62 | 63 | call kernel_task_active_pid 64 | 65 | cmp rax, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.pid] 66 | jne .window_flags_error 67 | 68 | mov rbx, qword [rsp] 69 | 70 | mov rax, qword [rbx + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags] 71 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags], rax 72 | 73 | jmp .window_flags_end 74 | 75 | .window_flags_error: 76 | stc 77 | 78 | .window_flags_end: 79 | pop rsi 80 | pop rbx 81 | pop rax 82 | 83 | jmp service_render_irq.end 84 | 85 | macro_debug "service_render_irq.window_update" 86 | -------------------------------------------------------------------------------- /kernel/idt.asm: -------------------------------------------------------------------------------- 1 | KERNEL_IDT_IRQ_offset equ 0x20 2 | 3 | KERNEL_IDT_TYPE_exception equ 0x8E00 4 | KERNEL_IDT_TYPE_irq equ 0x8F00 5 | KERNEL_IDT_TYPE_isr equ 0xEF00 6 | 7 | kernel_idt_mount: 8 | push rax 9 | push rbx 10 | push rcx 11 | push rdi 12 | 13 | xchg rax, rdi 14 | 15 | shl rdi, STATIC_MULTIPLE_BY_16_shift 16 | add rdi, qword [kernel_idt_header + KERNEL_STRUCTURE_IDT_HEADER.address] 17 | 18 | mov rcx, 1 19 | call kernel_idt_update 20 | 21 | pop rdi 22 | pop rcx 23 | pop rbx 24 | pop rax 25 | 26 | ret 27 | 28 | macro_debug "kernel_idt_mount" 29 | 30 | kernel_idt_update: 31 | push rcx 32 | 33 | .next: 34 | push rax 35 | 36 | stosw 37 | 38 | mov ax, KERNEL_STRUCTURE_GDT.cs_ring0 39 | stosw 40 | 41 | mov ax, bx 42 | stosw 43 | mov rax, qword [rsp] 44 | 45 | shr rax, STATIC_MOVE_HIGH_TO_AX_shift 46 | stosw 47 | 48 | shr rax, STATIC_MOVE_HIGH_TO_EAX_shift 49 | stosd 50 | 51 | xor eax, eax 52 | stosd 53 | 54 | pop rax 55 | 56 | dec rcx 57 | jnz .next 58 | 59 | pop rcx 60 | 61 | ret 62 | 63 | macro_debug "kernel_idt_update" 64 | 65 | kernel_idt_exception_default: 66 | xchg bx, bx 67 | 68 | nop 69 | 70 | jmp $ 71 | 72 | macro_debug "kernel_idt_exception_default" 73 | 74 | kernel_idt_exception_general_protection_fault: 75 | xchg bx, bx 76 | 77 | nop 78 | nop 79 | 80 | jmp $ 81 | 82 | macro_debug "kernel_idt_exception_general_protection_fault" 83 | 84 | kernel_idt_exception_page_fault: 85 | push rcx 86 | push rsi 87 | 88 | xchg bx, bx 89 | 90 | nop 91 | nop 92 | nop 93 | 94 | jmp $ 95 | 96 | macro_debug "kernel_idt_exception_page_fault" 97 | 98 | kernel_idt_interrupt_hardware: 99 | push rdi 100 | 101 | mov rdi, qword [kernel_apic_base_address] 102 | mov dword [rdi + KERNEL_APIC_EOI_register], STATIC_EMPTY 103 | 104 | pop rdi 105 | 106 | iretq 107 | 108 | macro_debug "kernel_idt_interrupt_hardware" 109 | 110 | kernel_idt_interrupt_software: 111 | or word [rsp + KERNEL_TASK_STRUCTURE_IRETQ.eflags], KERNEL_TASK_EFLAGS_cf 112 | 113 | iretq 114 | 115 | macro_debug "kernel_idt_interrupt_software" 116 | 117 | kernel_idt_spurious_interrupt: 118 | iretq 119 | 120 | macro_debug "kernel_idt_spurious_interrupt" 121 | -------------------------------------------------------------------------------- /aiden/long_mode.asm: -------------------------------------------------------------------------------- 1 | AIDEN_LONG_MODE_PML4_address equ 0x0000A000 2 | AIDEN_LONG_MODE_PAGE_SIZE_bytes equ 0x1000 * 0x06 3 | 4 | AIDEN_LONG_MODE_PAGE_FLAG_available equ 00000001b 5 | AIDEN_LONG_MODE_PAGE_FLAG_writeable equ 00000010b 6 | AIDEN_LONG_MODE_PAGE_FLAG_2MiB_size equ 10000000b 7 | AIDEN_LONG_MODE_FLAG_default equ AIDEN_LONG_MODE_PAGE_FLAG_available | AIDEN_LONG_MODE_PAGE_FLAG_writeable 8 | 9 | aiden_long_mode: 10 | xor eax, eax 11 | mov ecx, AIDEN_LONG_MODE_PAGE_SIZE_bytes / 0x04 12 | mov edi, AIDEN_LONG_MODE_PML4_address 13 | rep stosd 14 | 15 | mov edi, AIDEN_LONG_MODE_PML4_address 16 | 17 | mov dword [edi], edi 18 | mov dword [edi], 0x1000 + AIDEN_LONG_MODE_PAGE_FLAG_default 19 | 20 | mov dword [edi + 0x1000], edi 21 | add dword [edi + 0x1000], (0x1000 * 0x02) + AIDEN_LONG_MODE_PAGE_FLAG_default 22 | mov dword [edi + 0x1000 + 0x08], edi 23 | add dword [edi + 0x1000 + 0x08], (0x1000 * 0x03) + AIDEN_LONG_MODE_PAGE_FLAG_default 24 | mov dword [edi + 0x1000 + 0x10], edi 25 | add dword [edi + 0x1000 + 0x10], (0x1000 * 0x04) + AIDEN_LONG_MODE_PAGE_FLAG_default 26 | mov dword [edi + 0x1000 + 0x18], edi 27 | add dword [edi + 0x1000 + 0x18], (0x1000 * 0x05) + AIDEN_LONG_MODE_PAGE_FLAG_default 28 | 29 | mov eax, AIDEN_LONG_MODE_PAGE_FLAG_default + AIDEN_LONG_MODE_PAGE_FLAG_2MiB_size 30 | mov ecx, 512 * 0x04 31 | add edi, 0x1000 * 0x02 32 | 33 | .next: 34 | stosd 35 | 36 | add edi, 0x04 37 | 38 | add eax, 0x00200000 39 | 40 | dec ecx 41 | jnz .next 42 | 43 | lgdt [aiden_long_mode_header_gdt_64bit] 44 | 45 | mov eax, 1010100000b 46 | mov cr4, eax 47 | 48 | mov aex, AIDEN_LONG_MODE_PML4_address 49 | mov cr3, eax 50 | 51 | mov ecx, 0xC0000080 52 | rdmsr 53 | or eax, 100000000b 54 | wrmsr 55 | 56 | mov eax, cr0 57 | or eax, 0x80000001 58 | mov cr0, eax 59 | 60 | jmp 0x0008:aiden_long_mode_entry 61 | 62 | align 0x08 63 | aiden_long_mode_table_gdt_64bit: 64 | dq 0x0000000000000000 65 | dq 0000000000100000100110000000000000000000000000000000000000000000b 66 | dq 0000000000100000100100100000000000000000000000000000000000000000b 67 | aiden_long_mode_table_gdt_64bit_end: 68 | 69 | aiden_long_mode_header_gdt_64bit: 70 | dw aiden_long_mode_table_gdt_64bit_end - aiden_long_mode_table_gdt_64bit - 0x01 71 | dd aiden_long_mode_table_gdt_64bit 72 | 73 | [bits 64] 74 | aiden_long_mode_entry: 75 | -------------------------------------------------------------------------------- /kernel/init/ps2.asm: -------------------------------------------------------------------------------- 1 | kernel_init_ps2: 2 | call driver_ps2_check_dummy_answer_or_dump 3 | 4 | mov al, DRIVER_PS2_COMMAND_CONFIGURATION_GET 5 | call driver_ps2_send_command_receive_answer 6 | 7 | push rax 8 | 9 | mov al, DRIVER_PS2_COMMAND_CONFIGURATION_SET 10 | call driver_ps2_send_command 11 | 12 | bts word [rsp], DRIVER_PS2_CONTROLLER_CONFIGURATION_BIT_SECOND_PORT_INTERRUPT 13 | btr word [rsp], DRIVER_PS2_CONTROLLER_CONFIGURATION_BIT_SECOND_PORT_CLOCK 14 | 15 | pop rax 16 | 17 | call driver_ps2_send_answer_or_ask_device 18 | 19 | mov al, DRIVER_PS2_COMMAND_PORT_SECOND_BYTE_SEND 20 | call driver_ps2_send_command 21 | mov al, DRIVER_PS2_DEVICE_RESET 22 | call driver_ps2_send_answer_or_ask_device 23 | 24 | call driver_ps2_receive_answer 25 | cmp al, DRIVER_PS2_ANSWER_COMMAND_ACKNOWLEDGED 26 | jne .error 27 | 28 | call driver_ps2_receive_answer 29 | 30 | cmp al, DRIVER_PS2_ANSWER_SELF_TEST_SUCCESS 31 | jne .error 32 | 33 | call driver_ps2_receive_answer 34 | mov byte [driver_ps2_mouse_type], al 35 | 36 | mov al, DRIVER_PS2_COMMAND_PORT_SECOND_BYTE_SEND 37 | call driver_ps2_send_command 38 | mov al, DRIVER_PS2_DEVICE_SET_DEFAULT 39 | call driver_ps2_send_answer_or_ask_device 40 | call driver_ps2_receive_answer 41 | 42 | cmp al, DRIVER_PS2_ANSWER_COMMAND_ACKNOWLEDGED 43 | jne .error 44 | 45 | mov al, DRIVER_PS2_COMMAND_PORT_SECOND_BYTE_SEND 46 | call driver_ps2_send_command 47 | mov al, DRIVER_PS2_DEVICE_PACKETS_ENABLE 48 | call driver_ps2_send_answer_or_ask_device 49 | call driver_ps2_receive_answer 50 | 51 | cmp al, DRIVER_PS2_ANSWER_COMMAND_ACKNOWLEDGED 52 | je .done 53 | 54 | .error: 55 | jmp $ 56 | 57 | .done: 58 | mov eax, KERNEL_IDT_IRQ_offset + DRIVER_PS2_MOUSE_IRQ_number 59 | mov bx, KERNEL_IDT_TYPE_irq 60 | mov rdi, driver_ps2_mouse 61 | call kernel_idt_mount 62 | 63 | mov eax, KERNEL_IDT_IRQ_offset + DRIVER_PS2_MOUSE_IRQ_number 64 | 65 | mov ebx, DRIVER_PS2_MOUSE_IO_APIC_register 66 | call kernel_io_apic_connect 67 | 68 | mov eax, KERNEL_IDT_IRQ_offset + DRIVER_PS2_KEYBOARD_IRQ_number 69 | mov bx, KERNEL_IDT_TYPE_irq 70 | mov rdi, driver_ps2_keyboard 71 | call kernel_idt_mount 72 | 73 | mov eax, KERNEL_IDT_IRQ_offset + DRIVER_PS2_KEYBOARD_IRQ_number 74 | mov ebx, DRIVER_PS2_KEYBOARD_IO_APIC_register 75 | call kernel_io_apic_connect 76 | -------------------------------------------------------------------------------- /include/input.asm: -------------------------------------------------------------------------------- 1 | ; Read input from the keyboard and store in a buffer parameter 2 | ; - rbx: initial buffer size 3 | ; - rbx: pointer to the buffer where input will be stored 4 | 5 | include_input: 6 | ; Save register 7 | push rax 8 | push rbx 9 | push rsi 10 | push rcx 11 | 12 | ; Clear eax (used for comparison) 13 | xor eax, eax 14 | 15 | ; Check if the buffer is empty 16 | cmp rbx, STATIC_EMPTY 17 | je .loop; If empty jump the input loop 18 | 19 | mov rcx, rbx; Store buffer size in rcx 20 | call include_terminal_string; Print the current input buffer to terminal 21 | 22 | ; Load buffer size from stack 23 | mov rcx, qword [rsp] 24 | ; Calculate remaining buffer space 25 | sub rcx, rbx 26 | ; Adjust buffer pointer to the end of input 27 | add rsi, rbx 28 | 29 | .loop: 30 | mov ax, KERNEL_SERVICE_KEYBOARD_key; Request keyboard input 31 | int KERNEL_SERVICE; Call system service 32 | jz .loop; If not pressed, keep wait 33 | 34 | cmp ax, STATIC_ASCII_BACKSPACE; Check if backspace pressed 35 | je .key_backspac 36 | 37 | cmp ax, STATIC_ASCII_ENTER; Check if enter was pressed 38 | je .key_enter 39 | 40 | cmp ax, STATIC_ASCII_ESCAPE; Check if escape was pressed 41 | je .empty 42 | 43 | cmp ax, STATIC_ASCII_SPACE; Ignore constrol characters 44 | jb .loop 45 | cmp ax, STATIC_ASCII_TILDE; Ignore non printable characters 46 | ja .loop 47 | 48 | cmp rcx, STATIC_EMPTY; Check if buffer is full 49 | je .loop 50 | 51 | ; Store input character in buffer 52 | mov byte [rsi + rbx], al 53 | ; Increase character count 54 | inc rbx 55 | ; Decrease remaining buffer space 56 | dec rcx 57 | 58 | .print: 59 | push rcx 60 | 61 | mov ecx, 1 62 | ; Check if buffer is empty 63 | call include_terminal_char 64 | 65 | pop rcx 66 | 67 | jmp .loop 68 | 69 | .key_backspace: 70 | ; Check if buffer is empty 71 | test rbx, rbx 72 | jz .loop 73 | 74 | dec rbx; Remove last character 75 | inc rcx; Increase available buffer space 76 | jmp .print; Reflect change on screen 77 | 78 | .key_enter: 79 | test rbx, rbx; Check if anything was typed 80 | jz .empty 81 | 82 | mov qword [rsp], rbx; Store final buffer length 83 | ; Clear carry flag 84 | clc 85 | 86 | jmp .end 87 | 88 | .empty: 89 | ; Set carry flag (buffer empty) 90 | stc 91 | 92 | .end: 93 | ; Restore registers 94 | pop rcx 95 | pop rsi 96 | pop rbx 97 | pop rax 98 | 99 | ; Return to caller 100 | ret 101 | -------------------------------------------------------------------------------- /kernel/driver/rtc.asm: -------------------------------------------------------------------------------- 1 | DRIVER_RTC_IRQ_number equ 0x08 2 | DRIVER_RTC_IO_APIC_register equ KERNEL_IO_APIC_iowin + (DRIVER_RTC_IRQ_number * 0x02) 3 | 4 | DRIVER_RTC_PORT_command equ 0x0070 5 | DRIVER_RTC_PORT_data equ 0x0071 6 | 7 | DRIVER_RTC_PORT_second equ 0x00 8 | DRIVER_RTC_PORT_minute equ 0x02 9 | DRIVER_RTC_PORT_hour equ 0x04 10 | DRIVER_RTC_PORT_weekday equ 0x06 11 | DRIVER_RTC_PORT_day_of_month equ 0x07 12 | DRIVER_RTC_PORT_month equ 0x08 13 | DRIVER_RTC_PORT_year equ 0x09 14 | DRIVER_RTC_PORT_STATUS_REGISTER_A equ 0x0A 15 | DRIVER_RTC_PORT_STATUS_REGISTER_B equ 0x0B 16 | 17 | DRIVER_RTC_PORT_STATUS_REGISTER_A_rate equ 00000110b 18 | DRIVER_RTC_PORT_STATUS_REGISTER_A_divider equ 00100000b 19 | DRIVER_RTC_PORT_STATUS_REGISTER_A_update_in_progress equ 10000000b 20 | 21 | DRIVER_RTC_PORT_STATUS_REGISTER_B_daylight_savings equ 00000001b 22 | DRIVER_RTC_PORT_STATUS_REGISTER_B_24_hour_mode equ 00000010b 23 | DRIVER_RTC_PORT_STATUS_REGISTER_B_binary_mode equ 00000100b 24 | DRIVER_RTC_PORT_STATUS_REGISTER_B_periodic_interrupt equ 01000000b 25 | DRIVER_RTC_PORT_STATUS_REGISTER_C equ 0x0C 26 | 27 | DRIVER_RTC_Hz equ 1024 28 | 29 | struc DRIVER_RTC_STRUCTURE 30 | .second resb 1 31 | .minute resb 1 32 | .hour resb 1 33 | .day resb 1 34 | .month resb 1 35 | .year resb 1 36 | .day_of_week resb 1 37 | endstruc 38 | 39 | driver_rtc_semaphore db STATIC_FALSE 40 | 41 | driver_rtc_microtime dq STATIC_EMPTY 42 | 43 | driver_rtc_date_and_time dq STATIC_EMPTY 44 | 45 | driver_rtc: 46 | push rax 47 | 48 | inc qword [driver_rtc_microtime] 49 | 50 | in al, DRIVER_RTC_PORT_data 51 | 52 | mov rax, qword [kernel_apic_base_address] 53 | mov dword [rax + KERNEL_APIC_EOI_register], STATIC_EMPTY 54 | 55 | pop rax 56 | 57 | iretq 58 | 59 | driver_rtc_get_date_and_time: 60 | push rax 61 | 62 | mov al, DRIVER_RTC_PORT_second 63 | out DRIVER_RTC_PORT_command, al 64 | in al, DRIVER_RTC_PORT_data 65 | 66 | mov byte [driver_rtc_date_and_time + DRIVER_RTC_STRUCTURE.second], al 67 | 68 | mov al, DRIVER_RTC_PORT_minute 69 | out DRIVER_RTC_PORT_command, al 70 | in al, DRIVER_RTC_PORT_data 71 | 72 | mov byte [driver_rtc_date_and_time + DRIVER_RTC_STRUCTURE.minute], al 73 | 74 | mov al, DRIVER_RTC_PORT_hour 75 | out DRIVER_RTC_PORT_command, al 76 | in al, DRIVER_RTC_PORT_data 77 | 78 | mov byte [driver_rtc_date_and_time + DRIVER_RTC_STRUCTURE.hour], al 79 | 80 | mov al, DRIVER_RTC_PORT_STATUS_REGISTER_C 81 | out DRIVER_RTC_PORT_command, al 82 | in al, DRIVER_RTC_PORT_data 83 | 84 | pop rax 85 | 86 | ret 87 | -------------------------------------------------------------------------------- /kernel/service/date/ipc/desu.asm: -------------------------------------------------------------------------------- 1 | service_date_ipc_render: 2 | mov rax, qword [rdi + KERNEL_IPC_STRUCTURE.data + SERVICE_RENDER_STRUCTURE_IPC.id] 3 | mov r8, qword [rdi + KERNEL_IPC_STRUCTURE.data + SERVICE_RENDER_STRUCTURE_IPC.value0] 4 | mov r9, qword [rdi + KERNEL_IPC_STRUCTURE.data + SERVICE_RENDER_STRUCTURE_IPC.value1] 5 | 6 | cmp byte [rdi + KERNEL_IPC_STRUCTURE.data + SERVICE_RENDER_STRUCTURE_IPC.type], SERVICE_RENDER_IPC_MOUSE_BUTTON_RIGHT_press 7 | je .right_mouse_button 8 | 9 | cmp rax, qword [service_date_window_menu + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.id] 10 | jne .end 11 | 12 | mov rsi, service_date_window_menu 13 | call include_unit_element 14 | jc .end 15 | 16 | cmp qword [rsi + INCLUDE_UNIT_STRUCTURE_ELEMENT.event], STATIC_EMPTY 17 | je .end 18 | 19 | push qword [rsi + INCLUDE_UNIT_STRUCTURE_ELEMENT.event] 20 | ret 21 | 22 | .left_mouse_button_no_menu: 23 | jmp .end 24 | 25 | .right_mouse_button: 26 | cmp rax, qword [service_date_window_taskbar + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.id] 27 | je .end 28 | 29 | cmp rax, qword [service_date_window_workbench + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.id] 30 | jne .end 31 | 32 | mov rbx, qword [service_date_window_menu + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.id] 33 | call service_render_object_by_id 34 | 35 | mov rax, r8 36 | add rax, qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 37 | cmp rax, qword [service_date_window_workbench + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 38 | jl .y 39 | 40 | sub r8, qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 41 | 42 | .y: 43 | mov rax, r9 44 | add rax, qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.height] 45 | cmp rax, qword [service_date_window_taskbar + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.y] 46 | jl .visible 47 | 48 | mov r9, qword [service_date_window_taskbar + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.y] 49 | sub r9, qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.height] 50 | dec r9 51 | 52 | .visible: 53 | mov qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.x], r8 54 | mov qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.y], r9 55 | 56 | or qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.flags], INCLUDE_UNIT_WINDOW_FLAG_visible | INCLUDE_UNIT_WINDOW_FLAG_flush 57 | 58 | .end: 59 | ret 60 | -------------------------------------------------------------------------------- /kernel/service/date/ipc/render.asm: -------------------------------------------------------------------------------- 1 | service_date_ipc_render: 2 | mov rax, qword [rdi + KERNEL_IPC_STRUCTURE.data + SERVICE_RENDER_STRUCTURE_IPC.id] 3 | mov r8, qword [rdi + KERNEL_IPC_STRUCTURE.data + SERVICE_RENDER_STRUCTURE_IPC.value0] 4 | mov r9, qword [rdi + KERNEL_IPC_STRUCTURE.data + SERVICE_RENDER_STRUCTURE_IPC.value1] 5 | 6 | cmp byte [rdi + KERNEL_IPC_STRUCTURE.data + SERVICE_RENDER_STRUCTURE_IPC.type], SERVICE_RENDER_IPC_MOUSE_BUTTON_RIGHT_press 7 | je .right_mouse_button 8 | 9 | cmp rax, qword [service_date_window_menu + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.id] 10 | jne .end 11 | 12 | mov rsi, service_date_window_menu 13 | call include_unit_element 14 | jc .end 15 | 16 | cmp qword [rsi + INCLUDE_UNIT_STRUCTURE_ELEMENT.event], STATIC_EMPTY 17 | je .end 18 | 19 | push qword [rsi + INCLUDE_UNIT_STRUCTURE_ELEMENT.event] 20 | ret 21 | 22 | .left_mouse_button_no_menu: 23 | jmp .end 24 | 25 | .right_mouse_button: 26 | cmp rax, qword [service_date_window_taskbar + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.id] 27 | je .end 28 | 29 | cmp rax, qword [service_date_window_workbench + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.id] 30 | jne .end 31 | 32 | mov rbx, qword [service_date_window_menu + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.id] 33 | call service_render_object_by_id 34 | 35 | mov rax, r8 36 | add rax, qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 37 | cmp rax, qword [service_date_window_workbench + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 38 | jl .y 39 | 40 | sub r8, qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 41 | 42 | .y: 43 | mov rax, r9 44 | add rax, qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.height] 45 | cmp rax, qword [service_date_window_taskbar + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.y] 46 | jl .visible 47 | 48 | mov r9, qword [service_date_window_taskbar + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.y] 49 | sub r9, qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.height] 50 | dec r9 51 | 52 | .visible: 53 | mov qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.x], r8 54 | mov qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.y], r9 55 | 56 | or qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.SIZE + INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA.flags], INCLUDE_UNIT_WINDOW_FLAG_visible | INCLUDE_UNIT_WINDOW_FLAG_flush 57 | 58 | .end: 59 | ret 60 | -------------------------------------------------------------------------------- /kernel/init/long_mode.asm: -------------------------------------------------------------------------------- 1 | KERNEL_INIT_LONG_MODE_PML4_TABLE_address equ 0x0000A000 2 | 3 | KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte equ 0x1000 4 | KERNEL_INIT_LONG_MODE_PAGE_SIZE_2MiB_byte equ 0x00200000 5 | 6 | KERNEL_INIT_LONG_MODE_PAGE_FLAG_available equ 00000001b 7 | KERNEL_INIT_LONG_MODE_PAGE_FLAG_writeable equ 00000010b 8 | KERNEL_INIT_LONG_MODE_PAGE_FLAG_2MiB_size equ 10000000b 9 | KERNEL_INIT_LONG_MODE_PAGE_FLAG_default equ KERNEL_INIT_LONG_MODE_PAGE_FLAG_available | KERNEL_INIT_LONG_MODE_PAGE_FLAG_writeable 10 | 11 | [BITS 32] 12 | xor eax, eax 13 | mov ecx, (KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte * 0x06) / 0x04 14 | mov edi, KERNEL_INIT_LONG_MODE_PML4_TABLE_address 15 | rep stosd 16 | 17 | mov dword [KERNEL_INIT_LONG_MODE_PML4_TABLE_address], KERNEL_INIT_LONG_MODE_PML4_TABLE_address + KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte + KERNEL_INIT_LONG_MODE_PAGE_FLAG_default 18 | 19 | mov dword [KERNEL_INIT_LONG_MODE_PML4_TABLE_address + KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte], KERNEL_INIT_LONG_MODE_PML4_TABLE_address + (KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte * 0x02) + KERNEL_INIT_LONG_MODE_PAGE_FLAG_default 20 | mov dword [KERNEL_INIT_LONG_MODE_PML4_TABLE_address + KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte + 0x08], KERNEL_INIT_LONG_MODE_PML4_TABLE_address + (KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte * 0x03) + KERNEL_INIT_LONG_MODE_PAGE_FLAG_default 21 | mov dword [KERNEL_INIT_LONG_MODE_PML4_TABLE_address + KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte + 0x10], KERNEL_INIT_LONG_MODE_PML4_TABLE_address + (KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte * 0x04) + KERNEL_INIT_LONG_MODE_PAGE_FLAG_default 22 | mov dword [KERNEL_INIT_LONG_MODE_PML4_TABLE_address + KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte + 0x18], KERNEL_INIT_LONG_MODE_PML4_TABLE_address + (KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte * 0x05) + KERNEL_INIT_LONG_MODE_PAGE_FLAG_default 23 | 24 | mov eax, KERNEL_INIT_LONG_MODE_PAGE_FLAG_default + KERNEL_INIT_LONG_MODE_PAGE_FLAG_2MiB_size 25 | mov ecx, 512 * 0x04 26 | mov edi, KERNEL_INIT_LONG_MODE_PML4_TABLE_address + (KERNEL_INIT_LONG_MODE_PAGE_SIZE_4KiB_byte * 0x02) 27 | 28 | .next: 29 | stosd 30 | 31 | add edi, 0x04 32 | 33 | add eax, KERNEL_INIT_LONG_MODE_PAGE_SIZE_2MiB_byte 34 | 35 | dec ecx 36 | jnz .next 37 | 38 | lgdt [kernel_init_header_gdt_64bit] 39 | 40 | mov eax, 1010100000b 41 | mov cr4, eax 42 | 43 | mov eax, KERNEL_INIT_LONG_MODE_PML4_TABLE_address 44 | mov cr3, eax 45 | 46 | mov ecx, 0xC0000080 47 | rdmsr 48 | or eax, 100000000b 49 | wrmsr 50 | 51 | mov eax, cr0 52 | or eax, 0x80000001 53 | mov cr0, eax 54 | 55 | jmp 0x0008:kernel_init 56 | 57 | align 0x08 58 | 59 | kernel_init_table_gdt_64bit: 60 | dq STATIC_EMPTY 61 | dq 0000000000100000100110000000000000000000000000000000000000000000b 62 | dq 0000000000100000100100100000000000000000000000000000000000000000b 63 | 64 | kernel_init_table_gdt_64bit_end: 65 | 66 | kernel_init_header_gdt_64bit: 67 | dw kernel_init_table_gdt_64bit_end - kernel_init_table_gdt_64bit - 0x01 68 | dd kernel_init_table_gdt_64bit 69 | -------------------------------------------------------------------------------- /kernel/service/network.asm: -------------------------------------------------------------------------------- 1 | %include "kernel/service/network/config.asm" 2 | %include "kernel/service/network/data.asm" 3 | %include "kernel/service/network/checksum.asm" 4 | %include "kernel/service/network/arp.asm" 5 | %include "kernel/service/network/icmp.asm" 6 | %include "kernel/service/network/tcp.asm" 7 | 8 | ; Main network service loop 9 | service_network: 10 | xor ebp, ebp ; Clear EBP register (stack base pointer) 11 | 12 | call kernel_task_active ; Check if the kernel task is active 13 | mov rax, qword [rdi + KERNEL_TASK_STRUCTURE.pid] ; Get the PID fo the kernel task 14 | 15 | mov qword [service_network_pid], rax ; Store the PID in service_network_pid 16 | 17 | .loop: 18 | mov rdi, service_network_ipc_message ; Load IPC message buffer 19 | call kernel_ipc_receive ; Wait for IPC message 20 | jc .loop ; If there is an error (carry flag set), retry 21 | 22 | mov rcx, qword [rdi + KERNEL_IPC_STRUCTURE.size] ; Load message size 23 | mov rsi, qword [rdi + KERNEL_IPC_STRUCTURE.pointer] ; Load message pointer 24 | 25 | ; Check if ARP frame 26 | cmp word [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.type], SERVICE_NETWORK_FRAME_ETHERNET_TYPE_arp 27 | je service_network_arp ; Jump if ARP 28 | 29 | ; Check if IP frame 30 | cmp word [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.type], SERVICE_NETWORK_FRAME_ETHERNET_TYPE_ip 31 | je service_network_ip ; Jump if IP 32 | 33 | xchg bx, bx ; Debug breakpoint (NOP equivalent) 34 | 35 | .end: 36 | test rsi, rsi ; Check if message pointer is null 37 | jz .loop ; If null, continue loop 38 | 39 | mov rdi, rsi ; Load message pointer 40 | call kernel_memory_release_page ; Free memory 41 | 42 | jmp .loop ; Repeat main loop 43 | 44 | macro_debug "service_network" 45 | 46 | ; Handles incoming IP frames 47 | service_network_ip: 48 | ; Check if ICMP 49 | cmp byte [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.protocol], SERVICE_NETWORK_FRAME_IP_PROTOCOL_ICMP 50 | je service_network_icmp ; Jump if ICMP 51 | 52 | ; Check if TCP 53 | cmp byte [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.protocol], SERVICE_NETWORK_FRAME_IP_PROTOCOL_TCP 54 | je service_network_tcp ; Jump if TCP 55 | 56 | .end: 57 | jmp service_network.end ; Return to main loop 58 | 59 | macro_debug "service_network_ip" 60 | 61 | ; Transfers packets between processes 62 | service_network_transfer: 63 | ; Save registers 64 | push rbx 65 | push rcx 66 | push rsi 67 | 68 | mov rbx, qword [service_tx_pid] ; Load transmission service PID 69 | test rbx, rbx ; Check if PID is valid 70 | jz .error ; If invalid, jump to error 71 | 72 | mov rcx, rax ; Save RAX (return value) 73 | mov rsi, rdi ; Save RDI (message pointer) 74 | call kernel_ipc_insert ; Send IPC message 75 | jnc .end ; If success, skip error 76 | 77 | .error: 78 | stc ; Set carry flag to indicate failure 79 | 80 | .end: 81 | ; Restore registers 82 | pop rsi 83 | pop rcx 84 | pop rbx 85 | 86 | ret ; Return from function 87 | -------------------------------------------------------------------------------- /include/unit/config.asm: -------------------------------------------------------------------------------- 1 | INCLUDE_UNIT_WINDOW_NAME_length equ 23 2 | INCLUDE_UNIT_WINDOW_BACKGROUND_color equ 0x00151515 3 | 4 | INCLUDE_UNIT_WINDOW_FLAG_visible equ 1 << 0 5 | INCLUDE_UNIT_WINDOW_FLAG_flush equ 1 << 1 6 | INCLUDE_UNIT_WINDOW_FLAG_fixed_xy equ 1 << 2 7 | INCLUDE_UNIT_WINDOW_FLAG_fixed_z equ 1 << 3 8 | INCLUDE_UNIT_WINDOW_FLAG_fragile equ 1 << 4 9 | INCLUDE_UNIT_WINDOW_FLAG_arbiter equ 1 << 6 10 | INCLUDE_UNIT_WINDOW_FLAG_unregistered equ 1 << 8 11 | INCLUDE_UNIT_WINDOW_FLAG_header equ 1 << 9 12 | INCLUDE_UNIT_WINDOW_FLAG_border equ 1 << 10 13 | INCLUDE_UNIT_ELEMENT_TYPE_none equ 0x00 14 | INCLUDE_UNIT_ELEMENT_TYPE_header equ 0x01 15 | INCLUDE_UNIT_ELEMENT_TYPE_label equ 0x02 16 | INCLUDE_UNIT_ELEMENT_TYPE_draw equ 0x03 17 | INCLUDE_UNIT_ELEMENT_TYPE_chain equ 0x04 18 | INCLUDE_UNIT_ELEMENT_TYPE_button equ 0x05 19 | 20 | INCLUDE_UNIT_ELEMENT_HEADER_HEIGHT_pixel equ INCLUDE_FONT_HEIGHT_pixel 21 | INCLUDE_UNIT_ELEMENT_HEADER_PADDING_LEFT_pixel equ 0x02 22 | INCLUDE_UNIT_ELEMENT_HEADER_FOREGROUND_color equ 0x00717171 23 | INCLUDE_UNIT_ELEMENT_HEADER_BACKGROUND_color equ 0x00202020 24 | 25 | INCLUDE_UNIT_ELEMENT_BUTTON_FOREGROUND_color equ 0x00FFFFFF 26 | INCLUDE_UNIT_ELEMENT_BUTTON_BACKGROUND_color equ 0x00303030 27 | 28 | INCLUDE_UNIT_ELEMENT_LABEL_FOREGROUND_color equ 0x00BBBBBB 29 | INCLUDE_UNIT_ELEMENT_LABEL_BACKGROUND_color equ INCLUDE_UNIT_WINDOW_BACKGROUND_color 30 | 31 | struc INCLUDE_UNIT_STRUCTURE_FIELD 32 | .x resb 8 33 | .y resb 8 34 | .width resb 8 35 | .height resb 8 36 | 37 | .SIZE: 38 | endstruc 39 | 40 | struc INCLUDE_UNIT_STRUCTURE_WINDOW 41 | .field resb INCLUDE_UNIT_STRUCTURE_FIELD.SIZE 42 | .address resb 8 43 | 44 | .SIZE: 45 | endstruc 46 | 47 | struc INCLUDE_UNIT_STRUCTURE_WINDOW_EXTRA 48 | .size resb 8 49 | .flags resb 8 50 | .id resb 8 51 | .length resb 1 52 | .name resb INCLUDE_UNIT_WINDOW_NAME_length 53 | .scanline resb 8 54 | 55 | .SIZE: 56 | endstruc 57 | 58 | struc INCLUDE_UNIT_STRUCTURE_ELEMENT 59 | .type resb 4 60 | .size resb 8 61 | .field resb INCLUDE_UNIT_STRUCTURE_FIELD.SIZE 62 | .event resb 8 63 | 64 | .SIZE: 65 | endstruc 66 | 67 | struc INCLUDE_UNIT_STRUCTURE_ELEMENT_HEADER 68 | .element resb INCLUDE_UNIT_STRUCTURE_ELEMENT.SIZE 69 | .length resb 1 70 | 71 | .string: 72 | endstruc 73 | 74 | struc INCLUDE_UNIT_STRUCTURE_ELEMENT_LABEL 75 | .element resb INCLUDE_UNIT_STRUCTURE_ELEMENT.SIZE 76 | .length resb 1 77 | 78 | .string: 79 | endstruc 80 | 81 | struc INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON 82 | .element resb INCLUDE_UNIT_STRUCTURE_ELEMENT.SIZE 83 | .length resb 1 84 | 85 | .string: 86 | .SIZE: 87 | endstruc 88 | 89 | struc INCLUDE_UNIT_STRUCTURE_ELEMENT_DRAW 90 | .element resb INCLUDE_UNIT_STRUCTURE_ELEMENT.SIZE 91 | 92 | .SIZE: 93 | endstruc 94 | 95 | struc INCLUDE_UNIT_STRUCTURE_ELEMENT_CHAIN 96 | .type resb 4 97 | .size resb 8 98 | .address resb 8 99 | 100 | .SIZE: 101 | endstruc 102 | -------------------------------------------------------------------------------- /kernel/ipc.asm: -------------------------------------------------------------------------------- 1 | KERNEL_IPC_SIZE_page_default equ 1 2 | KERNEL_IPC_ENTRY_limit equ (KERNEL_IPC_SIZE_page_default << KERNEL_PAGE_SIZE_shift) / KERNEL_IPC_STRUCTURE.SIZE 3 | 4 | KERNEL_IPC_TTL_default equ DRIVER_RTC_Hz / 10 5 | 6 | kernel_ipc_semaphore db STATIC_FALSE 7 | kernel_ipc_base_address dq STATIC_EMPTY 8 | kernel_ipc_entry_count dq STATIC_EMPTY 9 | 10 | kernel_ipc_insert: 11 | push rax 12 | push rdx 13 | push rsi 14 | push rdi 15 | push rcx 16 | 17 | call kernel_task_active 18 | mov rdx, qword [rdi + KERNEL_TASK_STRUCTURE.pid] 19 | 20 | macro_lock kernel_ipc_semaphore, 0 21 | 22 | .wait: 23 | cmp qword [kernel_ipc_entry_count], KERNEL_IPC_ENTRY_limit 24 | jne .reload 25 | 26 | xchg bx, bx 27 | jmp $ 28 | 29 | .reload: 30 | mov rax, qword [driver_rtc_microtime] 31 | 32 | mov rcx, KERNEL_IPC_ENTRY_limit 33 | 34 | mov rdi, qword [kernel_ipc_base_address] 35 | 36 | .loop: 37 | cmp rax, qword [rdi + KERNEL_IPC_STRUCTURE.ttl] 38 | ja .found 39 | 40 | add rdi, KERNEL_IPC_STRUCTURE.SIZE 41 | 42 | dec rcx 43 | jnz .loop 44 | 45 | stc 46 | 47 | jmp .error 48 | 49 | .found: 50 | mov qword [rdi + KERNEL_IPC_STRUCTURE.pid_source], rdx 51 | 52 | mov qword [rdi + KERNEL_IPC_STRUCTURE.pid_destination], rbx 53 | 54 | mov rcx, qword [rsp] 55 | 56 | test rcx, rcx 57 | jz .load 58 | 59 | mov qword [rdi + KERNEL_IPC_STRUCTURE.size], rcx 60 | 61 | mov qword [rdi + KERNEL_IPC_STRUCTURE.pointer], rsi 62 | 63 | jmp .end 64 | 65 | .load: 66 | push rdi 67 | 68 | mov ecx, KERNEL_IPC_STRUCTURE.SIZE - KERNEL_IPC_STRUCTURE.data 69 | add rdi, KERNEL_IPC_STRUCTURE.data 70 | rep movsb 71 | 72 | pop rdi 73 | 74 | .end: 75 | inc qword [kernel_ipc_entry_count] 76 | 77 | add rax, KERNEL_IPC_TTL_default 78 | mov qword [rdi + KERNEL_IPC_STRUCTURE.ttl], rax 79 | 80 | .error: 81 | mov byte [kernel_ipc_semaphore], STATIC_FALSE 82 | 83 | pop rcx 84 | pop rdi 85 | pop rsi 86 | pop rdx 87 | pop rax 88 | 89 | ret 90 | 91 | macro_debug "kernel_ipc_insert" 92 | 93 | kernel_ipc_receive: 94 | push rax 95 | push rcx 96 | push rsi 97 | push rdi 98 | 99 | cmp qword [kernel_ipc_entry_count], STATIC_EMPTY 100 | je .empty 101 | 102 | call kernel_task_active_pid 103 | 104 | mov rcx, KERNEL_IPC_ENTRY_limit 105 | 106 | mov rsi, qword [kernel_ipc_base_address] 107 | 108 | mov rdi, qword [driver_rtc_microtime] 109 | 110 | .loop: 111 | cmp qword [rsi + KERNEL_IPC_STRUCTURE.pid_destination], rax 112 | jne .next 113 | 114 | cmp rdi, qword [rsi + KERNEL_IPC_STRUCTURE.ttl] 115 | jbe .found 116 | 117 | .next: 118 | add rsi, KERNEL_IPC_STRUCTURE.SIZE 119 | 120 | dec rcx 121 | jnz .loop 122 | 123 | .empty: 124 | stc 125 | 126 | jmp .error 127 | 128 | .found: 129 | mov ecx, KERNEL_IPC_STRUCTURE.SIZE 130 | mov rdi, qword [rsp] 131 | rep movsb 132 | 133 | mov qword [rsi - KERNEL_IPC_STRUCTURE.SIZE], STATIC_EMPTY 134 | 135 | dec qword [kernel_ipc_entry_count] 136 | 137 | clc 138 | 139 | .error: 140 | pop rdi 141 | pop rsi 142 | pop rcx 143 | pop rax 144 | 145 | ret 146 | 147 | macro_debug "kernel_ipc_receive" 148 | -------------------------------------------------------------------------------- /kernel/config.asm: -------------------------------------------------------------------------------- 1 | %define KERNEL_name "Aiden"; Name of the kernel 2 | %define KERNEL_version "1"; Kernel major version 3 | %define KERNEL_revision "3"; Kernel minor revision 4 | %define KERNEL_architecture "x86_64"; Target system architecture 5 | 6 | ; Base memory address where the kernel is loaded 7 | KERNEL_BASE_address equ 0x0000000000100000 8 | 9 | ; Stack Memory Configuration 10 | KERNEL_STACK_address equ KERNEL_MEMORY_HIGH_VIRTUAL_address - KERNEL_STACK_SIZE_byte ; Stack start address 11 | KERNEL_STACK_pointer equ KERNEL_MEMORY_HIGH_VIRTUAL_address - KERNEL_PAGE_SIZE_byte ; Stack pointer location 12 | KERNEL_STACK_SIZE_byte equ KERNEL_PAGE_SIZE_byte * 0x02 ; Stack size (2 pages) 13 | 14 | ; Temporary Stack Pointer used during early initialization 15 | KERNEL_STACK_TEMPORARY_pointer equ 0x8000 + KERNEL_PAGE_SIZE_byte 16 | 17 | ; High Memory Addressing 18 | KERNEL_MEMORY_HIGH_mask equ 0xFFFF000000000000 ; Mask for high memory access 19 | KERNEL_MEMORY_HIGH_REAL_address equ 0xFFFF800000000000 ; Real address mapping for high memory 20 | ; Virtual high memory address 21 | KERNEL_MEMORY_HIGH_VIRTUAL_address equ KERNEL_MEMORY_HIGH_REAL_address - KERNEL_MEMORY_HIGH_mask 22 | 23 | ; Video Configuration 24 | KERNEL_VIDEO_DEPTH_shift equ 2 ; Shift value for video depth calculations 25 | KERNEL_VIDEO_DEPTH_byte equ 4 ; Video depth in bytes (4 bytes per pixel) 26 | KERNEL_VIDEO_DEPTH_bit equ 32 ; Video depth in bits (32-bit color) 27 | 28 | ; Kernel Service Interrupt Number 29 | KERNEL_SERVICE equ 0x40 ; Interrupt number for kernel services 30 | 31 | ; Process Management Services 32 | KERNEL_SERVICE_PROCESS equ 0x0000 33 | KERNEL_SERVICE_PROCESS_exit equ 0x0000 + KERNEL_SERVICE_PROCESS ; Exit a process 34 | KERNEL_SERVICE_PROCESS_run equ 0x0100 + KERNEL_SERVICE_PROCESS ; Start a new process 35 | KERNEL_SERVICE_PROCESS_check equ 0x0200 + KERNEL_SERVICE_PROCESS ; Check process status 36 | ; Allocate memory for a process 37 | KERNEL_SERVICE_PROCESS_memory_alloc equ 0x0300 + KERNEL_SERVICE_PROCESS 38 | 39 | KERNEL_SERVICE_PROCESS_ipc_receive equ 0x0400 + KERNEL_SERVICE_PROCESS 40 | KERNEL_SERVICE_PROCESS_pid equ 0x0500 + KERNEL_SERVICE_PROCESS 41 | 42 | ; Video Services 43 | KERNEL_SERVICE_VIDEO equ 0x0001 44 | KERNEL_SERVICE_VIDEO_properties equ 0x0000 + KERNEL_SERVICE_VIDEO 45 | 46 | ; Virtual File System (VFS) Services 47 | KERNEL_SERVICE_VFS equ 0x0003 48 | KERNEL_SERVICE_VFS_exist equ 0x0000 + KERNEL_SERVICE_VFS 49 | 50 | ; System Services 51 | KERNEL_SERVICE_SYSTEM equ 0x0004 52 | ; Get system memory information 53 | KERNEL_SERVICE_SYSTEM_memory equ 0x0000 + KERNEL_SERVICE_SYSTEM 54 | 55 | struc KERNEL_IPC_STRUCTURE 56 | .ttl resb 8 57 | .pid_source resb 8 58 | .pid_destination resb 8 59 | 60 | .data: 61 | .size resb 8 62 | .pointer resb 8 63 | .other resb 24 64 | 65 | .SIZE: 66 | endstruc 67 | 68 | ; Error Codes 69 | KERNEL_ERROR_memory_low equ 0x0001 70 | 71 | SERVICE_RENDER_IPC_KEYBOARD equ 0 72 | SERVICE_RENDER_IPC_MOUSE_BUTTON_LEFT_press equ 1 73 | SERVICE_RENDER_IPC_MOUSE_BUTTON_RIGHT_press equ 2 74 | 75 | struc SERVICE_RENDER_STRUCTURE_IPC 76 | .type resb 1 77 | .reserved resb 7 78 | .id resb 8 79 | .value0 resb 8 80 | .value1 resb 8 81 | endstruc 82 | -------------------------------------------------------------------------------- /software/console/data.asm: -------------------------------------------------------------------------------- 1 | ; Aligns the following data to a multiple of `STATIC_QWORD_SIZE_byte` 2 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 3 | 4 | console_ipc_data: 5 | times KERNEL_IPC_STRUCTURE.SIZE db STATIC_EMPTY 6 | 7 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 8 | 9 | ; This section defines the main properties of the console window 10 | 11 | console_window: 12 | dq STATIC_EMPTY; Placeholder for window instance reference 13 | dq STATIC_EMPTY; Reserved for future use 14 | dq CONSOLE_WINDOW_WIDTH_pixel; Width of the console window in pixels 15 | dq CONSOLE_WINDOW_HEIGHT_pixel; Height of the console window in pixels 16 | dq STATIC_EMPTY; Reserved for additional data 17 | 18 | .extra: 19 | dq STATIC_EMPTY; Reserved for future use 20 | ; Reserved for additional settings 21 | dq INCLUDE_UNIT_WINDOW_FLAG_header | INCLUDE_UNIT_WINDOW_FLAG_border 22 | dq STATIC_EMPTY; Reserved for additional settings 23 | ; Window title length (in bytes) 24 | db 7 25 | db "Console "; Window title (padded with spaces for alignment) 26 | dq STATIC_EMPTY; Reserved field for additional configurations 27 | 28 | .elements: 29 | .element_header: 30 | dd INCLUDE_UNIT_ELEMENT_TYPE_header; Element type: Header 31 | dq .element_header_end - .element_header; Size of the header element 32 | dq 0; X position (aligned to the left) 33 | dq 0; Y position (aligned to the top) 34 | dq STATIC_EMPTY; Reserved field 35 | dq INCLUDE_UNIT_ELEMENT_HEADER_HEIGHT_pixel; Height of the header 36 | dq STATIC_EMPTY; Reserved field 37 | db .element_header_end - .element_header_string; Length of the header text 38 | 39 | ; Header Text 40 | 41 | .element_header_string: 42 | db "Console"; Text displayed in the header 43 | 44 | .element_header_end: 45 | 46 | .element_terminal: 47 | dd INCLUDE_UNIT_ELEMENT_TYPE_draw; Element type: Drawable area (Terminal) 48 | dq .element_terminal_end - .element_terminal; Size of the terminal element 49 | dq 0; X position (aligned to the left) 50 | dq INCLUDE_UNIT_ELEMENT_HEADER_HEIGHT_pixel; Y position (below the header) 51 | dq CONSOLE_WINDOW_WIDTH_pixel; Width of the terminal area 52 | dq CONSOLE_WINDOW_HEIGHT_pixel - INCLUDE_UNIT_ELEMENT_HEADER_HEIGHT_pixel; Height of the terminal area 53 | dq STATIC_EMPTY; Reserved field 54 | 55 | .element_terminal_end: 56 | dd STATIC_EMPTY; Reserved for future expansion 57 | 58 | console_window_end: 59 | 60 | ; This section defines the terminal’s properties and rendering attributes. 61 | 62 | console_terminal_table: 63 | dq CONSOLE_WINDOW_WIDTH_pixel; Width of the console window 64 | dq CONSOLE_WINDOW_HEIGHT_pixel - INCLUDE_UNIT_ELEMENT_HEADER_HEIGHT_pixel; Height excluding the header 65 | ; Total framebuffer size in bytes (Width * Height * Video Depth) 66 | dq (CONSOLE_WINDOW_WIDTH_pixel * (CONSOLE_WINDOW_HEIGHT_pixel - INCLUDE_UNIT_ELEMENT_HEADER_HEIGHT_pixel)) << KERNEL_VIDEO_DEPTH_shift 67 | dq CONSOLE_WINDOW_WIDTH_pixel << KERNEL_VIDEO_DEPTH_shift; Bytes per scanline 68 | dq STATIC_EMPTY; Reserved field 69 | dq STATIC_EMPTY; Reserved field 70 | dq STATIC_EMPTY; Reserved field 71 | dq STATIC_EMPTY; Reserved field 72 | dq STATIC_EMPTY; Reserved field 73 | dq STATIC_EMPTY; Reserved field 74 | dq 0x00F5F5F5; Foreground color (light gray) 75 | dq 0x00000000; Background color (black) 76 | -------------------------------------------------------------------------------- /kernel/service/visual/config.asm: -------------------------------------------------------------------------------- 1 | ; Maximum length of the name assigned to a render object 2 | ; This defines the storage space allocated for object names 3 | SERVICE_RENDER_OBJECT_NAME_length equ 23 4 | 5 | ; The following flags define properties and behaviors of render objects. 6 | ; These flags are used in the `SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags` field 7 | SERVICE_RENDER_OBJECT_FLAG_visible equ 1 << 0 ; Object is visible on screen 8 | SERVICE_RENDER_OBJECT_FLAG_flush equ 1 << 1 ; Object requires screen refresh 9 | SERVICE_RENDER_OBJECT_FLAG_fixed_xy equ 1 << 2 ; Object has a fixed position in X/Y space 10 | SERVICE_RENDER_OBJECT_FLAG_fixed_z equ 1 << 3 ; Object has a fixed Z-depth (layering) 11 | SERVICE_RENDER_OBJECT_FLAG_fragile equ 1 << 4 ; Object is volatile and may be removed easily 12 | SERVICE_RENDER_OBJECT_FLAG_pointer equ 1 << 5 ; Object acts as a pointer (e.g., mouse cursor) 13 | SERVICE_RENDER_OBJECT_FLAG_arbiter equ 1 << 6 ; Object has arbitration control over rendering 14 | 15 | ; Maximum number of entries for fill and zone lists, determined by the available page size. 16 | SERVICE_RENDER_FILL_LIST_limit equ (KERNEL_PAGE_SIZE_byte / SERVICE_RENDER_STRUCTURE_FILL.SIZE) - 0x01 17 | SERVICE_RENDER_ZONE_LIST_limit equ (KERNEL_PAGE_SIZE_byte / SERVICE_RENDER_STRUCTURE_ZONE.SIZE) - 0x01 18 | 19 | ; This structure defines the basic properties of a render object, including its position and dimensions 20 | struc SERVICE_RENDER_STRUCTURE_FIELD 21 | .x resb 8; X-coordinate position (8 bytes) 22 | .y resb 8; Y-coordinate position (8 bytes) 23 | .width resb 8; Width of the object (8 bytes) 24 | .height resb 8; Height of the object (8 bytes) 25 | 26 | .SIZE: 27 | endstruc 28 | 29 | ; Render object structure 30 | ; Structure representing a graphical render object in memory. 31 | struc SERVICE_RENDER_STRUCTURE_OBJECT 32 | .field resb SERVICE_RENDER_STRUCTURE_FIELD.SIZE; Field structure containing object properties 33 | .address resb 8; Memory address of the object's framebuffer 34 | 35 | .SIZE: 36 | endstruc 37 | 38 | ; This structure holds additional metadata for render objects, including flags and identifiers 39 | struc SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA 40 | .size resb 8; Total size of the object (8 bytes) 41 | .flags resb 8; Flags defining object properties (8 bytes) 42 | .id resb 8; Unique identifier of the object (8 bytes) 43 | .length resb 1; Length of the object name (1 byte) 44 | .name resb SERVICE_RENDER_OBJECT_NAME_length; Name of the object (23 bytes) 45 | .pid resb 8; Process ID associated with the object (8 bytes) 46 | 47 | .SIZE: 48 | endstruc 49 | 50 | ; Fill structure 51 | ; Structure defining a fill operation in the render service 52 | struc SERVICE_RENDER_STRUCTURE_FILL 53 | .field resb SERVICE_RENDER_STRUCTURE_FIELD.SIZE; Field structure defining the fill region 54 | .object resb 8; Reference to the object being filled 55 | 56 | .SIZE: 57 | endstruc 58 | 59 | ; Zone structure 60 | ; Structure defining a render zone, used for region-based rendering 61 | struc SERVICE_RENDER_STRUCTURE_ZONE 62 | .field resb SERVICE_RENDER_STRUCTURE_FIELD.SIZE; Field structure defining the zone dimensions 63 | .object resb 8; Reference to the associated object 64 | 65 | .SIZE: 66 | endstruc 67 | -------------------------------------------------------------------------------- /kernel/driver/pci.asm: -------------------------------------------------------------------------------- 1 | DRIVER_PCI_PORT_command equ 0x0CF8 2 | DRIVER_PCI_PORT_data equ 0x0CFC 3 | 4 | DRIVER_PCI_REGISTER_vendor_and_device equ 0x00 5 | DRIVER_PCI_REGISTER_status_and_command equ 0x04 6 | DRIVER_PCI_REGISTER_class_and_subclass equ 0x08 7 | DRIVER_PCI_REGISTER_bar0 equ 0x10 8 | DRIVER_PCI_REGISTER_bar1 equ 0x14 9 | DRIVER_PCI_REGISTER_bar2 equ 0x18 10 | DRIVER_PCI_REGISTER_bar3 equ 0x1C 11 | DRIVER_PCI_REGISTER_bar4 equ 0x20 12 | DRIVER_PCI_REGISTER_bar5 equ 0x24 13 | DRIVER_PCI_REGISTER_irq equ 0x3C 14 | DRIVER_PCI_REGISTER_FLAG_64_bit equ 00000010b 15 | 16 | DRIVER_PCI_CLASS_SUBCLASS_ide equ 0x0101 17 | DRIVER_PCI_CLASS_SUBCLASS_ahci equ 0x0106 18 | DRIVER_PCI_CLASS_SUBCLASS_scsi equ 0x0107 19 | DRIVER_PCI_CLASS_SUBCLASS_network equ 0x0200 20 | 21 | driver_pci_find_vendor_and_device: 22 | push rbx 23 | push rcx 24 | push rdx 25 | push rax 26 | 27 | xor ebx, ebx 28 | xor ecx, ecx 29 | xor edx, edx 30 | 31 | .next: 32 | mov eax, DRIVER_PCI_REGISTER_vendor_and_device 33 | call driver_pci_read 34 | 35 | cmp eax, dword [rsp] 36 | je .found 37 | 38 | inc edx 39 | 40 | cmp edx, 0x0008 41 | jb .next 42 | 43 | inc ecx 44 | 45 | xor edx, edx 46 | 47 | cmp ecx, 0x0020 48 | jb .next 49 | 50 | inc ebx 51 | 52 | xor ecx, ecx 53 | 54 | cmp ebx, 0x0100 55 | jb .next 56 | 57 | .error: 58 | stc 59 | 60 | jmp .end 61 | 62 | .found: 63 | mov eax, DRIVER_PCI_REGISTER_bar0 64 | call driver_pci_read 65 | 66 | mov qword [rsp + STATIC_QWORD_SIZE_byte], rdx 67 | mov qword [rsp + STATIC_QWORD_SIZE_byte * 0x02], rcx 68 | 69 | clc 70 | 71 | .end: 72 | pop rax 73 | pop rdx 74 | pop rcx 75 | pop rbx 76 | 77 | ret 78 | 79 | driver_pci_find_class_and_subclass: 80 | push rbx 81 | push rcx 82 | push rdx 83 | push rax 84 | 85 | xor ebx, ebx 86 | xor ecx, ecx 87 | xor edx, edx 88 | 89 | .next: 90 | mov eax, DRIVER_PCI_REGISTER_class_and_subclass 91 | call driver_pci_read 92 | 93 | shr eax, STATIC_MOVE_HIGH_TO_AX_shift 94 | 95 | cmp ax, word [rsp] 96 | je .found 97 | 98 | inc edx 99 | 100 | cmp edx, 0x0008 101 | jb .next 102 | 103 | inc ecx 104 | 105 | xor edx, edx 106 | 107 | cmp ecx, 0x0020 108 | jb .next 109 | 110 | inc ebx 111 | 112 | xor ecx, ecx 113 | 114 | cmp ebx, 0x0100 115 | jb .next 116 | 117 | .error: 118 | stc 119 | 120 | jmp .end 121 | 122 | .found: 123 | mov qword [rsp + STATIC_QWORD_SIZE_byte], rdx 124 | mov qword [rsp + STATIC_QWORD_SIZE_byte * 0x02], rcx 125 | mov qword [rsp + STATIC_QWORD_SIZE_byte * 0x03], rbx 126 | 127 | clc 128 | 129 | .end: 130 | pop rax 131 | pop rdx 132 | pop rcx 133 | pop rbx 134 | 135 | ret 136 | 137 | driver_pci_read: 138 | push rbx 139 | push rcx 140 | push rdx 141 | 142 | or eax, 0x80000000 143 | 144 | ror eax, 8 145 | or al, dl 146 | 147 | ror eax, 3 148 | or al, cl 149 | 150 | ror eax, 5 151 | or al, bl 152 | 153 | rol eax, 16 154 | 155 | mov dx, DRIVER_PCI_PORT_command 156 | out dx, eax 157 | 158 | mov dx, DRIVER_PCI_PORT_data 159 | in eax, dx 160 | 161 | pop rdx 162 | pop rcx 163 | pop rbx 164 | 165 | ret 166 | 167 | driver_pci_write: 168 | push rbx 169 | push rcx 170 | push rdx 171 | push rax 172 | 173 | or eax, 0x80000000 174 | 175 | ror eax, 8 176 | or al, dl 177 | 178 | ror eax, 3 179 | or al, cl 180 | 181 | ror eax, 5 182 | or al, bl 183 | 184 | rol eax, 16 185 | 186 | mov dx, DRIVER_PCI_PORT_command 187 | out dx, eax 188 | 189 | pop rax 190 | 191 | mov dx, DRIVER_PCI_PORT_data 192 | out dx, eax 193 | 194 | pop rdx 195 | pop rcx 196 | pop rbx 197 | 198 | ret 199 | -------------------------------------------------------------------------------- /kernel/exec.asm: -------------------------------------------------------------------------------- 1 | kernel_exec: 2 | push rbx 3 | push rdx 4 | push rsi 5 | push rbp 6 | push r8 7 | push r11 8 | push r12 9 | push r13 10 | push rax 11 | push rcx 12 | push rdi 13 | 14 | mov rcx, qword [rdi + KERNEL_VFS_STRUCTURE_KNOT.size] 15 | call include_page_from_size 16 | 17 | mov r12, rcx 18 | 19 | add rcx, 14 20 | call kernel_page_secure 21 | jc .error 22 | 23 | mov rbp, rcx 24 | 25 | call kernel_memory_alloc_page 26 | call kernel_page_drain 27 | 28 | inc qword [kernel_page_paged_count] 29 | 30 | mov r11, rdi 31 | 32 | mov rax, KERNEL_MEMORY_HIGH_VIRTUAL_address 33 | mov bx, KERNEL_PAGE_FLAG_available | KERNEL_PAGE_FLAG_write | KERNEL_PAGE_FLAG_user 34 | mov rcx, r12 35 | call kernel_page_map_logical 36 | jc .error 37 | 38 | shl r12, KERNEL_PAGE_SIZE_shift 39 | add rax, r12 40 | and bx, ~KERNEL_PAGE_FLAG_user 41 | mov rcx, KERNEL_MEMORY_MAP_SIZE_page 42 | call kernel_page_map_logical 43 | 44 | mov r13, rax 45 | 46 | mov rdi, qword [r8] 47 | and di, KERNEL_PAGE_mask 48 | push rdi 49 | 50 | mov rax, STATIC_MAX_unsigned 51 | mov ecx, (KERNEL_MEMORY_MAP_SIZE_page << KERNEL_PAGE_SIZE_shift) >> STATIC_DIVIDE_BY_QWORD_shift 52 | rep stosq 53 | 54 | pop rsi 55 | mov rcx, r12 56 | shr rcx, KERNEL_PAGE_SIZE_shift 57 | add rcx, KERNEL_MEMORY_MAP_SIZE_page 58 | call kernel_memory_secure 59 | 60 | mov rax, (KERNEL_MEMORY_HIGH_VIRTUAL_address << STATIC_MULTIPLE_BY_2_shift) - KERNEL_PAGE_SIZE_byte 61 | or bx, KERNEL_PAGE_FLAG_user 62 | mov rcx, KERNEL_PAGE_SIZE_byte >> STATIC_DIVIDE_BY_PAGE_shift 63 | call kernel_page_map_logical 64 | jc .error 65 | 66 | mov rax, KERNEL_STACK_address 67 | mov rbx, KERNEL_PAGE_FLAG_available | KERNEL_PAGE_FLAG_write 68 | mov rcx, KERNEL_STACK_SIZE_byte >> STATIC_DIVIDE_BY_PAGE_shift 69 | call kernel_page_map_logical 70 | jc .error 71 | 72 | mov rsi, qword [kernel_page_pml4_address] 73 | mov rdi, r11 74 | call kernel_page_merge 75 | 76 | mov rdi, qword [r8] 77 | and di, KERNEL_PAGE_mask 78 | add rdi, KERNEL_PAGE_SIZE_byte - ( STATIC_QWORD_SIZE_byte * 0x05 ) 79 | 80 | mov rax, KERNEL_MEMORY_HIGH_REAL_address 81 | stosq 82 | 83 | mov rax, KERNEL_STRUCTURE_GDT.cs_ring3 | 0x03 84 | stosq 85 | 86 | mov rax, KERNEL_TASK_EFLAGS_default 87 | stosq 88 | 89 | mov rax, STATIC_EMPTY 90 | stosq 91 | 92 | mov rax, KERNEL_STRUCTURE_GDT.ds_ring3 | 0x03 93 | stosq 94 | 95 | mov rsi, qword [rsp] 96 | 97 | mov rax, cr3 98 | mov cr3, r11 99 | 100 | mov rdi, SOFTWARE_base_address 101 | call kernel_vfs_file_read 102 | 103 | mov cr3, rax 104 | 105 | xor bx, bx 106 | movzx ecx, byte [rsi + KERNEL_VFS_STRUCTURE_KNOT.length] 107 | add rsi, KERNEL_VFS_STRUCTURE_KNOT.name 108 | call kernel_task_add 109 | jc .error 110 | 111 | add r13, qword [kernel_memory_high_mask] 112 | mov qword [rdi + KERNEL_TASK_STRUCTURE.map], r13 113 | mov qword [rdi + KERNEL_TASK_STRUCTURE.map_size], (KERNEL_MEMORY_MAP_SIZE_page << KERNEL_PAGE_SIZE_shift) << STATIC_MULTIPLE_BY_8_shift 114 | 115 | or word [rdi + KERNEL_TASK_STRUCTURE.flags], KERNEL_TASK_FLAG_active 116 | 117 | add qword [kernel_page_free_count], rbp 118 | sub qword [kernel_page_reserved_count], rbp 119 | 120 | mov qword [rsp + STATIC_QWORD_SIZE_byte], rcx 121 | 122 | jmp .end 123 | 124 | .error: 125 | mov qword [rsp + STATIC_QWORD_SIZE_byte * 0x03], rax 126 | 127 | .end: 128 | pop rdi 129 | pop rcx 130 | pop rax 131 | pop r13 132 | pop r12 133 | pop r11 134 | pop r8 135 | pop rbp 136 | pop rsi 137 | pop rdx 138 | pop rbx 139 | 140 | ret 141 | 142 | macro_debug "kernel_exec" 143 | -------------------------------------------------------------------------------- /kernel/service/visual/data.asm: -------------------------------------------------------------------------------- 1 | ; Main semaphore to control rendering service execution 2 | service_render_semaphore db STATIC_FALSE 3 | ; Stores the Process ID (PID) associated with the rendering service 4 | service_render_pid dq STATIC_EMPTY 5 | 6 | ; Object control semaphores 7 | service_render_object_semaphore db STATIC_FALSE ; Controls access to rendering objects 8 | service_render_object_arbiter_semaphore db STATIC_FALSE ; Controls arbitration among rendering objects 9 | service_render_fill_semaphore db STATIC_FALSE ; Controls filling operations in the render process 10 | service_render_zone_semaphore db STATIC_FALSE ; Controls zoning operations in the render process 11 | 12 | ; Keyboard alt semaphore 13 | service_render_keyboard_alt_left_semaphore db STATIC_FALSE 14 | ; Mouse button semaphores 15 | service_render_mouse_button_left_semaphore db STATIC_FALSE ; Left mouse button state 16 | service_render_mouse_button_right_semaphore db STATIC_FALSE ; Right mouse button state 17 | 18 | ; Object ID control 19 | service_render_object_id_semaphore db STATIC_FALSE ; Ensures unique object ID assignment 20 | service_render_object_id dq 0x01 ; Initial object ID, incremented as new objects are registered 21 | 22 | ; Memory alignment for next data block 23 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 24 | 25 | ; Object management pointers 26 | service_render_object_selected_pointer dq STATIC_EMPTY ; Pointer to currently selected render object 27 | service_render_object_privileged_pid dq STATIC_EMPTY ; PID of the privileged render object 28 | 29 | ; Render object list management 30 | service_render_object_list_address dq STATIC_EMPTY ; Address of the render object list in memory 31 | servide_render_object_list_size_page dq 1 ; Number of pages allocated for the object list 32 | service_render_object_list_records dq STATIC_EMPTY ; Number of active object records 33 | ; Number of free object slots in the list 34 | service_render_object_list_records_free dq KERNEL_PAGE_SIZE_byte / (SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.SIZE) 35 | service_render_object_list_modify_time dq STATIC_EMPTY ; Timestamp of last modification to the object list 36 | 37 | ; Render fill and zone management 38 | service_render_fill_list_address dq STATIC_EMPTY ; Address of the render fill list 39 | service_render_zone_list_address dq STATIC_EMPTY ; Address of the render zone list 40 | service_render_zone_list_records dq STATIC_EMPTY ; Number of active zones in the list 41 | 42 | ; Inter-process Communication (IPC) Data 43 | 44 | service_render_ipc_data: 45 | times KERNEL_IPC_STRUCTURE.SIZE db STATIC_EMPTY; Allocate space for IPC communication data 46 | 47 | ; Framebuffer Object 48 | 49 | service_render_object_framebuffer: 50 | dq 0; Object X coordinate 51 | dq 0; Object Y coordinate 52 | dq STATIC_EMPTY; Object width 53 | dq STATIC_EMPTY; Object height 54 | dq STATIC_EMPTY; Pointer to framebuffer data 55 | 56 | .extra: 57 | dq STATIC_EMPTY; Additional attributes 58 | dq STATIC_EMPTY; Reserved space 59 | 60 | ; Cursor Object 61 | 62 | service_render_object_cursor: 63 | dq 0; Cursor X coordinate 64 | dq 0; Cursor Y coordinate 65 | dq 12; Cursor width (12 pixels) 66 | dq 19; Cursor height (19 pixels) 67 | dq service_render_object_cursor.data; Pointer to cursor image data 68 | 69 | .extra: 70 | ; Size of cursor data 71 | dq service_render_object_cursor.end - service_render_object_cursor.data 72 | ; Cursor flags 73 | dq SERVICE_RENDER_OBJECT_FLAG_pointer | SERVICE_RENDER_OBJECT_FLAG_flush | SERVICE_RENDER_OBJECT_FLAG_visible 74 | dq STATIC_EMPTY; Reserved field 75 | 76 | .data: 77 | incbin "kernel/service/visual/gfx/cursor.data"; Include cursor image binary data 78 | 79 | .end: 80 | -------------------------------------------------------------------------------- /kernel/service/visual/event.asm: -------------------------------------------------------------------------------- 1 | service_render_event: 2 | push rax 3 | push rbx 4 | push rcx 5 | push rsi 6 | push r8 7 | push r9 8 | push r10 9 | push r11 10 | 11 | call service_render_keyboard 12 | 13 | mov r8d, dword [driver_ps2_mouse_x] 14 | mov r9d, dword [driver_ps2_mouse_y] 15 | 16 | mov r14, r8 17 | sub r14, qword [service_render_object_cursor + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.x] 18 | 19 | mov r15, r9 20 | sub r15, qword [service_render_object_cursor + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.y] 21 | 22 | bt word [driver_ps2_mouse_state], DRIVER_PS2_DEVICE_MOUSE_PACKET_LMB_bit 23 | jnc .no_mouse_button_left_action 24 | 25 | cmp byte [service_render_mouse_button_left_semaphore], STATIC_TRUE 26 | je .no_mouse_button_left_action 27 | 28 | mov byte [service_render_mouse_button_left_semaphore], STATIC_TRUE 29 | 30 | ; INFO: DEBUG MODE 31 | ;cmp qword [service_render_object_selected_pointer], STATIC_EMPTY 32 | ;jne .no_mouse_button_left_action 33 | 34 | call service_render_object_find 35 | jc .no_mouse_button_left_action 36 | 37 | mov qword [service_render_object_selected_pointer], rsi 38 | 39 | mov cl, SERVICE_RENDER_IPC_MOUSE_BUTTON_LEFT_press 40 | call service_render_ipc_mouse 41 | 42 | test qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags], SERVICE_RENDER_OBJECT_FLAG_fixed_z 43 | jnz .fixed_z 44 | 45 | mov rax, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.pid] 46 | call service_render_object_up 47 | 48 | mov qword [service_render_object_selected_pointer], rsi 49 | 50 | or qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags], SERVICE_RENDER_OBJECT_FLAG_flush 51 | 52 | or qword [service_render_object_cursor + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags], SERVICE_RENDER_OBJECT_FLAG_flush 53 | 54 | .fixed_z: 55 | call service_render_object_hide 56 | 57 | .no_mouse_button_left_action: 58 | bt word [driver_ps2_mouse_state], DRIVER_PS2_DEVICE_MOUSE_PACKET_LMB_bit 59 | jc .no_mouse_button_left_release 60 | 61 | .no_mouse_button_left_action_release: 62 | mov byte [service_render_mouse_button_left_semaphore], STATIC_FALSE 63 | 64 | .no_mouse_button_left_action_release_selected: 65 | ; INFO: DEBUG mode 66 | ;mov qword [service_render_object_selected_pointer], STATIC_EMPTY 67 | 68 | .no_mouse_button_left_release: 69 | bt word [driver_ps2_mouse_state], DRIVER_PS2_DEVICE_MOUSE_PACKET_RMB_bit 70 | jnc .no_mouse_button_right_action 71 | 72 | cmp byte [service_render_mouse_button_right_semaphore], STATIC_TRUE 73 | je .no_mouse_button_right_action 74 | 75 | mov byte [service_render_mouse_button_right_semaphore], STATIC_TRUE 76 | 77 | call service_render_object_find 78 | jc .no_mouse_button_right_action 79 | 80 | call service_render_object_hide 81 | 82 | mov cl, SERVICE_RENDER_IPC_MOUSE_BUTTON_RIGHT_press 83 | call service_render_ipc_mouse 84 | 85 | .no_mouse_button_right_action: 86 | bt word [driver_ps2_mouse_state], DRIVER_PS2_DEVICE_MOUSE_PACKET_RMB_bit 87 | jc .no_mouse_button_right_release 88 | 89 | mov byte [service_render_mouse_button_right_semaphore], STATIC_FALSE 90 | 91 | .no_mouse_button_right_release: 92 | test r14, r14 93 | jnz .move 94 | 95 | test r15, r15 96 | jz .end 97 | 98 | .move: 99 | mov rsi, service_render_object_cursor 100 | call service_render_zone_insert_by_object 101 | 102 | add qword [service_render_object_cursor + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.x], r14 103 | add qword [service_render_object_cursor + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.y], r15 104 | 105 | or qword [service_render_object_cursor + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags], SERVICE_RENDER_OBJECT_FLAG_flush 106 | 107 | cmp byte [service_render_mouse_button_left_semaphore], STATIC_FALSE 108 | je .end 109 | 110 | cmp qword [service_render_object_selected_pointer], STATIC_EMPTY 111 | je .end 112 | 113 | call service_render_object_move 114 | 115 | .end: 116 | pop r11 117 | pop r10 118 | pop r9 119 | pop r8 120 | pop rsi 121 | pop rcx 122 | pop rbx 123 | pop rax 124 | 125 | ret 126 | 127 | macro_debug "service_render_event" 128 | -------------------------------------------------------------------------------- /config.asm: -------------------------------------------------------------------------------- 1 | %define DEBUG 2 | 3 | KERNEL_PAGE_mask equ 0xF000 4 | KERNEL_PAGE_SIZE_byte equ 0x1000 5 | KERNEL_PAGE_SIZE_shift equ 12 6 | SOFTWARE_base_address equ KERNEL_MEMORY_HIGH_REAL_address 7 | SERVICE_RENDER_IRQ equ 0x41 8 | SERVICE_RENDER_WINDOW_create equ 0x00 9 | SERVICE_RENDER_WINDOW_update equ 0x01 10 | STATIC_REPLACE_AL_WITH_HIGH_shift equ 8 11 | STATIC_REPLACE_AX_WITH_HIGH_shift equ 16 12 | STATIC_REPLACE_EAX_WITH_HIGH_shift equ 32 13 | STATIC_MULTIPLE_BY_2_shift equ 1 14 | STATIC_MULTIPLE_BY_4_shift equ 2 15 | STATIC_MULTIPLE_BY_8_shift equ 3 16 | STATIC_MULTIPLE_BY_QWORD_shift equ STATIC_MULTIPLE_BY_8_shift 17 | STATIC_MULTIPLE_BY_16_shift equ 4 18 | STATIC_MULTIPLE_BY_32_shift equ 5 19 | STATIC_MULTIPLE_BY_64_shift equ 6 20 | STATIC_MULTIPLE_BY_512_shift equ 9 21 | STATIC_MULTIPLE_BY_PAGE_shift equ KERNEL_PAGE_SIZE_shift 22 | STATIC_DIVIDE_BY_2_shift equ 1 23 | STATIC_DIVIDE_BY_4_shift equ 2 24 | STATIC_DIVIDE_BY_DWORD_shift equ STATIC_DIVIDE_BY_4_shift 25 | STATIC_DIVIDE_BY_8_shift equ 3 26 | STATIC_DIVIDE_BY_QWORD_shift equ STATIC_DIVIDE_BY_8_shift 27 | STATIC_DIVIDE_BY_16_shift equ 4 28 | STATIC_DIVIDE_BY_32_shift equ 5 29 | STATIC_DIVIDE_BY_256_shift equ 8 30 | STATIC_DIVIDE_BY_1024_shift equ 10 31 | STATIC_DIVIDE_BY_PAGE_shift equ KERNEL_PAGE_SIZE_shift 32 | STATIC_MOVE_AL_HALF_TO_HIGH_shift equ 4 33 | STATIC_MOVE_AL_TO_HIGH_shift equ 8 34 | STATIC_MOVE_AX_TO_HIGH_shift equ 16 35 | STATIC_MOVE_EAX_TO_HIGH_shift equ 32 36 | STATIC_MOVE_HIGH_TO_AL_shift equ 8 37 | STATIC_MOVE_HIGH_TO_AX_shift equ 16 38 | STATIC_MOVE_HIGH_TO_EAX_shift equ 32 39 | STATIC_BYTE_mask equ 0xFF 40 | STATIC_BYTE_LOW_mask equ 0x0F 41 | STATIC_BYTE_SIZE_byte equ 0x01 42 | STATIC_WORD_SIZE_byte equ 0x02 43 | STATIC_DWORD_SIZE_byte equ 0x04 44 | STATIC_QWORD_SIZE_byte equ 0x08 45 | STATIC_QWORD_SIZE_bit equ 64 46 | STATIC_WORD_mask equ 0x000000000000FFFF 47 | STATIC_QWORD_mask equ 0xFFFFFFFF00000000 48 | STATIC_BYTE_BIT_sign equ 7 49 | STATIC_WORD_BIT_sign equ 15 50 | STATIC_QWORD_BIT_sign equ 63 51 | STATIC_QWORD_DIGIT_length equ 16 52 | STATIC_ASCII_TERMINATOR equ 0x0000 53 | STATIC_ASCII_BACKSPACE equ 0x0008 54 | STATIC_ASCII_TAB equ 0x0009 55 | STATIC_ASCII_NEW_LINE equ 0x000A 56 | STATIC_ASCII_ENTER equ 0x000D 57 | STATIC_ASCII_ESCAPE equ 0x001B 58 | STATIC_ASCII_SPACE equ 0x0020 59 | STATIC_ASCII_MINUS equ 0x002D 60 | STATIC_ASCII_DOT equ 0x002E 61 | STATIC_ASCII_SLASH equ 0x002F 62 | STATIC_ASCII_DIGIT_0 equ 0x0030 63 | STATIC_ASCII_DIGIT_9 equ 0x0039 64 | STATIC_ASCII_COLON equ 0x003A 65 | STATIC_ASCII_BACKSLASH equ 0x005C 66 | STATIC_ASCII_TILDE equ 0x007E 67 | STATIC_ASCII_DELETE equ 0x007F 68 | 69 | STATIC_TRUE equ 0x00 70 | STATIC_FALSE equ 0x01 71 | 72 | STATIC_EMPTY equ 0x00 73 | STATIC_RESERVED equ STATIC_EMPTY 74 | 75 | STATIC_NOTHING equ 0x90 76 | 77 | STATIC_MAX_unsigned equ -1 78 | 79 | STATIC_NUMBER_SYSTEM_binary equ 0x02 80 | STATIC_NUMBER_SYSTEM_octal equ 0x08 81 | STATIC_NUMBER_SYSTEM_decimal equ 0x0A 82 | STATIC_NUMBER_SYSTEM_hexadecimal equ 0x10 83 | 84 | STATIC_ASCII_SEQUENCE_length equ 0x06 85 | 86 | %define STATIC_COLOR_ASCII_DEFAULT STATIC_COLOR_ASCII_GRAY_LIGHT 87 | %define STATIC_COLOR_ASCII_BLACK "\e[30m" 88 | %define STATIC_COLOR_ASCII_BLUE "\e[34m" 89 | %define STATIC_COLOR_ASCII_GREEN "\e[32m" 90 | %define STATIC_COLOR_ASCII_CYAN "\e[36m" 91 | %define STATIC_COLOR_ASCII_RED "\e[31m" 92 | %define STATIC_COLOR_ASCII_MAGENTA "\e[35m" 93 | %define STATIC_COLOR_ASCII_BROWN "\e[33m" 94 | %define STATIC_COLOR_ASCII_GRAY_LIGHT "\e[37m" 95 | %define STATIC_COLOR_ASCII_GRAY "\e[90m" 96 | %define STATIC_COLOR_ASCII_BLUE_LIGHT "\e[94m" 97 | %define STATIC_COLOR_ASCII_GREEN_LIGHT "\e[92m" 98 | %define STATIC_COLOR_ASCII_CYAN_LIGHT "\e[96m" 99 | %define STATIC_COLOR_ASCII_RED_LIGHT "\e[91m" 100 | %define STATIC_COLOR_ASCII_MAGENTA_LIGHT "\e[95m" 101 | %define STATIC_COLOR_ASCII_YELLOW "\e[93m" 102 | %define STATIC_COLOR_ASCII_WHITE "\e[39m" 103 | 104 | STATIC_COLOR_BACKGROUND_default equ STATIC_COLOR_black 105 | STATIC_COLOR_default equ STATIC_COLOR_gray_light 106 | STATIC_COLOR_black equ 0x00101010 107 | STATIC_COLOR_blue equ 0x000000AA 108 | STATIC_COLOR_green equ 0x0000AA00 109 | STATIC_COLOR_cyan equ 0x0000AAAA 110 | STATIC_COLOR_red equ 0x00AA0000 111 | STATIC_COLOR_magenta equ 0x00AA00AA 112 | STATIC_COLOR_brown equ 0x00AA5500 113 | STATIC_COLOR_gray_light equ 0x00AAAAAA 114 | STATIC_COLOR_gray equ 0x00555555 115 | STATIC_COLOR_blue_light equ 0x005555FF 116 | STATIC_COLOR_green_light equ 0x0055FF55 117 | STATIC_COLOR_cyan_light equ 0x0055FFFF 118 | STATIC_COLOR_red_light equ 0x00FF5555 119 | STATIC_COLOR_magenta_light equ 0x00FF55FF 120 | STATIC_COLOR_yellow equ 0x00FFFF55 121 | STATIC_COLOR_white equ 0x00FFFFFF 122 | 123 | struc STATIC_STRUCTURE_BLOCK 124 | .data resb KERNEL_PAGE_SIZE_byte - STATIC_QWORD_SIZE_byte 125 | .link resb 8 126 | 127 | .SIZE: 128 | endstruc 129 | -------------------------------------------------------------------------------- /kernel/driver/serial.asm: -------------------------------------------------------------------------------- 1 | ; Serial Port Base Addresses: 2 | ; COM1: 0x03F8 3 | ; COM2: 0x02F8 4 | ; 5 | ; Registers: 6 | ; - Data Register (offset 0) → Holds data to be sent/received 7 | ; - Interrupt Enable Register (offset 1) → Controls interrupts 8 | ; - Interrupt Identification / FIFO Control Register (offset 2) → FIFO buffer 9 | ; - Line Control Register (offset 3) → Configures baud rate, parity, stop bits 10 | ; - Modem Control Register (offset 4) → Controls modem status 11 | ; - Line Status Register (offset 5) → Indicates transmission status 12 | ; - Modem Status Register (offset 6) → Monitors modem control lines 13 | ; - Scratch Register (offset 7) → General-purpose storage 14 | 15 | ; Define Base Addresses for Serial Ports 16 | DRIVER_SERIAL_PORT_COM1 equ 0x03F8 17 | DRIVER_SERIAL_PORT_COM2 equ 0x02F8 18 | 19 | ; Define the structure for Serial Port Registers 20 | struc DRIVER_SERIAL_STRUCTURE_REGISTERS 21 | .data_or_divisor_low resb 1 ; Offset 0 - Data Register / Divisor Latch Low 22 | .interrupt_enable_or_divisor_high resb 1 ; Offset 1 - Interrupt Enable / Divisor Latch High 23 | .interrupt_identification_or_fifo resb 1 ; Offset 2 - Interrupt ID / FIFO Control 24 | .line_control_or_dlab resb 1 ; Offset 3 - Line Control / DLAB 25 | .modem_control resb 1 ; Offset 4 - Modem Control 26 | .line_status resb 1 ; Offset 5 - Line Status 27 | .modem_status resb 1 ; Offset 6 - Modem Status 28 | .scratch resb 1 ; Offset 7 - Scratch Register 29 | endstruc 30 | 31 | ; Configures COM1 for communication. 32 | ; - Disables interrupts 33 | ; - Enables DLAB to set baud rate 34 | ; - Configures data format (8 bits, no parity, 1 stop bit) 35 | ; - Enables FIFO buffer 36 | driver_serial: 37 | ; Save register 38 | push rax 39 | push rdx 40 | 41 | ; Disable Serial Port Interrupts 42 | mov al, 0x00 43 | mov dx, DRIVER_SERIAL_PORT_COM1 + DRIVER_SERIAL_STRUCTURE_REGISTERS.interrupt_enable_or_divisor_high 44 | out dx, al 45 | 46 | ; Enable DLAB (Divisor Latch Access Bit) to set baud rate 47 | mov al, 0x80 ; Set DLAB=1 (enables baud rate divisor setting) 48 | mov dx, DRIVER_SERIAL_PORT_COM1 + DRIVER_SERIAL_STRUCTURE_REGISTERS.line_control_or_dlab 49 | out dx, al 50 | 51 | ; Set Baud Rate to 38400 (Divisor = 3) 52 | mov al, 0x03 ; Divisor Latch Low Byte (3 → 38400 baud rate) 53 | mov dx, DRIVER_SERIAL_PORT_COM1 + DRIVER_SERIAL_STRUCTURE_REGISTERS.data_or_divisor_low 54 | out dx, al 55 | mov al, 0x00 ; Divisor Latch High Byte (0) 56 | mov dx, DRIVER_SERIAL_PORT_COM1 + DRIVER_SERIAL_STRUCTURE_REGISTERS.interrupt_enable_or_divisor_high 57 | out dx, al 58 | 59 | ; Configure Line Control Register (8N1 Format) 60 | mov al, 0x03 ; 8 data bits, no parity, 1 stop bit (8N1) 61 | mov dx, DRIVER_SERIAL_PORT_COM1 + DRIVER_SERIAL_STRUCTURE_REGISTERS.line_control_or_dlab 62 | out dx, al 63 | 64 | ; Enable FIFO, Clear Buffers, Set 14-Byte Threshold 65 | mov al, 0xC7 ; Enable FIFO, clear TX/RX, set 14-byte threshold 66 | mov dx, DRIVER_SERIAL_PORT_COM1 + DRIVER_SERIAL_STRUCTURE_REGISTERS.interrupt_identification_or_fifo 67 | out dx, al 68 | 69 | ; Restore Registers 70 | pop rdx 71 | pop rax 72 | 73 | ret 74 | 75 | ; Sends a null-terminated string over the serial port (COM1). 76 | ; - Loops through each character in RSI 77 | ; - Calls driver_serial_ready to check if the port is ready 78 | ; - Sends character when ready 79 | ; 80 | ; Parameters: 81 | ; RSI - Pointer to null-terminated string 82 | driver_serial_send: 83 | ; Save register 84 | push rax 85 | push rdx 86 | push rsi 87 | 88 | ; Set up Data Register Address 89 | mov dx, DRIVER_SERIAL_PORT_COM1 + DRIVER_SERIAL_STRUCTURE_REGISTERS.data_or_divisor_low 90 | 91 | .loop: 92 | lodsb ; Load next byte from RSI into AL 93 | jz .end ; If AL == 0 (null terminator), exit 94 | ; Wait for the port to be ready 95 | call driver_serial_ready 96 | ; Send character to serial port 97 | out dx, al 98 | ; Repeat for next character 99 | jmp .loop 100 | 101 | .end: 102 | ; Restore registers 103 | pop rsi 104 | pop rdx 105 | pop rax 106 | 107 | ret 108 | 109 | ; Waits until the serial port is ready to transmit data. 110 | ; - Reads Line Status Register 111 | ; - Checks Transmitter Holding Register Empty (THRE) and Transmitter Empty (TEMT) 112 | ; 113 | ; Output: 114 | ; Returns when the port is ready for the next byte. 115 | driver_serial_ready: 116 | ; Save register 117 | push rax 118 | push rdx 119 | 120 | ; Set up Line Status Register Address 121 | mov dx, DRIVER_SERIAL_PORT_COM1 + DRIVER_SERIAL_STRUCTURE_REGISTERS.line_status 122 | 123 | .loop: 124 | in al, dx ; Read Line Status Register 125 | 126 | test al, 01100000b ; Check THRE (bit 5) and TEMT (bit 6) 127 | jz .loop ; If not ready, keep checking 128 | 129 | ; Restore register 130 | pop rdx 131 | pop rax 132 | 133 | ret 134 | -------------------------------------------------------------------------------- /kernel/service/network/arp.asm: -------------------------------------------------------------------------------- 1 | service_network_arp: 2 | ; Save the RAX register 3 | push rax 4 | 5 | ; Check if the ARP hardware type is Ethernet (HTYPE = 1) 6 | cmp word [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.htype], SERVICE_NETWORK_FRAME_ARP_HTYPE_ethernet 7 | jne .omit ; If not, skip processing 8 | 9 | ; Check if the ARP protocol type is IPv4 (PTYPE = 0x0800) 10 | cmp word [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.ptype], SERVICE_NETWORK_FRAME_ARP_PTYPE_ipv4 11 | jne .omit ; If not, skip processing 12 | 13 | ; Check if the hardware address length is 6 bytes (MAC address) 14 | cmp byte [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.hal], SERVICE_NETWORK_FRAME_ARP_HAL_mac 15 | jne .omit ; If not, skip processing 16 | 17 | ; Check if the protocol address length is 4 bytes (IPv4 address) 18 | cmp byte [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.pal], SERVICE_NETWORK_FRAME_ARP_PAL_ipv4 19 | jne .omit ; If not, skip processing 20 | 21 | ; Check if the target IP address in the ARP request matches our IP address 22 | mov eax, dword [driver_nic_i82540em_ipv4_address] 23 | cmp eax, dword [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.target_ip] 24 | jne .omit ; If not, skip processing 25 | 26 | ; Save the RDI register 27 | push rdi 28 | 29 | ; Allocate a page for the ARP response 30 | call kernel_memory_alloc_page 31 | jc .error ; If allocation fails, jump to .error 32 | 33 | ; Set the Ethernet frame type to ARP 34 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.type], SERVICE_NETWORK_FRAME_ETHERNET_TYPE_arp 35 | ; Set the ARP hardware type to Ethernet 36 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.htype], SERVICE_NETWORK_FRAME_ARP_HTYPE_ethernet 37 | ; Set the ARP protocol type to IPv4 38 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.ptype], SERVICE_NETWORK_FRAME_ARP_PTYPE_ipv4 39 | ; Set the hardware address length to 6 bytes (MAC address) 40 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.hal], SERVICE_NETWORK_FRAME_ARP_HAL_mac 41 | ; Set the protocol address length to 4 bytes (IPv4 address) 42 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.pal], SERVICE_NETWORK_FRAME_ARP_PAL_ipv4 43 | ; Set the ARP opcode to "reply" 44 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.opcode], SERVICE_NETWORK_FRAME_ARP_OPCODE_answer 45 | ; Set the source IP address in the ARP response to our IP address 46 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.source_ip], eax 47 | 48 | ; Set the target IP address in the ARP response to the sender's IP address 49 | mov eax, dword [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.source_ip] 50 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.target_ip], eax 51 | 52 | ; Set the source MAC address in the Ethernet frame and ARP response to our MAC address 53 | mov rax, qword [driver_nic_i82540em_mac_address] 54 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.source], eax 55 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.source_mac], eax 56 | shr rax, STATIC_MOVE_HIGH_TO_EAX_shift 57 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.source + SERVICE_NETWORK_STRUCTURE_MAC.4], ax 58 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.source_mac + SERVICE_NETWORK_STRUCTURE_MAC.4], ax 59 | 60 | ; Set the target MAC address in the ARP response to the sender's MAC address 61 | mov rax, qword [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.source_mac] 62 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.target_mac], eax 63 | shr rax, STATIC_MOVE_HIGH_TO_EAX_shift 64 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.target_mac + SERVICE_NETWORK_STRUCTURE_MAC.4], ax 65 | 66 | ; Wrap the ARP response in an Ethernet frame 67 | mov rax, qword [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.source_mac] 68 | mov cx, SERVICE_NETWORK_FRAME_ETHERNET_TYPE_arp 69 | call service_network_ethernet_wrap 70 | 71 | ; Send the ARP response 72 | mov eax, SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ARP.SIZE 73 | call service_network_transfer 74 | 75 | .error: 76 | ; Restore the RDI register 77 | pop rdi 78 | 79 | .omit: 80 | ; Restore the RAX register 81 | pop rax 82 | 83 | ; Jump to the end of the network service handler 84 | jmp service_network.end 85 | 86 | ; Debug macro to mark the end of the ARP handler 87 | macro_debug "service_network_arp" -------------------------------------------------------------------------------- /kernel/service/network/icmp.asm: -------------------------------------------------------------------------------- 1 | service_network_icmp: 2 | ; Saver register 3 | push rax 4 | push rbx 5 | push rcx 6 | push rsi 7 | push rdi 8 | 9 | ; Check if the received ICMP packet is an echo request 10 | cmp byte [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.type], SERVICE_NETWORK_FRAME_ICMP_TYPE_REQUEST 11 | jne .end 12 | 13 | ; Calculate IP header length from the incoming packet 14 | movzx ebx, byte [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.version_and_ihl] 15 | and bl, SERVICE_NETWORK_FRAME_IP_HEADER_LENGTH_mask 16 | shl bl, STATIC_MULTIPLE_BY_4_shift 17 | 18 | ; Allocate memory for response packet 19 | call kernel_memory_alloc_page 20 | jc .end 21 | 22 | ; Construct Ethernet, IP, and ICMP headers for the reply 23 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.type], SERVICE_NETWORK_FRAME_ETHERNET_TYPE_ip 24 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.version_and_ihl], SERVICE_NETWORK_FRAME_IP_HEADER_LENGTH_default | SERVICE_NETWORK_FRAME_IP_VERSION_4 25 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.dscp_and_ecn], STATIC_EMPTY 26 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.total_length], (SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.SIZE >> STATIC_REPLACE_AL_WITH_HIGH_shift) | (SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.SIZE << STATIC_REPLACE_AL_WITH_HIGH_shift) 27 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.identification], STATIC_EMPTY 28 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.f_and_f], STATIC_EMPTY 29 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.ttl], SERVICE_NETWORK_FRAME_IP_TTL_default 30 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.protocol], SERVICE_NETWORK_FRAME_IP_PROTOCOL_ICMP 31 | ; Set ICMP reply type and initialize reserved fields 32 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.type], SERVICE_NETWORK_FRAME_ICMP_TYPE_REPLY 33 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.code], STATIC_EMPTY 34 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.reserved], STATIC_EMPTY 35 | 36 | add rdi, SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE 37 | 38 | ; Copy ICMP payload from request to reply 39 | mov eax, dword [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.reserved] 40 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.reserved], eax 41 | 42 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.checksum], STATIC_EMPTY 43 | 44 | push rsi 45 | push rdi 46 | 47 | mov ecx, SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.SIZE - SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.data 48 | add rsi, SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.data 49 | add rdi, SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.data 50 | rep movsb 51 | 52 | pop rdi 53 | pop rsi 54 | 55 | ; Compute ICMP checksum 56 | xor eax, eax 57 | mov ecx, SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.SIZE >> STATIC_DIVIDE_BY_2_shift 58 | call service_network_checksum 59 | 60 | rol ax, STATIC_REPLACE_AL_WITH_HIGH_shift 61 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.checksum], ax 62 | 63 | sub rdi, SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE 64 | 65 | ; Swap source and destination IP addresses 66 | mov eax, dword [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.source_address] 67 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_IP.destination_address], eax 68 | 69 | mov eax, dword [driver_nic_i82540em_ipv4_address] 70 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_IP.source_address], eax 71 | 72 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_IP.checksum], STATIC_EMPTY 73 | 74 | ; Compute IP checksum 75 | xor eax, eax 76 | mov ecx, (SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.SIZE) >> STATIC_DIVIDE_BY_2_shift 77 | call service_network_checksum 78 | rol ax, STATIC_REPLACE_AL_WITH_HIGH_shift 79 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_IP.checksum], ax 80 | 81 | ; Wrap response in Ethernet frame and send 82 | sub rdi, SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE 83 | mov rax, qword [rsi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.source] 84 | mov cx, SERVICE_NETWORK_FRAME_ETHERNET_TYPE_ip 85 | call service_network_ethernet_wrap 86 | 87 | mov eax, SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_ICMP.SIZE 88 | call service_network_transfer 89 | 90 | .end: 91 | pop rdi 92 | pop rsi 93 | pop rcx 94 | pop rbx 95 | pop rax 96 | 97 | jmp service_network_ip.end 98 | 99 | macro_debug "service_network_icmp" -------------------------------------------------------------------------------- /kernel/init/data.asm: -------------------------------------------------------------------------------- 1 | ; Kernel name 2 | kernel_init_string_name db KERNEL_name 3 | 4 | kernel_init_string_name_end: 5 | 6 | ; These strings are used for error reporting during kernel bootup. 7 | ; Each message is null-terminated (STATIC_ASCII_TERMINATOR). 8 | kernel_init_string_error_video_header db "Error: no graphic mode header in multiboot table", STATIC_ASCII_TERMINATOR 9 | kernel_init_string_error_memory_header db "Error: no memory map header in multiboot header", STATIC_ASCII_TERMINATOR 10 | kernel_init_string_error_memory db "Error: memory map damaged", STATIC_ASCII_TERMINATOR 11 | kernel_init_string_error_memory_low db "Error: not enough memory", STATIC_ASCII_TERMINATOR 12 | kernel_init_string_error_acpi_header db "Error: RSDP/XSDP not found", STATIC_ASCII_TERMINATOR 13 | kernel_init_string_error_acpi db "Error: RSDT/XSDT not recognized", STATIC_ASCII_TERMINATOR 14 | kernel_init_string_error_apic db "Error: APIC not found", STATIC_ASCII_TERMINATOR 15 | kernel_init_string_error_ioapic db "Error: I/O APIC not found", STATIC_ASCII_TERMINATOR 16 | 17 | ; These strings define standard storage device paths for IDE drives. 18 | ; Used for device identification and access. 19 | kernel_init_string_storage_ide_hd_path db "/dev/hd" ; Base path for IDE hard drives 20 | kernel_init_string_storage_ide_hd_letter db "a" ; Default device letter 21 | 22 | kernel_init_string_storage_ide_hd_end: 23 | 24 | ; These variables serve as semaphores (flags) to track the initialization 25 | ; status of key system components (APIC, I/O APIC, SMP, AP processors). 26 | kernel_init_apic_semaphore db STATIC_FALSE ; APIC initialization status 27 | kernel_init_ioapic_semaphore db STATIC_FALSE ; I/O APIC initialization status 28 | kernel_init_smp_semaphore db STATIC_FALSE ; SMP initialization status 29 | kernel_init_ap_semaphore db STATIC_FALSE ; AP processor initialization status 30 | kernel_init_ap_count db STATIC_EMPTY ; Number of detected APs 31 | 32 | kernel_init_apic_id_highest db STATIC_EMPTY ; Highest detected APIC ID 33 | 34 | ; This table lists the kernel services available at boot time. 35 | ; Each entry consists of: 36 | ; - A 64-bit pointer to the service entry point 37 | ; - A byte indicating the length of the service name 38 | ; - The service name as a null-terminated string 39 | 40 | ; The list ends with a STATIC_EMPTY marker. 41 | 42 | kernel_init_services_list: 43 | dq service_tresher; Pointer to "tresher" service 44 | db 7; Length of "tresher" 45 | db "tresher" 46 | dq service_render; Pointer to "render" service 47 | db 6; Length of "render" 48 | db "render" 49 | dq service_datea; Pointer to "date" service 50 | db 4; Length of "date" 51 | db "date" 52 | dq STATIC_EMPTY; End of list marker 53 | 54 | ; Defines the initial directories available in the virtual file system. 55 | ; Each directory entry consists of: 56 | ; - A byte indicating the length of the directory name 57 | ; - The directory name as a null-terminated string 58 | 59 | ; The list ends with a STATIC_EMPTY marker. 60 | 61 | kernel_init_vfs_directory_structure: 62 | db 0x04; Length of "/bin" 63 | db "/bin" 64 | db 0x04; Length of "/dev" 65 | db "/dev" 66 | 67 | db STATIC_EMPTY; End of list marker 68 | 69 | ; Defines initial files available in the VFS. 70 | ; Each file entry consists of: 71 | ; - A 64-bit pointer to the file data 72 | ; - The file size (calculated as the difference between file start and end) 73 | ; - A byte indicating the length of the file path 74 | ; - The file path as a null-terminated string 75 | 76 | ; The list ends with a STATIC_EMPTY marker. 77 | 78 | kernel_init_vfs_files: 79 | ;dq kernel_init_vfs_file_init 80 | ;dq kernel_init_vfs_file_init_end - kernel_init_vfs_file_init 81 | ;db 9 82 | ;db "/bin/init" 83 | 84 | ;dq kernel_init_vfs_file_shell 85 | ;dq kernel_init_vfs_file_shell_end - kernel_init_vfs_file_shell 86 | ;db 10 87 | ;db "/bin/shell" 88 | 89 | ;dq kernel_init_vfs_file_hello 90 | ;dq kernel_init_vfs_file_hello_end - kernel_init_vfs_file_hello 91 | ;db 10 92 | ;db "/bin/hello" 93 | 94 | ;dq kernel_init_vfs_file_free 95 | ;dq kernel_init_vfs_file_free_end - kernel_init_vfs_file_free 96 | ;db 9 97 | ;db "/bin/free" 98 | 99 | dq kernel_init_vfs_file_console; Pointer to "/bin/console" file 100 | dq kernel_init_vfs_file_console_end - kernel_init_vfs_file_console 101 | db 12; Length of "/bin/console" 102 | db "/bin/console" 103 | dq STATIC_EMPTY; End of list marker 104 | 105 | ;kernel_init_vfs_file_init_end: 106 | ; kernel_init_vfs_file_shell incbin "build/shell" 107 | 108 | ;kernel_init_vfs_file_shell_end: 109 | ; kernel_init_vfs_file_hello incbin "build/hello" 110 | 111 | ;kernel_init_vfs_file_hello_end: 112 | ; kernel_init_vfs_file_free incbin "build/free" 113 | 114 | ; These sections contain the binary data for initial VFS files. 115 | ; The actual files are included from external build artifacts. 116 | 117 | kernel_init_vfs_file_free_end: 118 | kernel_init_vfs_file_console incbin "build/console" ; Include the compiled "console" binary 119 | 120 | kernel_init_vfs_file_console_end: 121 | 122 | ; This section includes the boot loader binary, used during system startup. 123 | 124 | kernel_init_boot_file: 125 | incbin "build/boot"; Include the compiled boot binary 126 | 127 | kernel_init_boot_file_end: 128 | -------------------------------------------------------------------------------- /kernel/service/date/data.asm: -------------------------------------------------------------------------------- 1 | service_date_pid dq STATIC_EMPTY 2 | ;Store the last state of the clock 3 | service_date_clock_last_state dq STATIC_EMPTY 4 | ; Character to be displayed as the clock colon, initially set to space 5 | service_date_clock_colon db STATIC_ASCII_SPACE 6 | ; Path to the event console binary file 7 | service_date_event_console_file db "/bin/console" 8 | 9 | service_date_event_console_file_end: 10 | ; Align memory to ensure proper structure placement 11 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 12 | 13 | ; Define IPC (Inter-Process Communication) data structure 14 | 15 | service_date_ipc_data: 16 | times KERNEL_IPC_STRUCTURE.SIZE db STATIC_EMPTY 17 | ; Align memory again for correct struct alignment 18 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 19 | 20 | ; Define main workbench window properties 21 | service_date_window_workbench dq 0 ; Window pointer 22 | dq 0; Reserved field 23 | dq STATIC_EMPTY; Placeholder for additional properties 24 | dq STATIC_EMPTY; Placeholder for additional properties 25 | dq STATIC_EMPTY; Placeholder for additional properties 26 | 27 | .extra: 28 | dq STATIC_EMPTY; Reserved extra data 29 | ; Window flag 30 | dq INCLUDE_UNIT_WINDOW_FLAG_fixed_xy | INCLUDE_UNIT_WINDOW_FLAG_fixed_z | INCLUDE_UNIT_WINDOW_FLAG_visible | INCLUDE_UNIT_WINDOW_FLAG_flush 31 | dq STATIC_EMPTY; Placeholder for additional properties 32 | db 16 33 | db "date - workbench " 34 | dq STATIC_EMPTY; Placeholder for additional properties 35 | 36 | ; Align memory for correct struct alignment 37 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 38 | 39 | ; add window taskbar date 40 | service_date_window_taskbar_modify_time dq STATIC_EMPTY 41 | 42 | ; Define taskbar window properties 43 | service_date_window_taskbar dq 0 ; Taskbar window pointer 44 | dq STATIC_EMPTY; Placeholder for additional properties 45 | dq STATIC_EMPTY; Placeholder for additional properties 46 | dq SERVICE_DATE_WINDOW_TASKBAR_HEIGHT_pixel; Taskbar height 47 | dq STATIC_EMPTY; Placeholder for additional properties 48 | 49 | ; Extra window properties for taskbar 50 | 51 | .extra: 52 | dq STATIC_EMPTY 53 | dq INCLUDE_UNIT_WINDOW_FLAG_fixed_xy | INCLUDE_UNIT_WINDOW_FLAG_fixed_z | INCLUDE_UNIT_WINDOW_FLAG_arbiter | INCLUDE_UNIT_WINDOW_FLAG_visible | INCLUDE_UNIT_WINDOW_FLAG_flush | INCLUDE_UNIT_WINDOW_FLAG_unregistered 54 | dq STATIC_EMPTY 55 | db 14 56 | db "cero - taskbar " 57 | dq STATIC_EMPTY 58 | 59 | ; UI elements for taskbar 60 | 61 | .elements: 62 | ; Chain Element (Placeholder for additional elements) 63 | .element_chain_0: dd INCLUDE_UNIT_ELEMENT_TYPE_chain ; Element type: Chain 64 | dq STATIC_EMPTY; Placeholder 65 | dq STATIC_EMPTY; Placeholder 66 | 67 | ; Clock Label Element 68 | .element_label_clock: dd INCLUDE_UNIT_ELEMENT_TYPE_label ; Element type: Label 69 | dq .element_label_clock_end - .element_label_clock; Element size 70 | dq 0; X position (relative) 71 | dq 0; Y position (relative) 72 | ; Width in pixels 73 | dq INCLUDE_FONT_WIDTH_pixel * (.element_label_clock_end - .element_label_clock_string_hour) 74 | dq INCLUDE_FONT_HEIGHT_pixel; Height in pixels 75 | dq STATIC_EMPTY; Reserved field 76 | db .element_label_clock_end - .element_label_clock_string_hour; String length 77 | ; Clock Time Display (HH:MM) 78 | .element_label_clock_string_hour: db "00" ; Initial hour value 79 | .element_label_clock_char_colon: db ":" ; Separator 80 | .element_label_clock_string_minute: db "00" ; Initial minute value 81 | 82 | .element_label_clock_end: 83 | 84 | dd STATIC_EMPTY 85 | 86 | service_date_window_taskbar_end: 87 | 88 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 89 | 90 | ; Window Menu Configuration 91 | 92 | service_date_window_menu: 93 | dq 160; Window width 94 | dq 80; Window height 95 | dq STATIC_EMPTY; Placeholder 96 | dq STATIC_EMPTY; Placeholder 97 | dq STATIC_EMPTY; Placeholder 98 | 99 | .extra: 100 | dq STATIC_EMPTY; Placeholder for future settings 101 | ; Flags for fragile & unregistered window behavior 102 | dq INCLUDE_UNIT_WINDOW_FLAG_fragile | INCLUDE_UNIT_WINDOW_FLAG_unregistered 103 | dq STATIC_EMPTY; Reserved field 104 | db 11 105 | db "cero - menu " 106 | dq STATIC_EMPTY; Reserved field 107 | 108 | ; UI Elements for Menu Window 109 | 110 | .elements: 111 | ; Header Element 112 | 113 | .element_header: 114 | dd INCLUDE_UNIT_ELEMENT_TYPE_header; Element type: Header 115 | dq .element_header_end - .element_header; Element size 116 | dq 0; X position (relative) 117 | dq 0; Y position (relative) 118 | dq STATIC_EMPTY; Placeholder width 119 | dq INCLUDE_UNIT_ELEMENT_HEADER_HEIGHT_pixel; Height in pixels 120 | dq STATIC_EMPTY; Reserved field 121 | db .element_header_end - .element_header_string; String length 122 | .element_header_string: db "Menu" ; Header text 123 | 124 | .element_header_end: 125 | ; Console Label Element 126 | 127 | .element_label_0: 128 | ; Element type: Label 129 | dd INCLUDE_UNIT_ELEMENT_TYPE_label 130 | dq .element_label_0_end - .element_label_0; Element size 131 | dq 0; X position (relative) 132 | dq INCLUDE_UNIT_ELEMENT_HEADER_HEIGHT_pixel; Y position below header 133 | ; Width in pixels 134 | dq ((.element_label_0_end - .element_label_0_string) * INCLUDE_FONT_WIDTH_pixel) 135 | dq INCLUDE_FONT_HEIGHT_pixel; Height in pixels 136 | dq service_date_event_console; Associated event handler 137 | db .element_label_0_end - .element_label_0_string; String length 138 | .element_label_0_string: db " Console " ; Label text 139 | 140 | .element_label_0_end: 141 | dd STATIC_EMPTY; End of label element 142 | 143 | service_date_window_menu_end: 144 | -------------------------------------------------------------------------------- /kernel/service/date/init.asm: -------------------------------------------------------------------------------- 1 | service_date_init: 2 | ; Check if the service render semaphore is set to false 3 | cmp byte [service_render_semaphore], STATIC_FALSE 4 | je service_date_init; If false, wait for it to be set 5 | 6 | call kernel_task_active_pid 7 | mov qword [service_date_pid], rax 8 | 9 | ; Initialize the workbench window structure 10 | mov rsi, service_date_window_workbench 11 | 12 | ; Load kernel video properties 13 | mov rax, qword [kernel_video_width_pixel]; Get screen width in pixels 14 | mov rbx, qword [kernel_video_height_pixel]; Get screen height in pixels 15 | mov rcx, qword [kernel_video_size_byte]; Get total video memory size 16 | ; Store the video properties into the workbench window structure 17 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.width], rax 18 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.height], rbx 19 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.size], rcx 20 | 21 | ; Allocate memory for the workbench window 22 | call include_page_from_size; Get required page size 23 | call kernel_memory_alloc; Allocate memory 24 | ; Store address 25 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.address], rdi 26 | 27 | ; Set background color for the workbench 28 | mov eax, SERVICE_DATE_WINDOW_WORKBENCH_BACKGROUND_color 29 | mov rcx, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.size] 30 | shr rcx, STATIC_DIVIDE_BY_DWORD_shift; Convert size to DWORD count 31 | rep stosd; Fill allocated memory with background color 32 | 33 | ; Generate a new render object ID and store it 34 | call service_render_object_id_new 35 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.id], rcx 36 | 37 | ; Insert the workbench into the render system 38 | call service_render_object_insert 39 | ; Initialize the taskbar window 40 | mov rsi, service_date_window_taskbar 41 | 42 | ; Adjust taskbar position to bottom of the screen 43 | sub rbx, SERVICE_DATE_WINDOW_TASKBAR_HEIGHT_pixel; Align taskbar at the bottom 44 | mov qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.y], rbx 45 | 46 | ; Set taskbar width to match screen width 47 | mov rax, qword [kernel_video_width_pixel] 48 | mov qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width], rax 49 | 50 | ; Adjust clock position on the taskbar (right-aligned) 51 | sub rax, qword [service_date_window_taskbar.element_label_clock + INCLUDE_UNIT_STRUCTURE_ELEMENT_LABEL.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 52 | mov qword [service_date_window_taskbar.element_label_clock + INCLUDE_UNIT_STRUCTURE_ELEMENT_LABEL.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.field + INCLUDE_UNIT_STRUCTURE_FIELD.x], rax 53 | 54 | ; Compute taskbar memory size 55 | mov rax, qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 56 | shl rax, KERNEL_VIDEO_DEPTH_shift; Adjust for video depth 57 | mul qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.height]; Compute total size 58 | 59 | ; Allocate memory for the object based on its required size 60 | mov rcx, rax; Set RCX to the calculated size of the object 61 | call include_page_from_size; Compute the required number of pages 62 | call kernel_memory_alloc; Allocate memory for the object 63 | 64 | ; Store the allocated address in the render object structure 65 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.address], rdi 66 | ; Initialize the unit (window or UI component) 67 | call include_unit 68 | 69 | ; Generate a new unique object ID for the render object 70 | call service_render_object_id_new 71 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.id], rcx 72 | 73 | ; Insert the render object into the system's render list 74 | call service_render_object_insert 75 | ; Move to initializing the menu window 76 | mov rsi, service_date_window_menu 77 | ; Set up the elements of the menu window 78 | call include_unit_elements_specification 79 | 80 | ; Assign the width and height values from registers 81 | mov qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width], r8 82 | mov qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.height], r9 83 | 84 | ; Calculate the total memory required for the menu window 85 | mov rax, qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 86 | shl rax, KERNEL_VIDEO_DEPTH_shift 87 | mul qword [rsi + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.height] 88 | 89 | ; Allocate memory for the menu window 90 | mov rcx, rax 91 | call include_page_from_size 92 | call kernel_memory_alloc 93 | ; Store the allocated address for the menu window 94 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.address], rdi 95 | ; Initialize the menu window as a unit 96 | call include_unit 97 | ; Generate a new unique ID for the menu window object 98 | call service_render_object_id_new 99 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.id], rcx 100 | ; Insert the menu window render object into the render list 101 | call service_render_object_insert 102 | ; Synchronize the modification timestamps between service date and service render 103 | mov rax, qword [service_render_object_list_modify_time] 104 | mov qword [service_date_window_taskbar_modify_time], rax 105 | -------------------------------------------------------------------------------- /aiden/aiden.asm: -------------------------------------------------------------------------------- 1 | %include "aiden/config.asm" 2 | 3 | [BITS 16] 4 | 5 | [ORG STATIC_AIDEN_base_address] 6 | 7 | aiden: 8 | cli 9 | 10 | jmp 0x0000:.repair_cs 11 | 12 | .repair_cs: 13 | xor ax, ax 14 | mov ds, ax 15 | mov es, ax 16 | mov ss, ax 17 | 18 | mov sp, STATIC_AIDEN_stack 19 | 20 | cld 21 | 22 | mov al, STATIC_EMPTY 23 | out DRIVER_PIT_PORT_command, al 24 | 25 | sti 26 | 27 | mov ax, 0x0003 28 | int 0x10 29 | 30 | mov ah, 0x42 31 | mov si, aiden_table_disk_address_packet 32 | int 0x13 33 | 34 | mov si, STATIC_AIDEN_ERROR_disk 35 | 36 | jc aiden_panic 37 | 38 | xor ebx, ebx 39 | mov edx, 0x534D4150 40 | 41 | mov si, STATIC_AIDEN_ERROR_memory 42 | 43 | mov edi, STATIC_AIDEN_memory_map 44 | 45 | .memory: 46 | mov eax, 0x14 47 | stosd 48 | 49 | mov eax, 0xE820 50 | mov ecx, 0x14 51 | int 0x15 52 | 53 | jc aiden_panic 54 | 55 | add edi, 0x14 56 | 57 | test ebx, ebx 58 | jnz .memory 59 | 60 | mov al, 0xFF 61 | out DRIVER_PIC_PORT_SLAVE_data, al 62 | out DRIVER_PIC_PORT_MASTER_data, al 63 | 64 | mov ax, 0x4F00 65 | mov si, STATIC_AIDEN_ERROR_video 66 | mov di, STATIC_AIDEN_video_vga_info_block 67 | int 0x10 68 | 69 | test ax, 0x4F00 70 | jnz aiden_panic 71 | 72 | mov esi, dword [di + STATIC_AIDEN_VIDEO_STRUCTURE_VGA_INFO_BLOCK.video_mode_ptr] 73 | 74 | .loop: 75 | cmp word [esi], 0xFFFF 76 | je .error 77 | 78 | mov ax, 0x4F01 79 | mov cx, word [esi] 80 | mov di, STATIC_AIDEN_video_mode_info_block 81 | int 0x10 82 | 83 | cmp word [di + STATIC_AIDEN_VIDEO_STRUCTURE_MODE_INFO_BLOCK.x_resolution], MULTIBOOT_VIDEO_WIDTH_pixel 84 | jne .next 85 | 86 | cmp word [di + STATIC_AIDEN_VIDEO_STRUCTURE_MODE_INFO_BLOCK.y_resolution], MULTIBOOT_VIDEO_HEIGHT_pixel 87 | jne .next 88 | 89 | cmp byte [di + STATIC_AIDEN_VIDEO_STRUCTURE_MODE_INFO_BLOCK.bits_per_pixel], STATIC_AIDEN_VIDEO_DEPTH_bit 90 | je .found 91 | 92 | .next: 93 | add esi, STATIC_WORD_SIZE_byte 94 | 95 | jmp .loop 96 | 97 | .error: 98 | mov si, STATIC_AIDEN_ERROR_video 99 | jmp aiden_panic 100 | 101 | .found: 102 | mov ax, 0x4F02 103 | mov bx, word [esi] 104 | or bx, STATIC_AIDEN_VIDEO_MODE_linear | STATIC_AIDEN_VIDEO_MODE_clean 105 | int 0x10 106 | 107 | test ah, ah 108 | jnz .error 109 | 110 | cli 111 | 112 | lgdt [aiden_header_gdt_32bit] 113 | 114 | mov eax, cr0 115 | bts eax, 0 116 | mov cr0, eax 117 | 118 | jmp long 0x0008:aiden_protected_mode 119 | 120 | aiden_panic: 121 | mov ax, 0xB800 122 | mov ds, ax 123 | 124 | mov word [ds:0x0000], si 125 | 126 | jmp $ 127 | 128 | aiden_line_a20_check: 129 | push ds 130 | 131 | mov ax, 0xFFFF 132 | mov ds, ax 133 | 134 | mov ebx, dword [ds:STATIC_AIDEN_base_address + 0x10] 135 | 136 | pop ds 137 | 138 | test ebx, dword [ds:STATIC_AIDEN_base_address] 139 | 140 | ret 141 | 142 | aiden_ps2_keyboard_in: 143 | in al, 0x64 144 | test al, 2 145 | 146 | jnz aiden_ps2_keyboard_in 147 | 148 | ret 149 | 150 | aiden_ps2_keyboard_out: 151 | in al, 0x64 152 | test al, 1 153 | jz aiden_ps2_keyboard_out 154 | 155 | ret 156 | 157 | [BITS 32] 158 | 159 | aiden_protected_mode: 160 | mov ax, 0x10 161 | mov ds, ax 162 | mov es, ax 163 | mov ss, ax 164 | 165 | mov ecx, edi 166 | sub ecx, STATIC_AIDEN_memory_map 167 | 168 | mov edi, STATIC_AIDEN_multiboot_header 169 | 170 | mov dword [edi + STATIC_MULTIBOOT_header.flags], STATIC_MULTIBOOT_HEADER_FLAG_memory_map | STATIC_MULTIBOOT_HEADER_FLAG_video 171 | 172 | mov dword [edi + STATIC_MULTIBOOT_header.mmap_length], ecx 173 | mov dword [edi + STATIC_MULTIBOOT_header.mmap_addr], STATIC_AIDEN_memory_map 174 | 175 | mov eax, dword [STATIC_AIDEN_video_mode_info_block + STATIC_AIDEN_VIDEO_STRUCTURE_MODE_INFO_BLOCK.physical_base_address] 176 | mov dword [edi + STATIC_MULTIBOOT_header.framebuffer_addr], eax 177 | mov dword [edi + STATIC_MULTIBOOT_header.framebuffer_width], MULTIBOOT_VIDEO_WIDTH_pixel 178 | mov dword [edi + STATIC_MULTIBOOT_header.framebuffer_height], MULTIBOOT_VIDEO_HEIGHT_pixel 179 | mov byte [edi + STATIC_MULTIBOOT_header.framebuffer_bpp], STATIC_AIDEN_VIDEO_DEPTH_bit 180 | mov byte [edi + STATIC_MULTIBOOT_header.framebuffer_type], STATIC_EMPTY 181 | 182 | mov esi, STATIC_AIDEN_kernel_address << STATIC_SEGMENT_to_pointer 183 | mov edi, STATIC_AIDEN_kernel_address << STATIC_SEGMENT_to_pointer << STATIC_SEGMENT_to_pointer 184 | mov ecx, (file_kernel_end - file_kernel) / 0x04 185 | rep movsd 186 | 187 | mov ebx, STATIC_AIDEN_multiboot_header 188 | 189 | jmp STATIC_AIDEN_kernel_address << STATIC_SEGMENT_to_pointer << STATIC_SEGMENT_to_pointer 190 | 191 | align 0x04 192 | 193 | aiden_table_disk_address_packet: 194 | db 0x10 195 | db STATIC_EMPTY 196 | dw (file_kernel_end - file_kernel) / STATIC_SECTOR_SIZE_byte 197 | dw 0x0000 198 | dw STATIC_AIDEN_kernel_address 199 | dq 0x0000000000000001 200 | 201 | align 0x10 202 | 203 | aiden_table_gdt_32bit: 204 | dq STATIC_EMPTY 205 | dq 0000000011001111100110000000000000000000000000001111111111111111b 206 | dq 0000000011001111100100100000000000000000000000001111111111111111b 207 | 208 | aiden_table_gdt_32bit_end: 209 | 210 | aiden_header_gdt_32bit: 211 | dw aiden_table_gdt_32bit_end - aiden_table_gdt_32bit - 0x01 212 | dd aiden_table_gdt_32bit 213 | 214 | times 436 - ( $ - $$ ) db 0x00 215 | 216 | db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 217 | 218 | db 0x00 219 | db 0x00, 0x00, 0x00 220 | db 0xEB 221 | db 0x00, 0x00, 0x00 222 | dd (file_kernel_end - $$) / 512 223 | dd (1048576 - (file_kernel_end - $$)) / 512 224 | 225 | times 510 - ($ - $$) db STATIC_EMPTY 226 | dw STATIC_AIDEN_magic 227 | 228 | file_kernel: 229 | incbin "build/kernel" 230 | align STATIC_SECTOR_SIZE_byte 231 | 232 | file_kernel_end: 233 | 234 | times 1048576 - ($ - $$) db STATIC_EMPTY 235 | -------------------------------------------------------------------------------- /kernel/service.asm: -------------------------------------------------------------------------------- 1 | kernel_service: 2 | push rax 3 | 4 | cmp al, KERNEL_SERVICE_PROCESS 5 | je .process 6 | 7 | cmp al, KERNEL_SERVICE_VIDEO 8 | je .video 9 | 10 | cmp al, KERNEL_SERVICE_VFS 11 | je .vfs 12 | 13 | cmp al, KERNEL_SERVICE_SYSTEM 14 | je .system 15 | 16 | .error: 17 | stc 18 | 19 | .end: 20 | pushf 21 | pop rax 22 | 23 | mov qword [rsp + KERNEL_TASK_STRUCTURE_IRETQ.eflags + STATIC_QWORD_SIZE_byte], rax 24 | 25 | pop rax 26 | 27 | iretq 28 | 29 | .process: 30 | cmp ax, KERNEL_SERVICE_PROCESS_exit 31 | je kernel_task_kill 32 | 33 | cmp ax, KERNEL_SERVICE_PROCESS_run 34 | je .process_run 35 | 36 | cmp ax, KERNEL_SERVICE_PROCESS_check 37 | je .process_check 38 | 39 | cmp ax, KERNEL_SERVICE_PROCESS_memory_alloc 40 | je .process_memory_alloc 41 | 42 | cmp ax, KERNEL_SERVICE_PROCESS_ipc_receive 43 | je .process_ipc_receive 44 | 45 | cmp ax, KERNEL_SERVICE_PROCESS_pid 46 | je .process_pid 47 | 48 | jmp kernel_service.error 49 | 50 | .process_run: 51 | push rsi 52 | push rdi 53 | push rcx 54 | 55 | call kernel_vfs_path_resolve 56 | jc .process_run_end 57 | 58 | call kernel_vfs_file_find 59 | jc .process_run_end 60 | 61 | call kernel_exec 62 | 63 | mov qword [rsp], rcx 64 | 65 | .process_run_end: 66 | pop rcx 67 | pop rdi 68 | pop rsi 69 | 70 | mov qword [rsp], rax 71 | 72 | jmp kernel_service.end 73 | 74 | .process_check: 75 | call kernel_task_pid_check 76 | 77 | jmp kernel_service.end 78 | 79 | .process_memory_alloc: 80 | push rax 81 | push rbx 82 | push rcx 83 | push rdi 84 | push r8 85 | push r11 86 | 87 | call include_page_from_size 88 | 89 | call kernel_service_memory_alloc 90 | jc .process_memory_alloc_error 91 | 92 | mov rax, rdi 93 | sub rax, qword [kernel_memory_high_mask] 94 | mov bx, KERNEL_PAGE_FLAG_write | KERNEL_PAGE_FLAG_user | KERNEL_PAGE_FLAG_available 95 | mov r11, cr3 96 | call kernel_page_map_logical 97 | jnc .process_memory_alloc_ready 98 | 99 | call kernel_service_memory_release 100 | 101 | .process_memory_alloc_error: 102 | stc 103 | mov qword [rsp + STATIC_QWORD_SIZE_byte], KERNEL_ERROR_memory_low 104 | 105 | jmp .process_memory_alloc_end 106 | 107 | .process_memory_alloc_ready: 108 | mov qword [rsp], rdi 109 | 110 | .process_memory_alloc_end: 111 | pop rdi 112 | pop rax 113 | pop r11 114 | pop r8 115 | pop rcx 116 | pop rbx 117 | 118 | jmp kernel_service.end 119 | 120 | .process_ipc_receive: 121 | call kernel_ipc_receive 122 | jmp kernel_service.end 123 | 124 | .process_pid: 125 | call kernel_task_active_pid 126 | mov qword [rsp], rax 127 | 128 | jmp kernel_service.end 129 | 130 | .video: 131 | cmp ax, KERNEL_SERVICE_VIDEO_properties 132 | je .video_properties 133 | 134 | jmp kernel_service.error 135 | 136 | .video_properties: 137 | mov r8, qword [kernel_video_width_pixel] 138 | mov r9, qword [kernel_video_height_pixel] 139 | 140 | mov r10, qword [kernel_video_size_byte] 141 | 142 | jmp kernel_service.end 143 | 144 | .vfs: 145 | cmp ax, KERNEL_SERVICE_VFS_exist 146 | jne kernel_service.error 147 | 148 | xor eax, eax 149 | 150 | push rcx 151 | push rsi 152 | push rdi 153 | 154 | call kernel_vfs_path_resolve 155 | jc .vfs_exist_not 156 | 157 | call kernel_vfs_file_find 158 | 159 | .vfs_exist_not: 160 | pop rdi 161 | pop rsi 162 | pop rcx 163 | 164 | mov qword [rsp], rax 165 | 166 | jmp kernel_service.end 167 | 168 | .system: 169 | cmp ax, KERNEL_SERVICE_SYSTEM_memory 170 | jne kernel_service.error 171 | 172 | mov r8, qword [kernel_page_total_count] 173 | mov r9, qword [kernel_page_free_count] 174 | mov r10, qword [kernel_page_paged_count] 175 | 176 | jmp kernel_service.end 177 | 178 | kernel_service_memory_alloc: 179 | push rbx 180 | push rdx 181 | push rsi 182 | push rdi 183 | push rax 184 | push rcx 185 | 186 | mov rax, STATIC_MAX_unsigned 187 | 188 | call kernel_task_active 189 | 190 | mov rcx, qword [rdi + KERNEL_TASK_STRUCTURE.map_size] 191 | mov rsi, qword [rdi + KERNEL_TASK_STRUCTURE.map] 192 | 193 | .reload: 194 | xor edx, edx 195 | 196 | .search: 197 | inc rax 198 | 199 | cmp rax, rcx 200 | je .error 201 | 202 | bt qword [rsi], rax 203 | jnz .search 204 | 205 | mov rbx, rax 206 | 207 | .check: 208 | inc rax 209 | 210 | inc rdx 211 | 212 | cmp rdx, qword [rsp] 213 | je .found 214 | 215 | cmp rax, rcx 216 | je .error 217 | 218 | bt qword [rsi], rax 219 | jc .check 220 | 221 | jmp .reload 222 | 223 | .error: 224 | mov qword [rsp + STATIC_QWORD_SIZE_byte], KERNEL_ERROR_memory_low 225 | stc 226 | jmp .end 227 | 228 | .found: 229 | mov rax, rbx 230 | 231 | .lock: 232 | btr qword [rsi], rax 233 | 234 | inc rax 235 | 236 | dec rdx 237 | jnz .lock 238 | 239 | shl rbx, STATIC_MULTIPLE_BY_PAGE_shift 240 | 241 | add rbx, qword [kernel_memory_real_address] 242 | 243 | mov qword [rsp + STATIC_QWORD_SIZE_byte * 0x02], rbx 244 | 245 | .end: 246 | pop rcx 247 | pop rax 248 | pop rdi 249 | pop rsi 250 | pop rdx 251 | pop rbx 252 | 253 | ret 254 | 255 | macro_debug "kernel_service_memory_alloc" 256 | 257 | kernel_service_memory_release: 258 | push rax 259 | push rdx 260 | push rsi 261 | push rdi 262 | push rcx 263 | 264 | call kernel_task_active 265 | 266 | mov rax, rdi 267 | sub rax, qword [kernel_memory_real_address] 268 | shr rax, KERNEL_PAGE_SIZE_shift 269 | 270 | mov rcx, 64 271 | xor rdx, rdx 272 | div rcx 273 | 274 | shl rax, STATIC_MULTIPLE_BY_8_shift 275 | add rsi, rax 276 | 277 | mov rcx, qword [rsp] 278 | 279 | .loop: 280 | bts qword [rsi], rdx 281 | 282 | inc rdx 283 | 284 | dec rcx 285 | jnz .loop 286 | 287 | pop rcx 288 | pop rdi 289 | pop rsi 290 | pop rdx 291 | pop rax 292 | 293 | ret 294 | 295 | macro_debug "kernel_service_memory_release" 296 | -------------------------------------------------------------------------------- /kernel/service/visual/fill.asm: -------------------------------------------------------------------------------- 1 | service_render_fill_insert_by_register: 2 | push rcx 3 | push rdi 4 | 5 | mov ecx, SERVICE_RENDER_FILL_LIST_limit 6 | 7 | mov rdi, qword [service_render_fill_list_address] 8 | 9 | .loop: 10 | cmp qword [rdi + SERVICE_RENDER_STRUCTURE_FILL.object], STATIC_EMPTY 11 | jne .next 12 | 13 | mov qword [rdi + SERVICE_RENDER_STRUCTURE_FILL.field + SERVICE_RENDER_STRUCTURE_FIELD.x], r8 14 | mov qword [rdi + SERVICE_RENDER_STRUCTURE_FILL.field + SERVICE_RENDER_STRUCTURE_FIELD.y], r9 15 | mov qword [rdi + SERVICE_RENDER_STRUCTURE_FILL.field + SERVICE_RENDER_STRUCTURE_FIELD.width], r10 16 | mov qword [rdi + SERVICE_RENDER_STRUCTURE_FILL.field + SERVICE_RENDER_STRUCTURE_FIELD.height], r11 17 | 18 | mov qword [rdi + SERVICE_RENDER_STRUCTURE_FILL.object], rsi 19 | 20 | jmp .end 21 | 22 | .next: 23 | add rdi, SERVICE_RENDER_STRUCTURE_FILL.SIZE 24 | 25 | dec rcx 26 | jnz .loop 27 | 28 | xchg bx, bx 29 | jmp $ 30 | 31 | .end: 32 | pop rdi 33 | pop rcx 34 | 35 | ret 36 | 37 | macro_debug "service_render_fill_insert_by_register" 38 | 39 | service_render_fill_insert_by_object: 40 | push rax 41 | push rcx 42 | push rdi 43 | push rsi 44 | 45 | mov ecx, SERVICE_RENDER_FILL_LIST_limit 46 | 47 | mov rdi, qword [service_render_fill_list_address] 48 | 49 | .loop: 50 | cmp qword [rdi + SERVICE_RENDER_STRUCTURE_FILL.object], STATIC_EMPTY 51 | jne .next 52 | 53 | movsq 54 | movsq 55 | movsq 56 | movsq 57 | 58 | mov rax, qword [rsp] 59 | mov qword [rdi], rax 60 | 61 | jmp .end 62 | 63 | .next: 64 | add rdi, SERVICE_RENDER_STRUCTURE_FILL.SIZE 65 | 66 | dec rcx 67 | jnz .loop 68 | 69 | xchg bx, bx 70 | jmp $ 71 | 72 | .end: 73 | pop rsi 74 | pop rdi 75 | pop rcx 76 | pop rax 77 | 78 | ret 79 | 80 | macro_debug "service_render_fill_insert_by_object" 81 | 82 | service_render_fill: 83 | push rax 84 | push rcx 85 | push rdx 86 | push rsi 87 | push rdi 88 | push r8 89 | push r9 90 | push r10 91 | push r11 92 | push r12 93 | push r13 94 | push r14 95 | push r15 96 | 97 | mov ecx, SERVICE_RENDER_FILL_LIST_limit 98 | 99 | mov rsi, qword [service_render_fill_list_address] 100 | 101 | .loop: 102 | cmp qword [rsi + SERVICE_RENDER_STRUCTURE_FILL.object], STATIC_EMPTY 103 | je .next 104 | 105 | push rcx 106 | push rsi 107 | 108 | mov r8, qword [rsi + SERVICE_RENDER_STRUCTURE_FILL.field + SERVICE_RENDER_STRUCTURE_FIELD.x] 109 | mov r9, qword [rsi + SERVICE_RENDER_STRUCTURE_FILL.field + SERVICE_RENDER_STRUCTURE_FIELD.y] 110 | mov r10, qword [rsi + SERVICE_RENDER_STRUCTURE_FILL.field + SERVICE_RENDER_STRUCTURE_FIELD.width] 111 | mov r11, qword [rsi + SERVICE_RENDER_STRUCTURE_FILL.field + SERVICE_RENDER_STRUCTURE_FIELD.height] 112 | 113 | bt r8, STATIC_QWORD_BIT_sign 114 | jnc .x_positive 115 | 116 | not r8 117 | inc r8 118 | sub r10, r8 119 | 120 | xor r8, r8 121 | 122 | .x_positive: 123 | bt r9, STATIC_QWORD_BIT_sign 124 | jnc .y_positive 125 | 126 | not r9 127 | inc r9 128 | sub r11, r9 129 | 130 | xor r9, r9 131 | 132 | .y_positive: 133 | mov rax, r8 134 | add rax, r10 135 | cmp rax, qword [kernel_video_width_pixel] 136 | jb .x_inside 137 | 138 | sub rax, qword [kernel_video_width_pixel] 139 | sub r10, rax 140 | 141 | .x_inside: 142 | mov rax, r9 143 | add rax, r11 144 | cmp rax, qword [kernel_video_height_pixel] 145 | jb .y_inside 146 | 147 | sub rax, qword [kernel_video_height_pixel] 148 | sub r11, rax 149 | 150 | .y_inside: 151 | mov rsi, qword [rsi + SERVICE_RENDER_STRUCTURE_FILL.object] 152 | 153 | mov r12, r10 154 | shl r12, KERNEL_VIDEO_DEPTH_shift 155 | mov r13, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.width] 156 | shl r13, KERNEL_VIDEO_DEPTH_shift 157 | mov r14, qword [service_render_object_framebuffer + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.width] 158 | shl r14, KERNEL_VIDEO_DEPTH_shift 159 | 160 | mov rdi, r8 161 | shl rdi, KERNEL_VIDEO_DEPTH_shift 162 | 163 | mov rax, r14 164 | mul r9 165 | 166 | add rdi, rax 167 | add rdi, qword [service_render_object_framebuffer + SERVICE_RENDER_STRUCTURE_OBJECT.address] 168 | 169 | sub r8, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.x] 170 | js .overflow 171 | sub r9, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.y] 172 | js .overflow 173 | 174 | mov rax, r9 175 | mul r13 176 | 177 | shl r8, KERNEL_VIDEO_DEPTH_shift 178 | 179 | mov rsi, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.address] 180 | add rsi, rax 181 | add rsi, r8 182 | 183 | .row: 184 | mov rcx, r10 185 | 186 | .print: 187 | cmp byte [rsi + 0x03], STATIC_MAX_unsigned 188 | je .transparent_max 189 | 190 | movsd 191 | 192 | jmp .continue 193 | 194 | .overflow: 195 | mov rsi, qword [rsp] 196 | call service_render_zone_insert_by_object 197 | call service_render_zone 198 | 199 | jmp .leave 200 | 201 | .transparent_max: 202 | add rsi, STATIC_DWORD_SIZE_byte 203 | add rdi, STATIC_DWORD_SIZE_byte 204 | 205 | .continue: 206 | dec rcx 207 | jnz .print 208 | 209 | sub rdi, r12 210 | add rdi, r14 211 | 212 | sub rsi, r12 213 | add rsi, r13 214 | 215 | dec r11 216 | jnz .row 217 | 218 | or qword [service_render_object_framebuffer + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags], SERVICE_RENDER_OBJECT_FLAG_flush 219 | 220 | .leave: 221 | pop rsi 222 | pop rcx 223 | 224 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_FILL.object], STATIC_EMPTY 225 | 226 | .next: 227 | add rsi, SERVICE_RENDER_STRUCTURE_FILL.SIZE 228 | 229 | dec rcx 230 | jnz .loop 231 | 232 | .end: 233 | pop r15 234 | pop r14 235 | pop r13 236 | pop r12 237 | pop r11 238 | pop r10 239 | pop r9 240 | pop r8 241 | pop rdi 242 | pop rsi 243 | pop rdx 244 | pop rcx 245 | pop rax 246 | 247 | ret 248 | 249 | macro_debug "service_render_fill" 250 | -------------------------------------------------------------------------------- /kernel/service/visual/zone.asm: -------------------------------------------------------------------------------- 1 | service_render_zone_insert_by_object: 2 | push rax 3 | push rdx 4 | push rdi 5 | push rsi 6 | 7 | macro_lock service_render_zone_semaphore, 0 8 | 9 | cmp qword [service_render_zone_list_records], SERVICE_RENDER_ZONE_LIST_limit 10 | jb .insert 11 | 12 | xchg bx, bx 13 | jmp $ 14 | 15 | .insert: 16 | mov eax, SERVICE_RENDER_STRUCTURE_ZONE.SIZE 17 | mul qword [service_render_zone_list_records] 18 | 19 | mov rdi, qword [service_render_zone_list_address] 20 | add rdi, rax 21 | 22 | movsq 23 | movsq 24 | movsq 25 | movsq 26 | 27 | mov rax, qword [rsp] 28 | mov qword [rdi], rax 29 | 30 | inc qword [service_render_zone_list_records] 31 | 32 | mov byte [service_render_zone_semaphore], STATIC_FALSE 33 | 34 | pop rsi 35 | pop rdi 36 | pop rdx 37 | pop rax 38 | 39 | ret 40 | 41 | macro_debug "service_render_zone_insert_by_object" 42 | 43 | service_render_zone_insert_by_register: 44 | push rax 45 | push rdx 46 | push rsi 47 | push rdi 48 | 49 | macro_lock service_render_zone_semaphore, 0 50 | 51 | cmp qword [service_render_zone_list_records], SERVICE_RENDER_ZONE_LIST_limit 52 | jb .insert 53 | 54 | xchg bx, bx 55 | jmp $ 56 | 57 | .insert: 58 | mov eax, SERVICE_RENDER_STRUCTURE_ZONE.SIZE 59 | mul qword [service_render_zone_list_records] 60 | 61 | mov rsi, qword [service_render_zone_list_address] 62 | add rsi, rax 63 | 64 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_ZONE.field + SERVICE_RENDER_STRUCTURE_FIELD.x], r8 65 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_ZONE.field + SERVICE_RENDER_STRUCTURE_FIELD.y], r9 66 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_ZONE.field + SERVICE_RENDER_STRUCTURE_FIELD.width], r10 67 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_ZONE.field + SERVICE_RENDER_STRUCTURE_FIELD.height], r11 68 | 69 | mov qword [rsi + SERVICE_RENDER_STRUCTURE_ZONE.object], rdi 70 | 71 | inc qword [service_render_zone_list_records] 72 | 73 | mov byte [service_render_zone_semaphore], STATIC_FALSE 74 | 75 | pop rdi 76 | pop rsi 77 | pop rdx 78 | pop rax 79 | 80 | ret 81 | 82 | macro_debug "service_render_zone_insert_by_register" 83 | 84 | service_render_zone: 85 | push rax 86 | push rdx 87 | push rsi 88 | push rdi 89 | push r8 90 | push r9 91 | push r10 92 | push r11 93 | push r12 94 | push r13 95 | push r14 96 | push r15 97 | 98 | cmp qword [service_render_zone_list_records], STATIC_EMPTY 99 | je .end 100 | 101 | mov rdi, qword [service_render_zone_list_address] 102 | 103 | jmp .entry 104 | 105 | .loop: 106 | mov qword [rdi + SERVICE_RENDER_STRUCTURE_ZONE.object], STATIC_EMPTY 107 | 108 | add rdi, SERVICE_RENDER_STRUCTURE_ZONE.SIZE 109 | 110 | .entry: 111 | cmp qword [rdi + SERVICE_RENDER_STRUCTURE_ZONE.object], STATIC_EMPTY 112 | je .end 113 | 114 | mov r8, qword [rdi + SERVICE_RENDER_STRUCTURE_ZONE.field + SERVICE_RENDER_STRUCTURE_FIELD.x] 115 | 116 | mov r9, qword [rdi + SERVICE_RENDER_STRUCTURE_ZONE.field + SERVICE_RENDER_STRUCTURE_FIELD.y] 117 | 118 | mov r10, qword [rdi + SERVICE_RENDER_STRUCTURE_ZONE.field + SERVICE_RENDER_STRUCTURE_FIELD.width] 119 | add r10, r8 120 | 121 | mov r11, qword [rdi + SERVICE_RENDER_STRUCTURE_ZONE.field + SERVICE_RENDER_STRUCTURE_FIELD.height] 122 | add r11, r9 123 | 124 | cmp r8, qword [kernel_video_width_pixel] 125 | jge .loop 126 | 127 | cmp r9, qword [kernel_video_height_pixel] 128 | jge .loop 129 | 130 | cmp r10, STATIC_EMPTY 131 | jle .loop 132 | 133 | cmp r11, STATIC_EMPTY 134 | jle .loop 135 | 136 | mov eax, SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.SIZE 137 | mul qword [service_render_object_list_records] 138 | 139 | mov rsi, qword [service_render_object_list_address] 140 | add rsi, rax 141 | 142 | .object: 143 | sub rsi, SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.SIZE 144 | 145 | cmp rsi, qword [service_render_object_list_address] 146 | je .fill 147 | 148 | test qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags], SERVICE_RENDER_OBJECT_FLAG_visible 149 | jz .object 150 | 151 | cmp rsi, qword [rdi + SERVICE_RENDER_STRUCTURE_ZONE.object] 152 | je .fill 153 | 154 | mov r12, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.x] 155 | 156 | mov r13, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.y] 157 | 158 | mov r14, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.width] 159 | add r14, r12 160 | 161 | mov r15, qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.field + SERVICE_RENDER_STRUCTURE_FIELD.height] 162 | add r15, r13 163 | 164 | cmp r12, r10 165 | jge .object 166 | cmp r13, r11 167 | jge .object 168 | cmp r14, r8 169 | jle .object 170 | cmp r15, r9 171 | jle .object 172 | 173 | .left: 174 | cmp r8, r12 175 | jge .up 176 | 177 | push r10 178 | 179 | mov r10, r12 180 | sub r10, r8 181 | 182 | sub r11, r9 183 | 184 | call service_render_zone_insert_by_register 185 | 186 | pop r10 187 | 188 | add r11, r9 189 | 190 | mov r8, r12 191 | 192 | .up: 193 | cmp r9, r13 194 | jge .right 195 | 196 | sub r10, r8 197 | 198 | push r11 199 | 200 | mov r11, r13 201 | sub r11, r9 202 | 203 | call service_render_zone_insert_by_register 204 | 205 | pop r11 206 | 207 | add r10, r8 208 | 209 | mov r9, r13 210 | 211 | .right: 212 | cmp r10, r14 213 | jle .down 214 | 215 | push r10 216 | sub r10, r14 217 | 218 | sub r11, r9 219 | 220 | push r8 221 | 222 | mov r8, r14 223 | 224 | call service_render_zone_insert_by_register 225 | 226 | pop r8 227 | 228 | sub qword [rsp], r10 229 | pop r10 230 | 231 | add r11, r9 232 | 233 | .down: 234 | cmp r11, r15 235 | jle .fill 236 | 237 | sub r11, r15 238 | 239 | push r9 240 | 241 | mov r9, r15 242 | 243 | call service_render_zone_insert_by_register 244 | 245 | pop r9 246 | 247 | sub qword [rsp], r11 248 | mov r11, r15 249 | 250 | .fill: 251 | sub r10, r8 252 | sub r11, r9 253 | cmp r10, STATIC_EMPTY 254 | jle .loop 255 | 256 | call service_render_fill_insert_by_register 257 | 258 | jmp .loop 259 | 260 | .end: 261 | mov qword [service_render_zone_list_records], STATIC_EMPTY 262 | 263 | pop r15 264 | pop r14 265 | pop r13 266 | pop r12 267 | pop r11 268 | pop r10 269 | pop r9 270 | pop r8 271 | pop rdi 272 | pop rsi 273 | pop rdx 274 | pop rax 275 | 276 | ret 277 | 278 | macro_debug "service_render_zone" 279 | -------------------------------------------------------------------------------- /kernel/init/acpi.asm: -------------------------------------------------------------------------------- 1 | ACPI_MADT_ENTRY_lapic equ 0x00 2 | ACPI_MADT_ENTRY_ioapic equ 0x01 3 | ACPI_MADT_ENTRY_iso equ 0x02 4 | ACPI_MADT_ENTRY_x2apic equ 0x09 5 | 6 | ACPI_MADT_APIC_FLAG_ENABLED_bit equ 0 7 | 8 | struc ACPI_STRUCTURE_RSDP 9 | .signature resb 8 10 | .checksum resb 1 11 | .oem_id resb 6 12 | .revision resb 1 13 | .rsdt_address resb 4 14 | 15 | .SIZE: 16 | endstruc 17 | 18 | struc ACPI_STRUCTURE_XSDP 19 | .rsdp resb ACPI_STRUCTURE_RSDP.SIZE 20 | .length resb 4 21 | .xsdt_address resb 8 22 | .checksum resb 1 23 | .reserved resb 3 24 | 25 | .SIZE: 26 | endstruc 27 | 28 | struc ACPI_STRUCTURE_RSDT_or_XSDT 29 | .signature resb 4 30 | .length resb 4 31 | .revision resb 1 32 | .checksum resb 1 33 | .oem_id resb 6 34 | .oem_table_id resb 8 35 | .oem_revision resb 4 36 | .creator_id resb 4 37 | .creator_revision resb 4 38 | 39 | .SIZE: 40 | endstruc 41 | 42 | struc ACPI_STRUCTURE_MADT 43 | .signature resb 4 44 | .length resb 4 45 | .revision resb 1 46 | .checksum resb 1 47 | .oem_id resb 6 48 | .oem_table_id resb 8 49 | .oem_revision resb 4 50 | .creator_id resb 4 51 | .creator_revision resb 4 52 | .apic_address resb 4 53 | .flags resb 4 54 | 55 | .SIZE: 56 | endstruc 57 | 58 | struc ACPI_STRUCTURE_MADT_entry 59 | .type resb 1 60 | .length resb 1 61 | endstruc 62 | 63 | struc ACPI_STRUCTURE_MADT_APIC 64 | .type resb 1 65 | .length resb 1 66 | .cpu_id resb 1 67 | .apic_id resb 1 68 | .flags resb 4 69 | 70 | .SIZE: 71 | endstruc 72 | 73 | struc ACPI_STRUCTURE_MADT_IOAPIC 74 | .type resb 1 75 | .length resb 1 76 | .ioapic_id resb 1 77 | .reserved resb 1 78 | .base_address resb 4 79 | .gsib resb 4 80 | 81 | .SIZE: 82 | endstruc 83 | 84 | struc ACPI_STRUCTURE_MADT_ISO 85 | .type resb 1 86 | .length resb 1 87 | .bus_source resb 1 88 | .irq_source resb 1 89 | .gsi resb 4 90 | .flags resb 2 91 | 92 | .SIZE: 93 | endstruc 94 | 95 | struc ACPI_STRUCTURE_MADT_NMI 96 | .type resb 1 97 | .length resb 1 98 | .acpi_id resb 1 99 | .flags resb 2 100 | .lint resb 1 101 | 102 | .SIZE: 103 | endstruc 104 | 105 | kernel_init_acpi: 106 | mov rbx, "RSD PTR " 107 | 108 | movzx esi, word [0x040E] 109 | 110 | shl esi, STATIC_MULTIPLE_BY_16_shift 111 | 112 | mov r8b, STATIC_TRUE 113 | 114 | .rsdp_search: 115 | lodsq 116 | 117 | cmp rax, rbx 118 | je .rsdp_found 119 | 120 | cmp esi, 0x000FFFFF 121 | jb .rsdp_search 122 | 123 | mov rsi, kernel_init_string_error_acpi_header 124 | 125 | .error: 126 | jmp kernel_panic 127 | 128 | .rsdp_found: 129 | push rsi 130 | 131 | xor al, al 132 | mov ecx, ACPI_STRUCTURE_RSDP.SIZE 133 | 134 | sub rsi, ACPI_STRUCTURE_RSDP.checksum 135 | 136 | .checksum: 137 | add al, byte [rsi] 138 | 139 | inc rsi 140 | 141 | loop .checksum 142 | 143 | pop rsi 144 | 145 | test al, al 146 | jnz .rsdp_search 147 | 148 | .rsdp_or_xsdp: 149 | sub rsi, ACPI_STRUCTURE_RSDP.checksum 150 | 151 | cmp byte [rsi + ACPI_STRUCTURE_RSDP.revision], 0x00 152 | jne .extended 153 | 154 | mov edi, dword [rsi + ACPI_STRUCTURE_RSDP.rsdt_address] 155 | 156 | jmp .standard 157 | 158 | .extended: 159 | mov rdi, qword [rsi + ACPI_STRUCTURE_XSDP.xsdt_address] 160 | 161 | mov r8b, STATIC_FALSE 162 | 163 | .standard: 164 | mov rsi, kernel_init_string_error_acpi 165 | 166 | cmp dword [rdi + ACPI_STRUCTURE_RSDT_or_XSDT.signature], "RSDT" 167 | je .found 168 | 169 | cmp dword [rdi + ACPI_STRUCTURE_RSDT_or_XSDT.signature], "XSDT" 170 | jne .error 171 | 172 | .found: 173 | mov ecx, dword [rdi + ACPI_STRUCTURE_RSDT_or_XSDT.length] 174 | sub ecx, ACPI_STRUCTURE_RSDT_or_XSDT.SIZE 175 | 176 | add rdi, ACPI_STRUCTURE_RSDT_or_XSDT.SIZE 177 | 178 | cmp r8b, STATIC_TRUE 179 | je .rsdt_pointers 180 | 181 | .xsdt_pointers: 182 | shr ecx, STATIC_DIVIDE_BY_QWORD_shift 183 | 184 | .xsdt_pointers_loop: 185 | mov rsi, qword [rdi] 186 | 187 | call .header 188 | 189 | add rdi, STATIC_QWORD_SIZE_byte 190 | 191 | dec ecx 192 | jnz .xsdt_pointers_loop 193 | 194 | jmp .summary 195 | 196 | .rsdt_pointers: 197 | shr ecx, STATIC_DIVIDE_BY_DWORD_shift 198 | 199 | .rsdt_pointers_loop: 200 | mov esi, dword [rdi] 201 | 202 | call .header 203 | 204 | add rdi, STATIC_DWORD_SIZE_byte 205 | 206 | dec ecx 207 | jnz .rsdt_pointers_loop 208 | 209 | .summary: 210 | mov rsi, kernel_init_string_error_apic 211 | 212 | cmp byte [kernel_apic_count], STATIC_EMPTY 213 | je .error 214 | 215 | mov rsi, kernel_init_string_error_ioapic 216 | 217 | cmp byte [kernel_init_ioapic_semaphore], STATIC_FALSE 218 | je .error 219 | 220 | jmp .end 221 | 222 | .header: 223 | cmp dword [rsi + ACPI_STRUCTURE_MADT.signature], "APIC" 224 | je .madt 225 | 226 | ret 227 | 228 | .madt: 229 | push rcx 230 | push rsi 231 | push rdi 232 | 233 | mov eax, dword [rsi + ACPI_STRUCTURE_MADT.apic_address] 234 | mov dword [kernel_apic_base_address], eax 235 | 236 | mov ecx, dword [rsi + ACPI_STRUCTURE_MADT.length] 237 | mov dword [kernel_apic_size], ecx 238 | 239 | sub ecx, ACPI_STRUCTURE_MADT.SIZE 240 | add rsi, ACPI_STRUCTURE_MADT.SIZE 241 | 242 | mov rdi, kernel_apic_id_table 243 | 244 | .madt_loop: 245 | cmp byte [rsi + ACPI_STRUCTURE_MADT_entry.type], ACPI_MADT_ENTRY_lapic 246 | je .madt_apic 247 | 248 | cmp byte [rsi + ACPI_STRUCTURE_MADT_entry.type], ACPI_MADT_ENTRY_ioapic 249 | je .madt_ioapic 250 | 251 | .madt_next_entry: 252 | movzx eax, byte [rsi + ACPI_STRUCTURE_MADT_entry.length] 253 | add rsi, rax 254 | 255 | sub rcx, rax 256 | jnz .madt_loop 257 | 258 | pop rdi 259 | pop rsi 260 | pop rcx 261 | 262 | ret 263 | 264 | .madt_apic: 265 | bt word [rsi + ACPI_STRUCTURE_MADT_APIC.flags], ACPI_MADT_APIC_FLAG_ENABLED_bit 266 | jnc .madt_next_entry 267 | 268 | inc word [kernel_apic_count] 269 | 270 | mov al, byte [rsi + ACPI_STRUCTURE_MADT_APIC.cpu_id] 271 | stosb 272 | 273 | cmp al, byte [kernel_init_apic_id_highest] 274 | jbe .madt_next_entry 275 | 276 | mov byte [kernel_init_apic_id_highest], al 277 | 278 | jmp .madt_next_entry 279 | 280 | .madt_ioapic: 281 | cmp byte [kernel_init_ioapic_semaphore], STATIC_TRUE 282 | je .madt_next_entry 283 | 284 | mov eax, dword [rsi + ACPI_STRUCTURE_MADT_IOAPIC.gsib] 285 | 286 | test al, al 287 | jnz .madt_next_entry 288 | 289 | mov eax, dword [rsi + ACPI_STRUCTURE_MADT_IOAPIC.base_address] 290 | mov dword [kernel_io_apic_base_address], eax 291 | 292 | mov byte [kernel_init_ioapic_semaphore], STATIC_TRUE 293 | 294 | jmp .madt_next_entry 295 | 296 | .end: 297 | -------------------------------------------------------------------------------- /kernel/service/date/taskbar.asm: -------------------------------------------------------------------------------- 1 | service_date_taskbar: 2 | ; Save register 3 | push rax 4 | push rbx 5 | push rdx 6 | push rdx 7 | push rsi 8 | push rdi 9 | ; Load the last modification time of the service render object list 10 | mov rax, qword [service_render_object_list_modify_time] 11 | ; Compare it with the stored modification time of the taskbar window 12 | cmp qword [service_date_window_taskbar_modify_time], rax 13 | je .end; If they are equal, no update is needed, so exit 14 | 15 | mov qword [service_date_window_taskbar_modify_time], rax 16 | 17 | ; Acquire a lock on the service render object semaphore to ensure thread safety 18 | macro_lock service_render_object_semaphore, 0 19 | 20 | ; Compute memory required for taskbar elements 21 | mov eax, INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.SIZE + INCLUDE_UNIT_WINDOW_NAME_length 22 | mul qword [service_render_object_list_records]; Multiply by the number of records 23 | push rax; Save the computed size on the stack 24 | 25 | ; Check if allocated space is sufficient 26 | cmp rax, qword [service_date_window_taskbar.element_chain_0 + INCLUDE_UNIT_STRUCTURE_ELEMENT_CHAIN.size] 27 | jbe .enough; If space is sufficient, skip allocation 28 | 29 | ; Allocate or Reallocate Memory for Taskbar Elements 30 | mov rcx, qword [service_date_window_taskbar.element_chain_0 + INCLUDE_UNIT_STRUCTURE_ELEMENT_CHAIN.size] 31 | test rcx, rcx 32 | jz .new; If zero, new allocation is needed 33 | 34 | ; If memory is already allocated, release it before reallocation 35 | call include_page_from_size 36 | mov rdi, qword [service_date_window_taskbar.element_chain_0 + INCLUDE_UNIT_STRUCTURE_ELEMENT_CHAIN.address] 37 | call kernel_memory_release 38 | 39 | .new: 40 | ; Allocate new memory for the taskbar elements 41 | mov rcx, rax; Set required size 42 | call include_page_from_size 43 | call kernel_memory_alloc 44 | 45 | ; Store the new memory address in the taskbar element chain 46 | mov qword [service_date_window_taskbar.element_chain_0 + INCLUDE_UNIT_STRUCTURE_ELEMENT_CHAIN.address], rdi 47 | 48 | .enough: 49 | ; Load the address of the taskbar element chain 50 | mov rdi, qword [service_date_window_taskbar.element_chain_0 + INCLUDE_UNIT_STRUCTURE_ELEMENT_CHAIN.address] 51 | 52 | ; Compute Button Width for Taskbar Entries 53 | 54 | ; Load taskbar window width 55 | mov rax, qword [service_date_window_taskbar + INCLUDE_UNIT_STRUCTURE_WINDOW.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 56 | ; Subtract the width occupied by the clock element 57 | sub rax, qword [service_date_window_taskbar.element_label_clock + INCLUDE_UNIT_STRUCTURE_ELEMENT_LABEL.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.field + INCLUDE_UNIT_STRUCTURE_FIELD.width] 58 | ; Compute the number of visible taskbar entries (excluding fixed elements) 59 | mov rcx, qword [service_render_object_list_records] 60 | sub rcx, SERVICE_DATE_WINDOW_count; Exclude static taskbar elements 61 | xor edx, edx 62 | div rcx; Divide remaining space among dynamic elements 63 | 64 | mov rbx, rax; Store computed button width 65 | 66 | ; Begin Iteration Over Rendered Objects 67 | mov rax, qword [service_date_pid]; Load process ID 68 | xor edx, edx 69 | mov rsi, qword [service_render_object_list_address]; Load object list start address 70 | 71 | .loop: 72 | ; Skip entries with empty flags 73 | cmp qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.flags], STATIC_EMPTY 74 | je .ready; Exit loop if empty entry is reached 75 | 76 | ; Skip entries belonging to the same process (already managed) 77 | cmp qword [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.pid], rax 78 | je .next 79 | 80 | ; Add Taskbar Button for Process Entry 81 | push rsi 82 | push rdi 83 | 84 | ; Set element type to "button" 85 | mov dword [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.type], INCLUDE_UNIT_ELEMENT_TYPE_button 86 | ; Set element size 87 | mov qword [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.size], INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.SIZE 88 | ; Set button position (X-coordinate) 89 | mov qword [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.field + INCLUDE_UNIT_STRUCTURE_FIELD.x], rdx 90 | ; Set button position (Y-coordinate, default) 91 | mov qword [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.field + INCLUDE_UNIT_STRUCTURE_FIELD.y], STATIC_EMPTY 92 | ; Set button width (computed earlier) 93 | mov qword [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.field + INCLUDE_UNIT_STRUCTURE_FIELD.width], rbx 94 | ; Set button height (taskbar height) 95 | mov qword [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.field + INCLUDE_UNIT_STRUCTURE_FIELD.height], SERVICE_DATE_WINDOW_TASKBAR_HEIGHT_pixel 96 | ; Set default event handler (empty for now) 97 | mov qword [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT.event], STATIC_EMPTY 98 | 99 | ; Retrieve object name length and store in button structure 100 | movzx ecx, byte [rsi + SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.length] 101 | mov byte [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.length], cl 102 | ; Update size to include the text length 103 | add qword [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.size], rcx 104 | ; Copy object name into taskbar button text 105 | add rsi, SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.name 106 | add rdi, INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.string 107 | rep movsb; Copy name string 108 | 109 | pop rdi 110 | pop rsi 111 | 112 | ; Move to the next taskbar entry 113 | add rdi, qword [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT_BUTTON.element + INCLUDE_UNIT_STRUCTURE_ELEMENT.size] 114 | add rdx, rbx; Update X-position 115 | 116 | .next: 117 | ; Move to the next object in the render list 118 | add rsi, SERVICE_RENDER_STRUCTURE_OBJECT.SIZE + SERVICE_RENDER_STRUCTURE_OBJECT_EXTRA.SIZE 119 | jmp .loop; Continue iteration 120 | 121 | .ready: 122 | ; Restore the saved taskbar element chain size 123 | pop qword [service_date_window_taskbar.element_chain_0 + INCLUDE_UNIT_STRUCTURE_ELEMENT_CHAIN.size] 124 | ; Mark the end of the element chain 125 | mov dword [rdi + INCLUDE_UNIT_STRUCTURE_ELEMENT.type], STATIC_EMPTY 126 | 127 | ; Reset the semaphore to indicate that the taskbar update is complete 128 | mov byte [service_render_object_semaphore], STATIC_FALSE 129 | 130 | ; Refresh Taskbar UI Elements 131 | mov rsi, service_date_window_taskbar.element_chain_0 132 | mov rdi, service_date_window_taskbar 133 | call include_unit_element_chain 134 | 135 | ; Trigger UI Update via System Interrupt 136 | mov al, SERVICE_RENDER_WINDOW_update 137 | mov rsi, service_date_window_taskbar 138 | int SERVICE_RENDER_IRQ 139 | 140 | .end: 141 | ; Restore register 142 | pop rsi 143 | pop rdi 144 | pop rdx 145 | pop rcx 146 | pop rbx 147 | pop rax 148 | ret 149 | -------------------------------------------------------------------------------- /kernel/service/network/wrap.asm: -------------------------------------------------------------------------------- 1 | ; Prepare ethernet frame 2 | service_network_ethernet_wrap: 3 | push rax ; Save rax register on stack 4 | 5 | mov qword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.target], rax ; Set target MAC address 6 | 7 | mov rax, qword [driver_nic_i82540em_mac_address] ; Load source MAC address 8 | mov qword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.source], rax ; Set source MAC address 9 | 10 | ; Set Ethernet frame type (IP, ARP, etc.) 11 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.type], cx 12 | 13 | pop rax ; Restore rax register 14 | 15 | ret ; Return from function 16 | 17 | macro_debug "service_network_ethernet_wrap" 18 | 19 | ; Prepares an IP packet 20 | service_network_ip_wrap: 21 | ; Save the registers 22 | push rcx 23 | push rax 24 | 25 | ; Set IP version (IPv4) and header length 26 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.version_and_ihl], SERVICE_NETWORK_FRAME_IP_VERSION_4 | SERVICE_NETWORK_FRAME_IP_HEADER_LENGTH_default 27 | 28 | ; Set Differentiated Services Code Point (DSCP) to 0 29 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.dscp_and_ecn], STATIC_EMPTY 30 | 31 | add cx, SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE ; Calculate total length of IP packet 32 | rol cx, STATIC_REPLACE_AL_WITH_HIGH_shift ; Adjust byte order 33 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.total_length], cx ; Set total length 34 | 35 | inc word [rsi + SERVICE_NETWORK_STRUCTURE_TCP_STACK.identification] ; Increment packet ID 36 | mov ax, word [rsi + SERVICE_NETWORK_STRUCTURE_TCP_STACK.identification] ; Load new ID 37 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.identification], ax ; Set identification field 38 | 39 | ; Set "Do Not Fragment" flag 40 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.f_and_f], SERVICE_NETWORK_FRAME_IP_F_AND_F_do_not_fragment 41 | ; Set Time-To-Live (TTL) 42 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.ttl], SERVICE_NETWORK_FRAME_IP_TTL_default 43 | ; Set protocol type (TCP, UDP, etc.) 44 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.protocol], bl 45 | ; Clear checksum field for now 46 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.checksum], STATIC_EMPTY 47 | ; Set source IP 48 | mov eax, dword [driver_nic_i82540em_ipv4_address] ; Load source IP address 49 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.source_address], eax ; Set source IP 50 | 51 | mov eax, dword [rsi + SERVICE_NETWORK_STRUCTURE_TCP_STACK.source_ipv4] ; Load destination IP address 52 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.destination_address], eax ; Set destination IP 53 | 54 | xor eax, eax ; Clear eax for checksum calculation 55 | mov ecx, SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE >> STATIC_DIVIDE_BY_2_shift ; Set size of header for checksum calculation 56 | add rdi, SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE ; Adjust pointer to IP header 57 | call service_network_checksum ; Compute checksum 58 | rol ax, STATIC_REPLACE_AL_WITH_HIGH_shift ; Adjust byte order 59 | sub rdi, SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE ; Reset pointer 60 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.checksum], ax ; Store checksum 61 | 62 | pop rax ; Restore rax register 63 | mov cx, SERVICE_NETWORK_FRAME_ETHERNET_TYPE_ip ; Set Ethernet frame type to IP 64 | call service_network_ethernet_wrap ; Wrap in Ethernet frame 65 | 66 | pop rcx ; Restore rcx register 67 | 68 | ret ; Return from function 69 | 70 | macro_debug "service_network_ip_wrap" 71 | 72 | ; Prepares a TCP segment 73 | service_network_tcp_wrap: 74 | ; Save registers 75 | push rax 76 | push rbx 77 | push rcx 78 | push rdi 79 | 80 | mov ax, word [rsi + SERVICE_NETWORK_STRUCTURE_TCP_STACK.host_port] ; Load source port 81 | ; Set source port 82 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_TCP.port_source], ax 83 | mov ax, word [rsi + SERVICE_NETWORK_STRUCTURE_TCP_STACK.source_port] 84 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_TCP.port_target], ax 85 | 86 | mov eax, dword [rsi + SERVICE_NETWORK_STRUCTURE_TCP_STACK.host_sequence] ; Load sequence number 87 | bswap eax ; Convert to network byte order 88 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_TCP.sequence], eax 89 | 90 | mov eax, dword [rsi + SERVICE_NETWORK_STRUCTURE_TCP_STACK.source_sequence] ; Load acknowledgment number 91 | bswap eax ; Convert to network byte order 92 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_TCP.acknowledgement], eax 93 | 94 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_TCP.header_length], bl 95 | 96 | mov al, byte [rsi + SERVICE_NETWORK_STRUCTURE_TCP_STACK.flags] ; Load TCP flags 97 | mov byte [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_TCP.flags], al 98 | 99 | mov ax, word [rsi + SERVICE_NETWORK_STRUCTURE_TCP_STACK.window_size] ; Load window size 100 | rol ax, STATIC_REPLACE_AL_WITH_HIGH_shift ; Adjust byte order 101 | ; Set window size 102 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_TCP.window_size], ax 103 | 104 | ; Clear checksum field 105 | mov dword [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_TCP.checksum_and_urgent_pointer], STATIC_EMPTY 106 | 107 | call service_network_tcp_pseudo_header ; Compute pseudo-header for checksum 108 | 109 | shr ecx, STATIC_DIVIDE_BY_2_shift ; Adjust size for checksum calculation 110 | ; Move pointer to TCP header 111 | add rdi, SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE 112 | call service_network_checksum ; Compute TCP checksum 113 | rol ax, STATIC_REPLACE_AL_WITH_HIGH_shift ; Adjust byte order 114 | mov word [rdi + SERVICE_NETWORK_STRUCTURE_FRAME_TCP.checksum], ax ; Store checksum 115 | 116 | mov rax, qword [rsi + SERVICE_NETWORK_STRUCTURE_TCP_STACK.source_mac] ; Load source MAC address 117 | mov bl, SERVICE_NETWORK_FRAME_IP_PROTOCOL_TCP ; Set protocol to TCP 118 | shl ecx, STATIC_MULTIPLE_BY_2_shift ; Adjust total segment size 119 | ; Reset pointer 120 | sub rdi, SERVICE_NETWORK_STRUCTURE_FRAME_ETHERNET.SIZE + SERVICE_NETWORK_STRUCTURE_FRAME_IP.SIZE 121 | call service_network_ip_wrap ; Wrap in IP packet 122 | 123 | ; Restore register 124 | pop rdi 125 | pop rcx 126 | pop rbx 127 | pop rax 128 | 129 | ret ; Return from function 130 | 131 | macro_debug "service_network_tcp_wrap" 132 | -------------------------------------------------------------------------------- /kernel/driver/storage/ide.asm: -------------------------------------------------------------------------------- 1 | DRIVER_IDE_CHANNEL_PRIMARY equ 0x01F0 2 | DRIVER_IDE_CHANNEL_SECONDARY equ 0x0170 3 | 4 | DRIVER_IDE_REGISTER_data equ 0x0000 5 | DRIVER_IDE_REGISTER_error equ 0x0001 6 | DRIVER_IDE_REGISTER_sector_count_0 equ 0x0002 7 | DRIVER_IDE_REGISTER_lba0 equ 0x0003 8 | DRIVER_IDE_REGISTER_lba1 equ 0x0004 9 | DRIVER_IDE_REGISTER_lba2 equ 0x0005 10 | DRIVER_IDE_REGISTER_drive_OR_head equ 0x0006 11 | DRIVER_IDE_REGISTER_command_OR_status equ 0x0007 12 | DRIVER_IDE_REGISTER_sector_count_1 equ 0x0008 13 | DRIVER_IDE_REGISTER_lba3 equ 0x0009 14 | DRIVER_IDE_REGISTER_lba4 equ 0x000A 15 | DRIVER_IDE_REGISTER_lba5 equ 0x000B 16 | DRIVER_IDE_REGISTER_control_OR_altstatus equ 0x000C 17 | DRIVER_IDE_REGISTER_device_address equ 0x000D 18 | DRIVER_IDE_REGISTER_channel_control_OR_altstatus equ 0x0206 19 | 20 | DRIVER_IDE_DRIVE_master equ 10100000b 21 | DRIVER_IDE_DRIVE_slave equ 10110000b 22 | 23 | DRIVER_IDE_CONTROL_nIEN equ 00000010b 24 | DRIVER_IDE_CONTROL_SRST equ 00000100b 25 | 26 | DRIVER_IDE_COMMAND_ATAPI_eject equ 0x1B 27 | DRIVER_IDE_COMMAND_read_pio equ 0x20 28 | DRIVER_IDE_COMMAND_read_pio_extended equ 0x24 29 | DRIVER_IDE_COMMAND_read_dma_extended equ 0x25 30 | DRIVER_IDE_COMMAND_write_pio equ 0x30 31 | DRIVER_IDE_COMMAND_write_pio_extended equ 0x34 32 | DRIVER_IDE_COMMAND_write_dma_extended equ 0x35 33 | DRIVER_IDE_COMMAND_packet equ 0xA0 34 | DRIVER_IDE_COMMAND_identify_packet equ 0xA1 35 | DRIVER_IDE_COMMAND_ATAPI_read equ 0xA8 36 | DRIVER_IDE_COMMAND_read_dma equ 0xC8 37 | DRIVER_IDE_COMMAND_write_dma equ 0xCA 38 | DRIVER_IDE_COMMAND_cache_flush equ 0xE7 39 | DRIVER_IDE_COMMAND_cache_flush_extended equ 0xEA 40 | DRIVER_IDE_COMMAND_identify equ 0xEC 41 | 42 | DRIVER_IDE_IDENTIFY_device_type equ 0x00 43 | DRIVER_IDE_IDENTIFY_cylinders equ 0x02 44 | DRIVER_IDE_IDENTIFY_heads equ 0x06 45 | DRIVER_IDE_IDENTIFY_sectors equ 0x0C 46 | DRIVER_IDE_IDENTIFY_serial equ 0x14 47 | DRIVER_IDE_IDENTIFY_model equ 0x36 48 | DRIVER_IDE_IDENTIFY_capabilities equ 0x62 49 | DRIVER_IDE_IDENTIFY_field_valid equ 0x6A 50 | DRIVER_IDE_IDENTIFY_max_lba equ 0x78 51 | DRIVER_IDE_IDENTIFY_command_sets equ 0xA4 52 | DRIVER_IDE_IDENTIFY_max_lba_extended equ 0xC8 53 | 54 | DRIVER_IDE_IDENTIFY_COMMAND_SETS_lba_extended equ 1 << 26 55 | 56 | DRIVER_IDE_STATUS_error equ 00000001b 57 | DRIVER_IDE_STATUS_index equ 00000010b 58 | DRIVER_IDE_STATUS_corrected_data equ 00000100b 59 | DRIVER_IDE_STATUS_data_ready equ 00001000b 60 | DRIVER_IDE_STATUS_seek_complete equ 00010000b 61 | DRIVER_IDE_STATUS_write_fault equ 00100000b 62 | DRIVER_IDE_STATUS_ready equ 01000000b 63 | DRIVER_IDE_STATUS_busy equ 10000000b 64 | 65 | DRIVER_IDE_ERROR_no_address_mark equ 00000001b 66 | DRIVER_IDE_ERROR_track_0_not_found equ 00000010b 67 | DRIVER_IDE_ERROR_command_aborted equ 00000100b 68 | DRIVER_IDE_ERROR_media_change_request equ 00001000b 69 | DRIVER_IDE_ERROR_id_mark_not_found equ 00010000b 70 | DRIVER_IDE_ERROR_media_changed equ 00100000b 71 | DRIVER_IDE_ERROR_uncorrectble_data equ 01000000b 72 | DRIVER_IDE_ERROR_bad_block equ 10000000b 73 | 74 | struc DRIVER_IDE_STRUCTURE_DEVICE 75 | .channel resb 2 76 | .drive resb 1 77 | .size_sectors resb 8 78 | 79 | .SIZE: 80 | endstruc 81 | 82 | driver_ide_devices_count db STATIC_EMPTY 83 | 84 | align STATIC_QWORD_SIZE_byte, db STATIC_NOTHING 85 | 86 | driver_ide_devices: 87 | times DRIVER_IDE_STRUCTURE_DEVICE.SIZE * 0x04 db STATIC_EMPTY 88 | 89 | driver_ide_init_drive: 90 | push rcx 91 | push rax 92 | push rdi 93 | push rdx 94 | 95 | add dx, DRIVER_IDE_REGISTER_drive_OR_head 96 | out dx, al 97 | 98 | call driver_ide_wait 99 | 100 | mov al, DRIVER_IDE_COMMAND_identify 101 | mov dx, word [rsp] 102 | add dx, DRIVER_IDE_REGISTER_command_OR_status 103 | out dx, al 104 | 105 | call driver_ide_wait 106 | 107 | in al, dx 108 | 109 | test al, al 110 | jz .end 111 | 112 | cmp al, STATIC_MAX_unsigned 113 | je .end 114 | 115 | test al, DRIVER_IDE_STATUS_error 116 | jnz .end 117 | 118 | mov ecx, 256 119 | mov dx, word [rsp] 120 | add dx, DRIVER_IDE_REGISTER_data 121 | rep insw 122 | 123 | mov rdi, qword [rsp + STATIC_QWORD_SIZE_byte] 124 | 125 | mov eax, dword [rdi + DRIVER_IDE_IDENTIFY_command_sets] 126 | test eax, DRIVER_IDE_IDENTIFY_COMMAND_SETS_lba_extended 127 | jz .end 128 | 129 | mov rcx, driver_ide_devices 130 | 131 | mov dx, word [rsp] 132 | cmp dx, DRIVER_IDE_CHANNEL_PRIMARY 133 | je .primary 134 | 135 | add rcx, DRIVER_IDE_STRUCTURE_DEVICE.SIZE << STATIC_MULTIPLE_BY_2_shift 136 | 137 | .primary: 138 | mov al, byte [rsp + STATIC_QWORD_SIZE_byte * 0x02] 139 | cmp al, DRIVER_IDE_DRIVE_master 140 | je .master 141 | 142 | add rcx, DRIVER_IDE_STRUCTURE_DEVICE.SIZE 143 | 144 | .master: 145 | mov word [rcx + DRIVER_IDE_STRUCTURE_DEVICE.channel], dx 146 | 147 | mov byte [rcx + DRIVER_IDE_STRUCTURE_DEVICE.drive], al 148 | 149 | mov eax, dword [rdi + DRIVER_IDE_IDENTIFY_max_lba_extended] 150 | mov qword [rcx + DRIVER_IDE_STRUCTURE_DEVICE.size_sectors], rax 151 | 152 | inc byte [driver_ide_devices_count] 153 | 154 | .end: 155 | pop rdx 156 | pop rdi 157 | pop rax 158 | pop rcx 159 | 160 | ret 161 | 162 | driver_ide_wait: 163 | push rax 164 | 165 | mov rax, qword [driver_rtc_microtime] 166 | inc rax 167 | 168 | .wait: 169 | cmp rax, qword [driver_rtc_microtime] 170 | jnb .wait 171 | 172 | pop rax 173 | 174 | ret 175 | 176 | driver_ide_init: 177 | push rax 178 | push rdx 179 | push rdi 180 | 181 | call kernel_memory_alloc_page 182 | 183 | mov al, DRIVER_IDE_CONTROL_nIEN 184 | mov dx, DRIVER_IDE_CHANNEL_PRIMARY + DRIVER_IDE_REGISTER_channel_control_OR_altstatus 185 | out dx, al 186 | 187 | mov dx, DRIVER_IDE_CHANNEL_PRIMARY 188 | call driver_ide_pool 189 | jc .next 190 | 191 | mov al, DRIVER_IDE_CONTROL_SRST 192 | mov dx, DRIVER_IDE_CHANNEL_PRIMARY + DRIVER_IDE_REGISTER_channel_control_OR_altstatus 193 | out dx, al 194 | 195 | xor al, al 196 | out dx, al 197 | 198 | mov dx, DRIVER_IDE_CHANNEL_PRIMARY 199 | call driver_ide_pool 200 | 201 | mov al, DRIVER_IDE_DRIVE_master 202 | mov dx, DRIVER_IDE_CHANNEL_PRIMARY 203 | call driver_ide_init_drive 204 | 205 | mov al, DRIVER_IDE_DRIVE_slave 206 | mov dx, DRIVER_IDE_CHANNEL_PRIMARY 207 | call driver_ide_init_drive 208 | 209 | .next: 210 | mov al, DRIVER_IDE_CONTROL_nIEN 211 | mov dx, DRIVER_IDE_CHANNEL_SECONDARY + DRIVER_IDE_REGISTER_channel_control_OR_altstatus 212 | out dx, al 213 | 214 | mov dx, DRIVER_IDE_CHANNEL_SECONDARY 215 | call driver_ide_pool 216 | jc .end 217 | 218 | mov al, DRIVER_IDE_CONTROL_SRST 219 | mov dx, DRIVER_IDE_CHANNEL_SECONDARY + DRIVER_IDE_REGISTER_channel_control_OR_altstatus 220 | out dx, al 221 | 222 | xor al, al 223 | out dx, al 224 | 225 | mov dx, DRIVER_IDE_CHANNEL_SECONDARY 226 | call driver_ide_pool 227 | 228 | mov al, DRIVER_IDE_DRIVE_master 229 | mov dx, DRIVER_IDE_CHANNEL_SECONDARY 230 | call driver_ide_init_drive 231 | 232 | mov al, DRIVER_IDE_DRIVE_slave 233 | mov dx, DRIVER_IDE_CHANNEL_SECONDARY 234 | call driver_ide_init_drive 235 | 236 | .end: 237 | call kernel_memory_release_page 238 | 239 | pop rdi 240 | pop rdx 241 | pop rax 242 | 243 | ret 244 | 245 | driver_ide_pool: 246 | push rax 247 | push rdx 248 | 249 | add dx, DRIVER_IDE_REGISTER_channel_control_OR_altstatus 250 | in al, dx 251 | in al, dx 252 | in al, dx 253 | in al, dx 254 | 255 | test al, al 256 | jz .error 257 | 258 | cmp al, STATIC_MAX_unsigned 259 | jne .wait 260 | 261 | .error: 262 | stc 263 | 264 | jmp .end 265 | 266 | .wait: 267 | in al, dx 268 | and al, DRIVER_IDE_STATUS_busy | DRIVER_IDE_STATUS_ready 269 | cmp al, DRIVER_IDE_STATUS_ready 270 | jne .wait 271 | 272 | clc 273 | 274 | .end: 275 | pop rdx 276 | pop rax 277 | 278 | ret 279 | --------------------------------------------------------------------------------