Compare commits

..
Author SHA1 Message Date
t3hn3rd 8b4335768b refactor(memory): complete PMM/VMM/LMM rewrite - bitmap allocators, bug fixes, hardening
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
PMM Rewrite:
- Replace ~8KB record array with compact bitmaps
  (PhysPresent/PhysAlloc/PhysScanned, 128B each)
- Add PhysOwner[0..1023] for per-block ownership tracking
- new_block: O(1) amortised via NextFreeHint + dword-level BSF scan,
  returns 0 as OOM sentinel
- free_block: O(1) direct bit clear with double-free detection
- alloc_block: validates PhysPresent and PhysAlloc bits before allocation
- Add pmm_free_blocks/pmm_total_blocks stats functions

VMM Correctness Fixes:
- Fix free_page block extraction (Address SHR 10, was using
  raw Address field)
- Fix invlpg operand (use virtual address, was passing PDE index)
- Clear PDE entry on free_page before returning block to PMM
- Remove map_page double-write (delegate to map_page_ex only)
- Add OOM propagation (new_page returns false if PMM returns 0)
- Fix missing pop_trace in new_page error path

LMM Rewrite:
- Replace per-entry record array with bitmap allocator
  (93% vs 43% page efficiency)
- Layout: Header(24B) + Bitmap(64512B) + Padding + Data at 0x10000
- SIZE_PREFIX=16 for 16-byte aligned returns (SSE MOVAPS requirement)
- Next-fit bitmap scan with roving hint (NextFree) and dword-level
  fast skip
- Large alloc sentinel (LARGE_ALLOC_MAGIC=$FFFFFFFE) so kfree detects
  klalloc'd memory
- Implement klfree (was previously a no-op - pages could never
  be returned)
- Implement try_release_page (return fully-free heap pages to VMM/PMM)
- Fix interrupt safety: stack-balanced pushfd/cli/pop +
  restore_if (sti only)
  Fixes Bad TSS caused by popfd restoring dangerous EFLAGS bits (NT, IOPL)
- Zero memory via rep stosd instead of byte-by-byte loop

Hardening:
- kalloc OOM now triggers BSOD instead of returning nil
  (90% of callers don't check)
- Double-free detection in kfree (verify bitmap bits set before clearing)
- Guard bytes ({$IFDEF DEBUG_LMM}): $DEADBEEF sentinel for buffer overrun detection
- kpalloc: bounds check (block >= 1024 -> GPF) + syslog MMIO mapping audit log

Observability:
- Add MEMINFO command as src/prog/meminfo.pas (moved from inline kernel.pas)
- Displays multiboot memory, PMM block stats, LMM heap stats
- Register via progmanager.pas following standard prog pattern

Files changed:
- src/pmemorymanager.pas
- src/vmemorymanager.pas
- src/lmemorymanager.pas
- src/kernel.pas
- src/progmanager.pas
- src/prog/meminfo.pas
2026-03-04 10:36:09 +00:00
233 changed files with 8539 additions and 37976 deletions

No files matched your search

+2 -2
View File
@@ -22,8 +22,8 @@ steps:
commands: commands:
- git fetch --tags - git fetch --tags
- find . -type f -print0 | xargs -0 dos2unix - find . -type f -print0 | xargs -0 dos2unix
- chmod +x /drone/src/toolchain/*.sh - chmod +x /drone/src/*.sh
- /drone/src/toolchain/compile.sh - /drone/src/compile.sh
- name: upload-iso-artifact - name: upload-iso-artifact
image: alpine/git image: alpine/git
+1 -4
View File
@@ -14,8 +14,5 @@ localenv.json
/lvgl/ /lvgl/
dockerout.txt dockerout.txt
AGENTS.md AGENTS.md
lessons_learnt.md
*.log *.log
/doc/*.md /doc/*.md
wasuro
src/core/core.version.pas
+2 -1
View File
@@ -14,9 +14,10 @@ RUN curl -sL https://sourceforge.net/projects/freepascal/files/Linux/$FPC_VERSIO
pushd fpc-$FPC_VERSION.i386-linux && ./install.sh && popd && \ pushd fpc-$FPC_VERSION.i386-linux && ./install.sh && popd && \
rm -rf fpc-$FPC_VERSION.i386-linux rm -rf fpc-$FPC_VERSION.i386-linux
COPY compile.sh /compile.sh
ADD https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver /usr/bin/semver ADD https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver /usr/bin/semver
RUN chmod +x /usr/bin/semver RUN chmod +x /usr/bin/semver
WORKDIR /code WORKDIR /code
RUN find . -type f -print0 | xargs -0 dos2unix RUN find . -type f -print0 | xargs -0 dos2unix
ENTRYPOINT ["/bin/bash", "-c"] ENTRYPOINT ["/bin/bash", "-c"]
CMD ["find toolchain -name '*.sh' -exec dos2unix {} + 2>/dev/null; find toolchain -name '*.sh' -exec chmod +x {} +; bash toolchain/compile.sh"] CMD ["/compile.sh"]
-75
View File
@@ -1,75 +0,0 @@
{ Compatibility shim: wasuro references the old unit name 'lmemorymanager'.
Since wasuro/ cannot be modified, this unit re-exports the public API of
memory.heap so that 'uses lmemorymanager' continues to compile. }
unit lmemorymanager;
interface
uses
memory.heap;
const
ALLOC_UNIT = memory.heap.ALLOC_UNIT;
DATA_OFFSET = memory.heap.DATA_OFFSET;
PAGE_SIZE_LMM = memory.heap.PAGE_SIZE_LMM;
TOTAL_UNITS = memory.heap.TOTAL_UNITS;
BITMAP_DWORDS = memory.heap.BITMAP_DWORDS;
SIZE_PREFIX = memory.heap.SIZE_PREFIX;
LARGE_ALLOC_MAGIC = memory.heap.LARGE_ALLOC_MAGIC;
type
PHeapPageHeader = memory.heap.PHeapPageHeader;
THeapPageHeader = memory.heap.THeapPageHeader;
procedure init;
function kalloc(size : uint32) : void;
function klalloc(size : uint32) : void;
procedure klfree(address : uint32);
function kpalloc(address : uint32) : void;
procedure kfree(area : void);
function lmm_total_free : uint32;
function lmm_page_count : uint32;
implementation
procedure init;
begin
memory.heap.init;
end;
function kalloc(size : uint32) : void; inline;
begin
kalloc := memory.heap.kalloc(size);
end;
function klalloc(size : uint32) : void; inline;
begin
klalloc := memory.heap.klalloc(size);
end;
procedure klfree(address : uint32); inline;
begin
memory.heap.klfree(address);
end;
function kpalloc(address : uint32) : void; inline;
begin
kpalloc := memory.heap.kpalloc(address);
end;
procedure kfree(area : void); inline;
begin
memory.heap.kfree(area);
end;
function lmm_total_free : uint32; inline;
begin
lmm_total_free := memory.heap.lmm_total_free;
end;
function lmm_page_count : uint32; inline;
begin
lmm_page_count := memory.heap.lmm_page_count;
end;
end.
-7
View File
@@ -1,7 +0,0 @@
unit types;
interface
implementation
end.
+3 -6
View File
@@ -20,13 +20,10 @@ runOrFail() {
fi fi
} }
TOOLCHAIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
declare -a run_steps=( declare -a run_steps=(
"compile_stub.sh" "Failed to compile stub!" "compile_stub.sh" "Failed to compile stub!"
"compile_vergen.sh" "Versions failed to compile" "compile_vergen.sh" "Versions failed to compile"
"compile_lvgl.sh" "Failed to compile LVGL!" "compile_lvgl.sh" "Failed to compile LVGL!"
"compile_wasuro.sh" "Failed to pull Wasuro!"
"compile_sources.sh" "Failed to compile FPC Sources!" "compile_sources.sh" "Failed to compile FPC Sources!"
"compile_link.sh" "Failed linking!" "compile_link.sh" "Failed linking!"
"compile_isogen.sh" "Failed to create ISO!" "compile_isogen.sh" "Failed to create ISO!"
@@ -36,7 +33,7 @@ for ((i=0; i<${#run_steps[@]}; i+=2))
do do
if [ "$ERRCOUNT" -eq "0" ] if [ "$ERRCOUNT" -eq "0" ]
then then
script="${TOOLCHAIN_DIR}/${run_steps[$i]}" script=$(pwd)/"${run_steps[$i]}"
message="${run_steps[$i+1]}" message="${run_steps[$i+1]}"
runOrFail "$script" "$message" runOrFail "$script" "$message"
fi fi
@@ -45,9 +42,9 @@ done
#Call generate final artifacts based on failure or success of the above. #Call generate final artifacts based on failure or success of the above.
if [ "$ERRCOUNT" -ne "0" ] if [ "$ERRCOUNT" -ne "0" ]
then then
. "${TOOLCHAIN_DIR}/compile_finish.sh" "failed" . ./compile_finish.sh "failed"
else else
. "${TOOLCHAIN_DIR}/compile_finish.sh" "success" . ./compile_finish.sh "success"
fi fi
cd .. cd ..
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -19,4 +19,4 @@ echo " "
LIBGCC=$(gcc -m32 -print-libgcc-file-name) LIBGCC=$(gcc -m32 -print-libgcc-file-name)
echo "libgcc: ${LIBGCC}" echo "libgcc: ${LIBGCC}"
ld -m elf_i386 -s --gc-sections -Ttoolchain/linker.script -o bin/kernel.bin $objstring --start-group lib/liblvgl.a ${LIBGCC} --end-group ld -m elf_i386 -s --gc-sections -Tlinker.script -o bin/kernel.bin $objstring --start-group lib/liblvgl.a ${LIBGCC} --end-group
+8 -22
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,16 +105,14 @@ 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 " "
echo "LVGL compilation complete." echo "LVGL compilation complete."
echo " " echo " "
File renamed without changes.
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
echo " "
echo "======================="
echo " "
echo "Compiling FPC Sources..."
echo " "
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
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
echo " "
echo "======================="
echo " "
echo "Compiling Stub..."
echo " "
nasm -f elf src/stub/stub.asm -o lib/stub.o
File renamed without changes.
@@ -1,15 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TOOLCHAIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo " " echo " "
echo "=======================" echo "======================="
echo " " echo " "
echo "Generating Versioning Info..." echo "Generating Versioning Info..."
echo " " echo " "
chmod +x "${TOOLCHAIN_DIR}/compile_checksum.sh" chmod +x ./compile_checksum.sh
"${TOOLCHAIN_DIR}/compile_checksum.sh" ./compile_checksum.sh
outfile="src/core/core.version.pas" outfile="src/include/asuro.pas"
file="toolchain/version" file="version"
{ {
# this script requires semver tool # this script requires semver tool
wget -q https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver -O bin/semver && chmod +x bin/semver wget -q https://raw.githubusercontent.com/fsaintjacques/semver-tool/master/src/semver -O bin/semver && chmod +x bin/semver
@@ -23,7 +22,7 @@ sub=$(semver get patch $tagref)
version=$(semver get release $tagref) version=$(semver get release $tagref)
release=$(semver get prerel $tagref) release=$(semver get prerel $tagref)
build=$(semver get build $tagref) build=$(semver get build $tagref)
linecount=$("${TOOLCHAIN_DIR}/loc.sh" | awk '{print $1}') linecount=$(./loc.sh | awk '{print $1}')
sourcecount=$(find src -type f | wc -l) sourcecount=$(find src -type f | wc -l)
drivercount=$(find src/driver -type f | wc -l) drivercount=$(find src/driver -type f | wc -l)
fpcversion=$(fpc -h | grep -m 1 version | awk '{print $5}') fpcversion=$(fpc -h | grep -m 1 version | awk '{print $5}')
@@ -35,7 +34,7 @@ checksum=$(md5sum checksums.md5 | awk '{print $1}')
[[ -n "$release" ]] && version="$version-$release" [[ -n "$release" ]] && version="$version-$release"
cat > $outfile <<EOF cat > $outfile <<EOF
unit core.version; unit asuro;
interface interface
-32
View File
@@ -1,32 +0,0 @@
#Flat filesystem
A super simple filesystem for asuro. Folders are emulated in filenames.
Starts with disk info sector, sector 0 of volume
---
#### disk info
jmp2boot : ubit24;
OEMName : array[0..7] of char;
version : uint16 // numerical version of filesystem
sectorCount : uint16;
fileCount : uint16
signature : uint32 = 0x0B00B1E5
the Rest of the sector is reserved
---
Starting from sector 1 is the file table. Table size is determined by entry size (64) * fileCount
---
####File entry
name : array[0..59] of char //file name max 60 chars
fileStart : 16bit // start sector of data
fileSize : 16bit // data size in sectors
---
-648
View File
File diff suppressed because it is too large. Load diff
-587
View File
File diff suppressed because it is too large. Load diff
Loaded 20 of 233 files, more files were not shown because too many files have changed in this diff. Show more