feature: add mkdocs-material documentation site with CI deployment
Generate comprehensive documentation for all 173 source units and integrate mkdocs-material into the build toolchain. Documentation covers kernel core, x86 architecture, drivers, applications, and all subsystems with a tabbed navigation structure. - Add mkdocs.yml with material theme, mermaid support, and tabbed nav - Add doc/index.md landing page - Generate doc/src/ markdown for every Pascal unit in src/ - Reorganize planning docs into doc/planning/ - Add compat, lvglh, and toolchain doc sections - Update Dockerfile to install python3 and mkdocs-material (pinned <2) - Replace pasdoc-based compile_docs.sh with mkdocs build --strict - Add compile_docs.sh to the main build pipeline in compile.sh - Add deploy-docs step in .drone.yml with host volume mount to nginx - Add site/.gitkeep for build output directory
This commit is contained in:
1 parent
7157a57513
commit
26e2fd947e
209 files changed
+16996
-13
No files matched your search
@@ -0,0 +1,104 @@
|
||||
# arch.x86.v86
|
||||
|
||||
Virtual 8086 (V86) mode monitor for executing real-mode BIOS interrupts from protected mode.
|
||||
|
||||
## Overview
|
||||
|
||||
This unit implements a Virtual 8086 mode monitor that allows the kernel to call BIOS interrupt handlers while running in 32-bit protected mode. The caller sets up a `TV86Regs` record with the desired input register values, calls `v86_int`, and receives the BIOS output register values back in the same record.
|
||||
|
||||
The implementation works by writing a two-instruction thunk (`INT n` / `INT 0xFF`) into low physical memory at address 0x7C00, building an IRET frame with VM=1 set in EFLAGS to switch the CPU into V86 mode, and executing the thunk. Every privileged instruction executed by the BIOS handler in V86 mode causes a General Protection Fault. The unit installs a custom naked GPF handler (`v86_gpf_isr`) that inspects the faulting instruction and emulates it: `INT`, `IRET`, `CLI`, `STI`, `PUSHF/PUSHFD`, `POPF/POPFD`, all `IN`/`OUT` variants (with and without operand-size prefix), and `HLT`. When the sentinel `INT 0xFF` is encountered, results are copied out of the saved register frame and control returns to the Pascal caller.
|
||||
|
||||
A minimal TSS is installed in GDT gate 5 so the CPU can locate the ring-0 stack pointer (ESP0) when transitioning from V86 ring 3 to ring 0 on a GPF.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `core.util`
|
||||
- `arch.x86.util`
|
||||
- `core.panic`
|
||||
- `io.syslog`
|
||||
- `debug.tracer`
|
||||
- `arch.x86.memory.virtual`
|
||||
- `arch.x86.gdt`
|
||||
- `arch.x86.idt`
|
||||
- `arch.x86.isr.types`
|
||||
|
||||
## Constants
|
||||
|
||||
| Constant | Value | Description |
|
||||
|-------------------|----------|-------------|
|
||||
| V86_EFLAGS | `$23000` | EFLAGS for V86 entry: VM=1, IOPL=3, IF=0 |
|
||||
| V86_THUNK_ADDR | `$7C00` | Physical address of the two-instruction thunk |
|
||||
| V86_STACK_SEG | `$0000` | Real-mode stack segment (SS) |
|
||||
| V86_STACK_PTR | `$8000` | Real-mode stack pointer (SP), grows downward |
|
||||
| V86_EXIT_INT | `$FF` | Sentinel interrupt number signalling V86 exit |
|
||||
| V86_R0_STACK_SIZE | `4096` | Size in bytes of the dedicated ring-0 stack used during V86 GPF handling |
|
||||
| V86_TSS_GDT_GATE | `5` | GDT gate index for the TSS descriptor |
|
||||
| V86_TSS_SELECTOR | `40` | TSS segment selector (gate 5 * 8) |
|
||||
| V86_TSS_SIZE | `104` | Minimum x86 TSS size in bytes |
|
||||
|
||||
## Types
|
||||
|
||||
### TV86Regs / PV86Regs
|
||||
|
||||
```pascal
|
||||
TV86Regs = record
|
||||
EAX, EBX, ECX, EDX : uint32;
|
||||
ESI, EDI, EBP : uint32;
|
||||
DS, ES, FS, GS : uint16;
|
||||
end;
|
||||
```
|
||||
|
||||
Input and output register state for a V86 BIOS call. Populate before calling `v86_int`; read results after it returns.
|
||||
|
||||
### TV86GPFFrame / PV86GPFFrame
|
||||
|
||||
```pascal
|
||||
TV86GPFFrame = packed record
|
||||
ErrorCode : uint32;
|
||||
EIP : uint32;
|
||||
CS : uint32;
|
||||
EFLAGS : uint32;
|
||||
ESP : uint32;
|
||||
SS : uint32;
|
||||
ES : uint32;
|
||||
DS : uint32;
|
||||
FS : uint32;
|
||||
GS : uint32;
|
||||
end;
|
||||
```
|
||||
|
||||
The CPU exception frame pushed on the ring-0 stack when a GPF occurs from V86 mode, preceded by the `PUSHAD` frame. The emulator modifies fields directly to redirect V86 execution.
|
||||
|
||||
## Functions and Procedures
|
||||
|
||||
### init
|
||||
|
||||
```pascal
|
||||
procedure init;
|
||||
```
|
||||
|
||||
Initialises the V86 subsystem. Sets up a minimal TSS in `V86TSS`, installs a GDT descriptor for it at gate 5 (access `$89`, present, DPL 0, TSS available), reloads the GDT, loads the task register (`LTR`), identity-maps the first 4 MiB with the user bit set (so V86 code can access the IVT, BDA, and VGA memory), and replaces IDT gate 13 (`#GP`) with the custom naked handler `v86_gpf_isr`. Must be called once during kernel initialisation before any BIOS calls are made.
|
||||
|
||||
### v86_int
|
||||
|
||||
```pascal
|
||||
function v86_int(intNo : uint8; var regs : TV86Regs) : boolean;
|
||||
```
|
||||
|
||||
Executes a real-mode BIOS interrupt from protected mode.
|
||||
|
||||
- `intNo` — The BIOS interrupt number to call (e.g., `$10` for video services).
|
||||
- `regs` — On entry, contains the register values to pass to the BIOS handler. On return, contains the register values returned by the BIOS handler.
|
||||
|
||||
Returns `true` if the call completed successfully (sentinel `INT 0xFF` was reached), `false` if the emulator encountered an unhandled opcode and aborted.
|
||||
|
||||
The function disables interrupts for the duration of the call and re-enables them on return.
|
||||
|
||||
## Notes
|
||||
|
||||
- Real-mode memory addresses are accessed by adding `KERNEL_VIRTUAL_BASE` (`$C0000000`) to the physical linear address, since the first 4 MiB of physical memory is identity-mapped at the higher-half kernel base.
|
||||
- The BIOS thunk is written to physical address 0x7C00 (the standard MBR load address), which is free after boot.
|
||||
- Segment override prefixes (`$26`, `$2E`, `$36`, `$3E`, `$64`, `$65`) and LOCK/REP prefixes (`$F0`, `$F2`, `$F3`) are recognised and skipped during opcode scanning but are otherwise not emulated.
|
||||
- The operand-size prefix (`$66`) is handled for `IRETD`, `PUSHFD`, `POPFD`, and 32-bit `IN`/`OUT` variants.
|
||||
- Non-V86 GPFs that arrive at the patched gate 13 handler are forwarded to `core.panic.panic` via `v86_chain_gpf`.
|
||||
- Only one V86 call may be in progress at a time; the global state variables are not reentrant.
|
||||
Reference in new issue
Block a user