Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
003850b
Implemented a basic framework for testing task switching.
superfury Mar 22, 2026
d9ad7aa
- Improved writing 16-bit TSS entries.
superfury Mar 22, 2026
4ce8f5d
- Implemented far pointers for user mode task switching using the TSS…
superfury Mar 22, 2026
91535c5
Implemented basic 16-bit and 32-bit TSS task switching tests with fla…
superfury Mar 22, 2026
8bf9a61
Improved TSS data and gate segments, allowing access in user mode for…
superfury Mar 23, 2026
f2e7c0e
Fixed TSS segment access rights.
superfury Mar 23, 2026
cb71e8e
Fixed TSS test initialization.
superfury Mar 23, 2026
2dc12a5
Fixed 386 task initialization.
superfury Mar 23, 2026
ff2266b
Fixed 386 task FS loading to properly load the correct register.
superfury Mar 23, 2026
ec5761f
Fixed 16-bit TSS initialization to write to the correct TSS.
superfury Mar 23, 2026
9c9951b
- Fixed 16-bit task initialization.
superfury Mar 23, 2026
09ee245
Fixed the 286 task entry point.
superfury Mar 23, 2026
73ff778
Fixed 286 task validation of segment selectors.
superfury Mar 23, 2026
93b2eca
Fixed setup of CR3 and related fields in the 32-bit TSS.
superfury Mar 23, 2026
d626981
Fixed TSS table layout and ring 2 stack pointers.
superfury Mar 23, 2026
50fb3a3
Update comment for data segment restoration when returning to kernel …
superfury Mar 23, 2026
d884024
Match the flat user code ring 0 setup against the other ring setup code.
superfury Mar 23, 2026
ec2811a
- Fixed return from 32-bit flat user mode to 16-bit kernel mode.
superfury Mar 23, 2026
e0f21b7
Improved 16-bit TSS validation.
superfury Mar 23, 2026
310c575
Improved 286 and 386 task flags test.
superfury Mar 24, 2026
eb853d9
Implemented seperated 16-bit and 32-bit TSS flags testing.
superfury Mar 24, 2026
a8bbb3b
The upper 16 bits of a 16-bit TSS task switched general purpose regis…
superfury Mar 24, 2026
5a60e24
Fixed 16-bit TSS limit to use a proper 16-bit stack pointer.
superfury Mar 24, 2026
5df97db
Fixed 32-bit TSS flags tests.
superfury Mar 24, 2026
4ad0dc1
Moved the entire 16-bit and 32-bit TSS task switch tests to the lower…
superfury Mar 27, 2026
582bbb6
- Fixed 286 TSS to be properly 32-bit as specified in the GDT.
superfury Apr 9, 2026
721a6d8
Fixed the system BIOS area to use proper offsets.
superfury Apr 9, 2026
8e5781a
Implemented 32-bit flat protected mode TSS helper functions to valida…
superfury Apr 9, 2026
14ae4a5
Simplfiied loading the EFLAGS register into EBX for checking the NT bit.
superfury Apr 9, 2026
db6601b
Fixed TSS helper functions error location.
superfury Apr 9, 2026
4302f8d
Implemented a function for setting the TSS backlink field.
superfury Apr 10, 2026
30acd79
Implemented 32-bit TSS and 16-bit TSS initial state validation.
superfury Apr 10, 2026
3658fa6
Implemented TSS task switching busy bit, nested task flag and backlin…
superfury Apr 10, 2026
cb49421
Fixed TSS busy bit error condition.
superfury Apr 10, 2026
fb36819
Fixed TSS data segments for user mode to be properly accessible from …
superfury Apr 10, 2026
f64f018
Fixed TSS busy bit detection and validation.
superfury Apr 10, 2026
76a10cf
- Properly include the TSS size when setting and validating nested ta…
superfury Apr 10, 2026
49d233f
Fixed NT flag validation and TSS size bit positions.
superfury Apr 10, 2026
18b5eb2
Fixed the TSS error pointer to be correctly addressed.
superfury Apr 11, 2026
08cc75f
Fixed TSS helper functions.
superfury Apr 11, 2026
8ac9728
- Fixed various TSS validation issues.
superfury Apr 11, 2026
cff8b99
Improved the 16-bit and 32-bit TSS validation checks.
superfury Apr 11, 2026
406e293
Fixed cleanup of the 386 task NT flag when finishing the TSS tests.
superfury Apr 12, 2026
6862f02
Fixed 80386/80486 JMP causing task switch to properly affect the nest…
superfury Apr 12, 2026
cb9647c
Implemented ring 2 stack validation when validating the TSS task swit…
superfury Apr 13, 2026
bd683a6
Implemented TSS task switch to Virtual 8086 mode tests.
superfury Apr 14, 2026
df30ab7
Validate that Virtual 8086 mode sets the VM flag from PL0.
superfury Apr 14, 2026
ef40469
Verify 16-bit protected mode interrupts from Virtual 8086 mode with t…
superfury Apr 14, 2026
4bfe237
Cleaned up the unused V86 definition file.
superfury Apr 14, 2026
68569fb
Split the POST A into POST 20, 21, 22.
superfury Apr 15, 2026
a42b6bf
Moved the BIOS expansion area into a seperate file.
superfury Apr 16, 2026
3f45b13
Merge branch 'barotto:master' into master
superfury Apr 21, 2026
46a25f0
Added tests for the IDTR and GDTR load and store instructions.
superfury Apr 21, 2026
d873fbe
Added a test for the flag instructions in real mode.
superfury Apr 21, 2026
763ad64
Fixed table pointer registers cleanup after testing.
superfury Apr 21, 2026
bc8ef77
Added a test for XLAT in real mode.
superfury Apr 21, 2026
7917bdb
Implemented interrupt flag tests on real mode interrupts and protecte…
superfury Apr 22, 2026
089aa75
Compressed the POST 8/9/A tests by moving the tests into the system B…
superfury Apr 22, 2026
c80da84
Reverted the POST codes back to before the real mode tests were added.
superfury Apr 22, 2026
34f32b5
- Added a test for a far return with immediate to a more privileged p…
superfury May 24, 2026
b116ce2
- Moved the POST 20 and 21 protected mode tests to the lower 64K ROM.
superfury Jun 1, 2026
1237a1e
- Moved the protected mode tests properly into the low 64K of the 128…
superfury Jun 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,15 @@ executed:
| ---- | ------------------------------------------------------------------ |
| 0x00 | Real mode initialisation |
| 0x01 | Conditional jumps and loops |
| 0x1D | Flag instructions in real mode |
| 0x02 | Quick tests of unsigned 32-bit multiplication and division |
| 0x03 | Move segment registers in real mode |
| 0x04 | Store, move, scan, and compare string data in real mode |
| 0x05 | Calls in real mode |
| 0x06 | Load full pointer in real mode |
| 0x1E | Load and store GDTR and IDTR in real mode ** |
| 0x1F | XLAT in real mode ** |
| 0x07 | Interrupts in real mode ** |
| 0x08 | GDT, LDT, PDT, and PT setup, enter protected mode |
| 0x09 | Stack functionality * |
| 0x20 | Test user mode (ring 3) switching |
Expand Down
64 changes: 17 additions & 47 deletions src/protected_inth.asm
Original file line number Diff line number Diff line change
@@ -1,36 +1,3 @@
;
; Kernel mode interrupt handler
;
kernelInterrupt:
testCPL 0 ; Elevates to CPL 0
push ebx
push ecx
push ds
lds ebx, [cs:ptrTSSprot] ; Get the TSS
mov ecx, [ebx+4] ; Get TSS ESP0
sub ecx, 0x14+0xC ; Where we should end up on the kernel stack, taking into account what we just pushed
cmp esp, ecx ; Did the stack decrease correctly?
jne error
mov cx, ss
cmp cx, word [ebx+8] ; Did the stack pointer load correctly?
jne error
pop ds
pop ecx
mov bx, cs
cmp bx, C_SEG_PROT32 ; Did we end up in kernel mode correctly?
jne error
pop ebx
cmp dword [esp+0x00], kernelModeInterruptReturn
jne error ; Invalid return address
cmp dword [esp+0x04], CU_SEG_PROT32|3
jne error ; Invalid return code segment
; Ignore eflags
cmp dword [esp+0x0C], ESP_R3_PROT
jne error ; Invalid return ESP
cmp dword [esp+0x10], SU_SEG_PROT32|3
jne error ; Invalid user stack segment
iret ; Simply return to user mode

;
; Kernel mode interrupt handler
;
Expand All @@ -39,7 +6,7 @@ kernelInterrupt286:
push ebx
push ecx
push ds
lds ebx, [cs:ptrTSSprot] ; Get the TSS
lds ebx, [cs:ptrTSSprot_R0] ; Get the TSS
mov ecx, [ebx+4] ; Get TSS ESP0
sub ecx, 0x0A+0xC ; Where we should end up on the kernel stack, taking into account what we just pushed
cmp esp, ecx ; Did the stack decrease correctly?
Expand All @@ -50,12 +17,12 @@ kernelInterrupt286:
pop ds
pop ecx
mov bx, cs
cmp bx, C_SEG_PROT32 ; Did we end up in kernel mode correctly?
cmp bx, C_SEG_PROT32low ; Did we end up in kernel mode correctly?
jne error
pop ebx
cmp word [esp+0x00], kernelModeInterruptReturn286
jne error ; Invalid return address
cmp word [esp+0x02], CU_SEG_PROT32|3
cmp word [esp+0x02], CU_SEG_PROT32low|3
jne error ; Invalid return code segment
; Ignore eflags
cmp word [esp+0x06], ESP_R3_PROT
Expand Down Expand Up @@ -90,7 +57,7 @@ kernelInterruptRestoreKernelStack:
pop ebx
cmp dword [esp+0x00], kernelModeInterruptKernelStackReturn
jne error ; Invalid return address
cmp dword [esp+0x04], CU_SEG_PROT32|3
cmp dword [esp+0x04], CU_SEG_PROT32low|3
jne error ; Invalid return code segment
; Ignore eflags
cmp dword [esp+0x0C], ESP_R3_PROT
Expand All @@ -110,7 +77,7 @@ kernelOnlyInterrupt:
push ebx
push ds
push ecx
lds ebx, [cs:ptrTSSprot] ; Get the TSS
lds ebx, [cs:ptrTSSprot_R0] ; Get the TSS
mov ecx, eax ; Get ESP for the kernel mode program (stored into eax)
sub ecx, 0xC+0xC ; Where we should end up on the kernel stack, taking into account what we just pushed
cmp esp, ecx ; Did the stack decrease correctly?
Expand All @@ -121,13 +88,13 @@ kernelOnlyInterrupt:
jne error
pop ecx
mov bx, cs
cmp bx, C_SEG_PROT32 ; Did we arrive at proper kernel code?
cmp bx, C_SEG_PROT32low ; Did we arrive at proper kernel code?
jne error
pop ds
pop ebx
cmp dword [esp+0x00], kernelModeOnlyInterruptReturn
jne error ; Invalid return address
cmp dword [esp+0x04],C_SEG_PROT32
cmp dword [esp+0x04],C_SEG_PROT32low
jne error ; Invalid return code segment
; Ignore eflags
iret ; Simply return to kernel mode
Expand All @@ -150,12 +117,12 @@ kernelConformingInterrupt:
jne error
pop ecx
mov bx, cs
cmp bx, CC_SEG_PROT32|3 ; Did we arrive at proper conforming code?
cmp bx, CC_SEG_PROT32low|3 ; Did we arrive at proper conforming code?
jne error
pop ebx
cmp dword [esp+0x00], kernelConformingInterruptReturn
jne error ; Invalid return address
cmp dword [esp+0x04], CU_SEG_PROT32|3
cmp dword [esp+0x04], CU_SEG_PROT32low|3
jne error ; Invalid return code segment
; Ignore eflags
iret ; Simply return to user mode, stays at CPL 3
Expand All @@ -171,7 +138,7 @@ kernelOnlyConformingInterrupt:
push ebx
push ds
push ecx
lds ebx, [cs:ptrTSSprot] ; Get the TSS
lds ebx, [cs:ptrTSSprot_R0] ; Get the TSS
mov ecx, eax ; Get ESP for the kernel mode program (stored into eax)
sub ecx, 0xC+0xC ; Where we should end up on the kernel stack, taking into account what we just pushed
cmp esp, ecx ; Did the stack decrease correctly?
Expand All @@ -182,13 +149,13 @@ kernelOnlyConformingInterrupt:
jne error
pop ecx
mov bx, cs
cmp bx, CC_SEG_PROT32 ; Did we arrive at proper conforming kernel code?
cmp bx, CC_SEG_PROT32low ; Did we arrive at proper conforming kernel code?
jne error
pop ds
pop ebx
cmp dword [esp+0x00], kernelOnlyConformingInterruptReturn
jne error ; Invalid return address
cmp dword [esp+0x04],C_SEG_PROT32
cmp dword [esp+0x04],C_SEG_PROT32low
jne error ; Invalid return code segment
; Ignore eflags
iret ; Simply return to kernel mode
Expand All @@ -211,12 +178,12 @@ userModeInterrupt:
jne error
pop ecx
mov bx, cs
cmp bx, CU_SEG_PROT32|3 ; Did we arrive at proper user mode code?
cmp bx, CU_SEG_PROT32low|3 ; Did we arrive at proper user mode code?
jne error
pop ebx
cmp dword [esp+0x00], userInterruptReturn
jne error ; Invalid return address
cmp dword [esp+0x04],CU_SEG_PROT32|3
cmp dword [esp+0x04],CU_SEG_PROT32low|3
jne error ; Invalid return code segment
; Ignore eflags
iret ; Simply return to caller, stays as user mode.
Expand All @@ -239,3 +206,6 @@ kernelInterrupt_validateIsV86mode:
test dword [esp+8],0x20000 ;V86 bit set?
jz error ;V86 bit not properly set?
iret

DefaultExcHandlerLow:
jmp C_SEG_PROT32:DefaultExcHandler
Loading