Compare commits

..
Author SHA1 Message Date
t3hn3rd 99fd5507ca Merge branch 'feature/vtop-fix' into feature/process-management
continuous-integration/drone/push Build is passing
2026-03-03 19:11:47 +00:00
t3hn3rd 035d489c4f feature: preemptive process management - implementation progress
continuous-integration/drone/push Build is passing
Implement a preemptive multitasking system for the Asuro kernel.

Context Switching & Scheduling:
- Custom IRQ0 ISR (contextswitcher.pas) with PUSHAD/POPAD ESP-swap
- Round-robin scheduler with priority-based quantum
- Process table using DList of PProcessContext pointers
- Idle process (PID 0) replaces kernel HLT loop

Process Lifecycle:
- create/kill/terminate/sendMessage API (processmanager.pas)
- Process states: Created, Running, Ready, Suspended, Awaiting,
  Finished, Error
- Parent-child tracking (ParentID, smChildExited notification on reap)
- proc_yield, proc_sleep_ms, proc_await, proc_suspend, proc_exit

Resource Binding & Cleanup:
- Per-process resource list
  (bindResource/unbindResource/unbindAllResources)
- TCP sockets auto-bound to owning process (OwnerPID on TTCPSocket)
- socket_cleanup + auto-unbind in DestroySocket

VTerminal Refactor:
- Multi-instance design (heap-allocated TVTermState per terminal)
- Foreground process with incremental stdout/stderr drain via LVGL timer
- Ctrl+C kills foreground process (killForeground)
- Per-terminal CWD, dir stack, FS builtins (CD/LS/PUSHD/POPD)
- Background job support (& suffix, JOBS/FG commands)
- Command history (Up/Down arrow)

Command Consolidation:
- 14 commands extracted from 9 units into centralized progmanager.pas
- Command procedures exported in host unit interfaces
- E1000/TRACER/stdio builtins kept in-place (conditional/circular)

New Units:
- src/include/proctypes.pas — process type definitions
- src/processmanager.pas — core process manager
- src/prog/ping.pas — standalone ICMP ping process
- src/prog/testcmd.pas — test command (proc_sleep_ms demo)
- src/testprocs.pas — process subsystem smoke tests

Misc:
- ICMP callbacks gain userData parameter for concurrency-safe ping
- CLI/STI guards on kalloc/kfree (lmemorymanager.pas)
- LV_KEY_CTRLC constant + Ctrl+C interception in LVGL keyboard hook
- Window owner PID tracking (windows.pas)
- ISR_32 gate override support (isrmanager.pas)
2026-03-03 19:02:21 +00:00
t3hn3rd 5e9d0004d7 feature: implement TCP (RFC 793) protocol driver
continuous-integration/drone/push Build is passing
Add full TCP/IP stack implementation at L4 alongside UDP and ICMP.

Core Protocol Engine:
- TCP types in nettypes.pas (header, TCB, state enum, error codes,
  callbacks, OOO entry, socket structures)
- 3-way handshake (active & passive OPEN)
- Reliable data transfer with ACK and sequence number tracking
- Graceful close (FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT)
- RST send/receive handling
- Retransmission with exponential backoff (max 5 attempts)
- Pseudo-header based checksum (RFC 793)

Server Support:
- LISTEN → SYN_RECEIVED → ESTABLISHED passive open path
- Listen backlog enforcement (configurable per-socket)
- accept() to retrieve established child connections

Robustness & Hardening:
- Delayed ACK timer (~200ms)
- Nagle's algorithm (buffer small sends while unACKed data pending)
- Jacobson/Karels RTT estimation with adaptive RTO
- Congestion control (slow start / congestion avoidance)
- Zero-window probing with exponential backoff
- MSS option negotiation in SYN/SYN-ACK (Kind=2, Len=4)
- Keep-alive (30s idle, 10s interval, 5 probes)
- Out-of-order segment reassembly (4-slot buffer)

Terminal & Testing:
- tcpconnect: active open + send "Hello, World!"
- tcplisten: passive open with syslog output
- tcphttp: HTTP/1.0 GET client

Also add push_trace() instrumentation to net, eth2, arp, ipv4,
icmp, udp, and dhcp entry points for call tracing, and register
tcp in net.init.
2026-03-03 10:55:50 +00:00
18 changed files with 312 additions and 3494 deletions

No files matched your search

+7 -21
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# compile_lvgl.sh — Download LVGL v9.2 source and compile into lib/liblvgl.a # compile_lvgl.sh — Download LVGL v9.2 source and compile into lib/liblvgl.a
# Clone & compile in /tmp (fast container-local fs). # Clone & compile in /tmp (fast container-local fs).
# Cache liblvgl.a on host mount (/code/lvgl/) to skip rebuild. # Copy source + objects to /lvgl (host mount) for debugging.
set -e set -e
LVGL_VERSION="v9.2.2" LVGL_VERSION="v9.2.2"
@@ -10,7 +10,6 @@ LVGL_DIR="/tmp/lvgl"
OBJ_DIR="/tmp/lvgl_obj" OBJ_DIR="/tmp/lvgl_obj"
CONF_DIR="$(pwd)/lvglh" CONF_DIR="$(pwd)/lvglh"
OUT_DIR="$(pwd)/lib" OUT_DIR="$(pwd)/lib"
CACHE_DIR="/code/lvgl"
CC="gcc" CC="gcc"
CFLAGS="-m32 -march=i686 -ffreestanding \ CFLAGS="-m32 -march=i686 -ffreestanding \
@@ -27,17 +26,6 @@ echo " "
echo "Compiling LVGL..." echo "Compiling LVGL..."
echo " " echo " "
# If cached liblvgl.a exists on host mount, just copy it and skip everything
if [ -f "${CACHE_DIR}/liblvgl.a" ]; then
echo "Found cached liblvgl.a in ${CACHE_DIR}, copying to ${OUT_DIR}..."
cp "${CACHE_DIR}/liblvgl.a" "${OUT_DIR}/liblvgl.a"
echo "(Delete lvgl/liblvgl.a to force a full rebuild.)"
echo " "
echo "LVGL compilation complete (cached)."
echo " "
exit 0
fi
# Clone LVGL into /tmp (container-local) # Clone LVGL into /tmp (container-local)
rm -rf "$LVGL_DIR" rm -rf "$LVGL_DIR"
echo "Downloading LVGL ${LVGL_VERSION}..." echo "Downloading LVGL ${LVGL_VERSION}..."
@@ -117,14 +105,12 @@ else
echo "No custom LVGL files in lvglh/." echo "No custom LVGL files in lvglh/."
fi fi
# Cache liblvgl.a and source to host mount for next build # Copy source + objects to /lvgl host mount for debugging
echo "Caching LVGL to host mount..." echo "Copying LVGL source and objects to host mount..."
mkdir -p "$CACHE_DIR" mkdir /code/lvgl 2>/dev/null || true
rm -rf ${CACHE_DIR}/* ${CACHE_DIR}/.[!.]* ${CACHE_DIR}/..?* 2>/dev/null || true rm -rf /code/lvgl/* /code/lvgl/.[!.]* /code/lvgl/..?* 2>/dev/null || true
cp "${OUT_DIR}/liblvgl.a" "${CACHE_DIR}/liblvgl.a" cp -a "$LVGL_DIR/src" /code/lvgl/src
cp -a "$LVGL_DIR/src" "${CACHE_DIR}/src" cp -a "$OBJ_DIR" /code/lvgl/obj
cp -a "$LVGL_DIR"/*.h "${CACHE_DIR}/" 2>/dev/null || true
cp -a "$OBJ_DIR" "${CACHE_DIR}/obj"
echo "Done." echo "Done."
echo " " echo " "
+1 -1
View File
@@ -4,4 +4,4 @@ echo "======================="
echo " " echo " "
echo "Compiling FPC Sources..." echo "Compiling FPC Sources..."
echo " " echo " "
fpc -Aelf -gw -g -gl -n -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/include/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/driver/bus/* -Fusrc/driver/bus/usb/* -Fusrc/driver/hid/* src/kernel.pas fpc -Aelf -gw -g -gl -n -v0ew -O3 -OpPENTIUM3 -Si -Sc -Sg -Xd -CX -XXs -CfSSE -CfSSE2 -Rintel -Pi386 -Tlinux -FElib/ -Fusrc/* -Fusrc/driver/* -Fusrc/driver/net/* -Fusrc/driver/bus/* -Fusrc/driver/bus/usb/* -Fusrc/driver/hid/* src/kernel.pas
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+21 -11
View File
@@ -69,13 +69,32 @@ uses
hashmap, vfs, hashmap, vfs,
video, vesa, doublebuffer, color, lvgl, desktop, uidebug, video, vesa, doublebuffer, color, lvgl, desktop, uidebug,
vterminal, vterminal,
graphicsrefresh, usbhotplug, graphicsrefresh, usbhotplug;
fifo, cfifo, cfifols, lifo, circ, minh, maxh, prio;
procedure terminal_command_meminfo(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
procedure terminal_command_bsod(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall; procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
implementation implementation
procedure terminal_command_meminfo(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
begin
push_trace('kernel.terminal_command_meminfo');
stdio.bufWriteStr(stdout_buf, 'Lower Memory = ');
stdio.bufWriteInt(stdout_buf, multibootinfo^.mem_lower);
stdio.bufWriteStrLn(stdout_buf, 'KB');
stdio.bufWriteStr(stdout_buf, 'Higher Memory = ');
stdio.bufWriteInt(stdout_buf, multibootinfo^.mem_upper);
stdio.bufWriteStrLn(stdout_buf, 'KB');
stdio.bufWriteStr(stdout_buf, 'Total Memory = ');
stdio.bufWriteInt(stdout_buf, ((multibootinfo^.mem_upper + 1000) div 1024) + 1);
stdio.bufWriteStrLn(stdout_buf, 'MB');
pop_trace;
end;
procedure terminal_command_bsod(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf); procedure terminal_command_bsod(params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
begin begin
push_trace('kernel.terminal_command_bsod'); push_trace('kernel.terminal_command_bsod');
@@ -168,7 +187,6 @@ begin
{ Stdio Init } { Stdio Init }
stdio.init(); stdio.init();
stdio.registerCommand('BSOD', @terminal_command_bsod, 'Force a Panic Screen.');
tss.init(); tss.init();
scheduler.init(); scheduler.init();
@@ -259,14 +277,6 @@ begin
usbhub.UnitTest; usbhub.UnitTest;
usb_keyboard.UnitTest; usb_keyboard.UnitTest;
usb_mouse.UnitTest; usb_mouse.UnitTest;
fifo.UnitTest;
cfifo.UnitTest;
cfifols.UnitTest;
lifo.UnitTest;
circ.UnitTest;
minh.UnitTest;
maxh.UnitTest;
prio.UnitTest;
{ Register timer-driven tasks } { Register timer-driven tasks }
graphicsrefresh.init; graphicsrefresh.init;
+159 -510
View File
File diff suppressed because it is too large. Load diff
+99 -239
View File
File diff suppressed because it is too large. Load diff
-83
View File
@@ -1,83 +0,0 @@
// Copyright 2021 Kieron Morris
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
{
Prog->meminfo - Print memory statistics (PMM / LMM).
@author(Kieron Morris <[email protected]>)
}
unit meminfo;
interface
uses
stdio, multiboot, pmemorymanager, lmemorymanager, tracer;
procedure init();
implementation
procedure run(Params : PParamList; stdin_buf, stdout_buf, stderr_buf : POutBuf);
var
pmm_total, pmm_free, pmm_used : uint32;
lmm_pages, lmm_free : uint32;
begin
{ Multiboot memory info }
stdio.bufWriteStrLn(stdout_buf, '--- Multiboot ---');
stdio.bufWriteStr(stdout_buf, 'Lower Memory : ');
stdio.bufWriteInt(stdout_buf, multibootinfo^.mem_lower);
stdio.bufWriteStrLn(stdout_buf, ' KB');
stdio.bufWriteStr(stdout_buf, 'Upper Memory : ');
stdio.bufWriteInt(stdout_buf, multibootinfo^.mem_upper);
stdio.bufWriteStrLn(stdout_buf, ' KB');
stdio.bufWriteStr(stdout_buf, 'Total Memory : ');
stdio.bufWriteInt(stdout_buf, ((multibootinfo^.mem_upper + 1000) div 1024) + 1);
stdio.bufWriteStrLn(stdout_buf, ' MB');
{ PMM stats }
stdio.bufWriteStrLn(stdout_buf, '--- PMM (4 MB blocks) ---');
pmm_total := pmemorymanager.pmm_total_blocks;
pmm_free := pmemorymanager.pmm_free_blocks;
pmm_used := pmm_total - pmm_free;
stdio.bufWriteStr(stdout_buf, 'Total Blocks : ');
stdio.bufWriteIntLn(stdout_buf, pmm_total);
stdio.bufWriteStr(stdout_buf, 'Free Blocks : ');
stdio.bufWriteIntLn(stdout_buf, pmm_free);
stdio.bufWriteStr(stdout_buf, 'Used Blocks : ');
stdio.bufWriteIntLn(stdout_buf, pmm_used);
stdio.bufWriteStr(stdout_buf, 'Free Physical : ');
stdio.bufWriteInt(stdout_buf, pmm_free * 4);
stdio.bufWriteStrLn(stdout_buf, ' MB');
{ LMM heap stats }
stdio.bufWriteStrLn(stdout_buf, '--- LMM (Heap) ---');
lmm_pages := lmemorymanager.lmm_page_count;
lmm_free := lmemorymanager.lmm_total_free;
stdio.bufWriteStr(stdout_buf, 'Heap Pages : ');
stdio.bufWriteIntLn(stdout_buf, lmm_pages);
stdio.bufWriteStr(stdout_buf, 'Heap Size : ');
stdio.bufWriteInt(stdout_buf, lmm_pages * 4);
stdio.bufWriteStrLn(stdout_buf, ' MB');
stdio.bufWriteStr(stdout_buf, 'Heap Free : ');
stdio.bufWriteInt(stdout_buf, lmm_free div 1024);
stdio.bufWriteStrLn(stdout_buf, ' KB');
end;
procedure init();
begin
tracer.push_trace('meminfo.init');
stdio.registerCommand('MEMINFO', @Run, 'Print memory statistics (PMM/LMM).');
end;
end.
+3 -2
View File
@@ -24,7 +24,7 @@ interface
uses uses
tracer, tracer,
//progs //progs
base64_prog, md5sum, dhclient, vbeinfo, testcmd, ping, meminfo; base64_prog, md5sum, dhclient, vbeinfo, testcmd, ping;
{ Initialize all baked-in programs } { Initialize all baked-in programs }
procedure init(); procedure init();
@@ -43,6 +43,8 @@ begin
tracer.push_trace('progmanager.init'); tracer.push_trace('progmanager.init');
{ Register commands from provider units } { Register commands from provider units }
stdio.registerCommand('MEMINFO', @kernel.terminal_command_meminfo, 'Print Simple Memory Information.');
stdio.registerCommand('BSOD', @kernel.terminal_command_bsod, 'Force a Panic Screen.');
stdio.registerCommand('CPU', @cpu.Terminal_Command_CPU, 'CPU Info.'); stdio.registerCommand('CPU', @cpu.Terminal_Command_CPU, 'CPU Info.');
stdio.registerCommand('DEV', @drivermanagement.terminal_command_dev, 'Driver Management Interface.'); stdio.registerCommand('DEV', @drivermanagement.terminal_command_dev, 'Driver Management Interface.');
stdio.registerCommand('PS', @processmanager.terminal_command_ps, 'List running processes.'); stdio.registerCommand('PS', @processmanager.terminal_command_ps, 'List running processes.');
@@ -63,7 +65,6 @@ begin
vbeinfo.init(); vbeinfo.init();
testcmd.init(); testcmd.init();
ping.init(); ping.init();
meminfo.init();
end; end;
end. end.
+22 -26
View File
@@ -159,14 +159,20 @@ end;
function map_page(page_number : uint16; block : uint16) : boolean; function map_page(page_number : uint16; block : uint16) : boolean;
var var
addr : ubit20;
page : uint16;
rldpd : uint32; rldpd : uint32;
begin begin
push_trace('vmemorymanager.map_page'); push_trace('vmemorymanager.map_page');
{ Delegate to map_page_ex — no redundant direct PDE writes } map_page:= false;
map_page := map_page_ex(page_number, block, PageDirectory); PageDirectory^[page_number].Present:= true;
{ Reload CR3 to flush TLB } addr:= block;
rldpd := uint32(PageDirectory) - KERNEL_VIRTUAL_BASE; PageDirectory^[page_number].Address:= addr SHL 10;
PageDirectory^[page_number].PageSize:= true;
PageDirectory^[page_number].Writable:= true;
map_page:= map_page_ex(page_number, block, PageDirectory);
rldpd:= uint32(PageDirectory) - KERNEL_VIRTUAL_BASE;
asm asm
mov eax, rldpd mov eax, rldpd
mov CR3, eax mov CR3, eax
@@ -195,15 +201,14 @@ var
begin begin
push_trace('vmemorymanager.new_page'); push_trace('vmemorymanager.new_page');
new_page := false; new_page:= false;
if not PageDirectory^[page_number].Present then begin if not PageDirectory^[page_number].Present then begin
if not PageDirectory^[page_number].Reserved then begin if not PageDirectory^[page_number].Reserved then begin
block := pmemorymanager.new_block(uint32(PageDirectory)); block:= pmemorymanager.new_block(uint32(PageDirectory));
if block = 0 then begin if block < 2 then begin
{ OOM — PMM has no free blocks. Return false gracefully. } GPF;
syslog.logln('VMM', 'ERROR: new_page failed — PMM OOM.');
end else begin end else begin
new_page := map_page(page_number, block); new_page:= map_page(page_number, block);
end; end;
end; end;
end; end;
@@ -211,15 +216,17 @@ begin
end; end;
function page_mappable(page_number : uint16) : boolean; function page_mappable(page_number : uint16) : boolean;
var
block : uint16;
begin begin
push_trace('vmemorymanager.page_mappable'); push_trace('vmemorymanager.page_mappable');
page_mappable := false; page_mappable:= false;
if not PageDirectory^[page_number].Present then begin if not PageDirectory^[page_number].Present then begin
if not PageDirectory^[page_number].Reserved then begin if not PageDirectory^[page_number].Reserved then begin
page_mappable := true; page_mappable:= true;
end; end;
end; end;
pop_trace;
end; end;
function new_page_at_address(address : uint32) : boolean; function new_page_at_address(address : uint32) : boolean;
@@ -236,25 +243,14 @@ end;
procedure free_page(page_number : uint16); procedure free_page(page_number : uint16);
var var
block : uint16; block : uint16;
vaddr : uint32;
begin begin
push_trace('vmemorymanager.free_page'); push_trace('vmemorymanager.free_page');
if PageDirectory^[page_number].Present then begin if PageDirectory^[page_number].Present then begin
{ Recover block index: Address stores (block SHL 10), so SHR 10 gives block } block:= PageDirectory^[page_number].Address;
block := PageDirectory^[page_number].Address SHR 10;
{ Clear the PDE before invalidating }
PageDirectory^[page_number].Present := false;
PageDirectory^[page_number].Writable := false;
PageDirectory^[page_number].PageSize := false;
PageDirectory^[page_number].Address := 0;
{ Invalidate TLB for this virtual address (invlpg needs a virtual addr) }
vaddr := uint32(page_number) SHL 22;
asm asm
mov eax, vaddr invlpg [page_number]
invlpg [eax]
end; end;
{ Return physical block to PMM }
pmemorymanager.free_block(block, uint32(PageDirectory)); pmemorymanager.free_block(block, uint32(PageDirectory));
end else begin end else begin
GPF; GPF;