├── .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 | 
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 |
--------------------------------------------------------------------------------