1
0
bifurqué depuis xt-sys/exectos

46 Révisions

Auteur SHA1 Message Date
a0b0938099 Remove unused header 2026-03-27 22:07:20 +01:00
32d3672a51 Generate distinct handlers for CPU traps and hardware interrupts 2026-03-27 20:42:41 +01:00
0c17337388 Fix symbol naming convention for i686 trap handlers 2026-03-27 19:23:37 +01:00
9c449bed43 Initialize IDT with specific trap handlers for each vector 2026-03-27 19:16:16 +01:00
a64aa83eb8 Provide implementation for HL::Irq 2026-03-27 13:00:13 +01:00
64b5de98c8 Move IRQ handling from kernel executive to hardware layer 2026-03-27 12:00:09 +01:00
9b19bc94b3 Replace manual IDT manipulation with SetIdtGate function call 2026-03-26 23:10:00 +01:00
9479f3d364 Implement APIC presence check and panic if unsupported 2026-03-25 22:52:58 +01:00
576a2b7f1b Enhance kernel panic output 2026-03-25 14:59:40 +01:00
916d124c9b Separate synchronization guards from spinlock implementation 2026-03-21 22:44:00 +01:00
140af4278e Fix uninitialized member in SpinLockGuard 2026-03-21 18:29:19 +01:00
d401ac4540 Remove redundant comments from panic calls 2026-03-16 09:55:26 +01:00
0fed593147 Ensure SS and RSP are saved in trap frame 2026-03-15 17:32:01 +01:00
6cdb66cbb3 Ensure SS and ESP are saved in trap frame 2026-03-15 00:33:09 +01:00
428928c7e1 Simplify panic interface by using C++ overloading 2026-03-13 19:42:03 +01:00
7144242613 Maintain sequence counter 2026-02-24 17:40:45 +01:00
7e62919c6b Rework singly linked list API 2026-02-24 14:49:56 +01:00
2bbc21b667 Implement singly linked list support 2026-02-22 12:25:51 +01:00
70d758ec5b Improve comments 2026-02-22 12:21:43 +01:00
d1553ff84a Add SHA-1 hashing support 2026-02-19 18:49:29 +01:00
94a8917c5c Revert RTL::LinkedList::RemoveEntryList() routine signature and extend RTL::LinkedList API 2026-02-16 15:43:00 +01:00
2af94a1c3b Use RTL::LinkedList::ListEmpty() routine to check if list is empty after removal 2026-02-11 19:15:57 +01:00
4b5188260f Fix build 2026-02-11 17:43:07 +01:00
47ec89a85e Forgotten to change signature in bootloader 2026-02-10 18:26:50 +01:00
edb40dd62b Change RTL::LinkedList::RemoveEntryList() routine signature 2026-02-10 18:24:26 +01:00
874d303f83 Update requirements 2025-12-26 10:39:55 +01:00
0120ba167f Introduce RAII helpers for runlevel transitions 2025-10-29 23:07:27 +01:00
4e9dc15501 Define VIRTUAL macro 2025-10-29 22:32:07 +01:00
164ff0c135 Expand spinlock queue levels 2025-10-28 08:35:34 +01:00
f538d035e2 Introduce global spinlock initialization and RAII guard classes 2025-10-27 20:48:44 +01:00
72b92f853e Use PTE base from PageMapInfo 2025-10-23 08:54:57 +02:00
00b04f5405 Refactor IDT gate setup to use explicit DPL and type fields 2025-10-18 18:29:49 +02:00
52afd31e77 Implement Stage2 loading in VBR code 2025-10-17 20:44:57 +02:00
7f06abf236 New message for unsupported CPUs 2025-10-17 09:18:49 +02:00
4f4df52d3d Include architecture-specific code in VBR 2025-10-17 09:12:54 +02:00
764fec4d75 Implement low-level CPU initialization support for i686 and AMD64 boot sectors 2025-10-17 09:05:24 +02:00
ca8a539c0e Change message labels naming convention 2025-10-17 08:58:41 +02:00
c206b443ed Move XTLDR image base definition to arch-specific config 2025-10-16 12:22:30 +02:00
b19b27a621 Build relocatable image to allow proper UEFI loading 2025-10-16 12:10:00 +02:00
56b81f5d73 Set fixed image base 2025-10-15 23:06:12 +02:00
1e99a3f4a9 Set fixed alignment and base address to allow execution under BIOS 2025-10-15 21:03:03 +02:00
0a71bc3995 Print fallback message in non-EFI environment 2025-10-15 20:55:16 +02:00
13a9d4c522 Introduce legacy VGA text mode support 2025-10-15 20:49:17 +02:00
9bf867af95 Propagate compile definitions to bootsector sources 2025-10-11 23:18:14 +02:00
a7be533521 Improve reliability and correctness of the PowerShell configure script (#21)
Co-authored-by: Pedro Valadés <perikiyoxd@gmail.com>
Co-committed-by: Pedro Valadés <perikiyoxd@gmail.com>
2025-10-10 20:18:05 +02:00
fdbe157c18 Fix CHS sector-by-sector read loop 2025-10-10 19:05:23 +02:00
56 fichiers modifiés avec 2392 ajouts et 507 suppressions

Voir le fichier

@@ -53,8 +53,9 @@ implement any environment subsystem to support applications that are strictly wr
* NT drivers compatibility layer
# Requirements
ExectOS is in very early development stage, thus its requirements have been not specified yet. However according to its
design, it requires a modern EFI enabled hardware. It is not possible currently to boot ExectOS on a legacy BIOS.
ExectOS is currently in a very early stage of development, so its specific requirements are not fully defined yet.
However, based on the current design, it requires modern EFI hardware. You cannot boot ExectOS on a legacy BIOS
right now, but there are plans to add BIOS support in the future.
# Source structure
| Directory | Description |

Voir le fichier

@@ -1,6 +1,8 @@
# XT Boot Sector
PROJECT(BOOTSECT)
add_definitions("-DARCH_ESP_SOURCE=\\\"${ARCH}/cpu.S\\\"")
# Compile boot sectors
compile_bootsector(mbrboot ${BOOTSECT_SOURCE_DIR}/mbrboot.S 0x7C00 Start)
compile_bootsector(espboot ${BOOTSECT_SOURCE_DIR}/espboot.S 0x7C00 Start)

144
boot/bootsect/amd64/cpu.S Fichier normal
Voir le fichier

@@ -0,0 +1,144 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: boot/bootsect/amd64/cpu.S
* DESCRIPTION: Low-level support for CPU initialization
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
BuildPageMap:
/* Generate page map for first 1GB of memory */
pushaw
pushw %es
cld
movw $(0x1000 / 16), %ax
movw %ax, %es
xorw %di, %di
movl $(0x2000 | 0x07), %eax
stosl
xorl %eax, %eax
movw $1021, %cx
rep stosl
movw $(0x2000 / 16), %ax
movw %ax, %es
xorw %di, %di
movl $(0x3000 | 0x07), %eax
stosl
xorl %eax, %eax
movw $1021, %cx
rep stosl
movw $(0x3000 / 16), %ax
movw %ax, %es
xorw %di, %di
movw $512, %cx
movl $0x00000083, %eax
.BuildPageMapLoop:
/* Identity map 512 pages of 2MB */
movl %eax, %es:(%di)
addl $2097152, %eax
addw $0x08, %di
loop .BuildPageMapLoop
popw %es
popaw
ret
InitializeCpu:
/* Check if CPU supports CPUID, long mode and PAE */
pushal
pushfl
popl %eax
movl %eax, %ebx
xorl $0x00200000, %eax
pushl %eax
popfl
pushfl
popl %eax
cmpl %ebx, %eax
je CpuUnsupported
movl $0x01, %eax
cpuid
testl $0x40, %edx
jz CpuUnsupported
movl $0x80000000, %eax
cpuid
cmpl $0x80000000, %eax
jbe CpuUnsupported
movl $0x80000001, %eax
cpuid
testl $0x20000000, %edx
jz CpuUnsupported
popal
call LoadGdt
ret
LoadGdt:
/* Load Global Descriptor Table */
lgdt .GdtPointer
ret
RunStage2:
/* Switch to long mode and pass control to Stage 2 */
call BuildPageMap
call ParseExecutableHeader
xorl %edx, %edx
pushl %edx
pushl %eax
cli
xorw %ax, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
movl %cr4, %eax
orl $0x00A0, %eax
movl %eax, %cr4
movl $0x00001000, %eax
movl %eax, %cr3
movl $0xC0000080, %ecx
rdmsr
orl $0x00000100, %eax
wrmsr
movl %cr0, %eax
orl $0x80000001, %eax
movl %eax, %cr0
ljmp $0x10, $.Stage2LongMode
.code64
.Stage2LongMode:
/* Set segments and stack, then jump to Stage 2 */
movw $0x18, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
xorw %ax, %ax
movw %ax, %fs
movw %ax, %gs
popq %rax
xorq %rbx, %rbx
xorq %rcx, %rcx
xorq %rdx, %rdx
xorq %rsi, %rsi
xorq %rdi, %rdi
xorq %rbp, %rbp
jmp *%rax
.code16
.GdtDescriptor:
/* Global Descriptor Table */
.quad 0x0000000000000000
.quad 0x0000000000000000
.quad 0x00AF9A000000FFFF
.quad 0x00CF92000000FFFF
.quad 0x00009E000000FFFF
.quad 0x000092000000FFFF
.quad 0x00CF9B000000FFFF
.GdtPointer:
/* Pointer to Global Descriptor Table */
.word .GdtPointer - .GdtDescriptor - 1
.long .GdtDescriptor
.Stage2FileName:
/* Name of Stage 2 executable file */
.ascii "BOOTX64 EFI"

Voir le fichier

@@ -121,15 +121,15 @@ VerifyBiosParameterBlock:
ja FsError
ReadExtraCode:
/* Read second VBR sector with extra boot code */
/* Read second VBR sector with extra boot code (3 sectors starting from sector 2) */
movl HiddenSectors - Start(%bp), %eax
addl $0x02, %eax
movw $0x01, %cx
movw $0x03, %cx
xorw %bx, %bx
movw %bx, %es
movw $0x7E00, %bx
call ReadSectors
jmp StartSectors
jmp StartExtraCode
ReadSectors:
/* Check for extended BIOS functions and use it only if available */
@@ -139,18 +139,22 @@ ReadSectors:
movw $0x55AA, %bx
movb DriveNumber - Start(%bp), %dl
int $0x13
jc ReadCHS
jc .ReadCHS
cmpw $0xAA55, %bx
jne ReadCHS
jne .ReadCHS
testb $0x01, %cl
jz ReadCHS
jz .ReadCHS
/* Verify drive size and determine whether to use CHS or LBA */
cmpl %edi, %eax
jnb ReadLBA
jnb .ReadLBA
ReadCHS:
.ReadCHS:
/* Read sectors using CHS */
popal
.CHSLoop:
/* Read sector by sector using CHS */
pushw %cx
pushal
xorl %edx, %edx
@@ -176,11 +180,11 @@ ReadCHS:
movw %es, %dx
addw $0x20, %dx
movw %dx, %es
loop ReadCHS
loop .CHSLoop
popw %es
ret
ReadLBA:
.ReadLBA:
/* Prepare DAP packet and read sectors using LBA */
popal
pushw %cx
@@ -209,19 +213,19 @@ ReadLBA:
movw %dx, %es
popw %bx
subw %si, %cx
jnz ReadLBA
jnz .ReadLBA
popw %es
ret
DiskError:
/* Display disk error message and reboot */
movw $msgDiskError, %si
movw $.MsgDiskError, %si
call Print
jmp Reboot
FsError:
/* Display FS error message and reboot */
movw $msgFsError, %si
movw $.MsgFsError, %si
call Print
jmp Reboot
@@ -229,48 +233,297 @@ Print:
/* Simple routine to print messages */
lodsb
orb %al, %al
jz DonePrint
jz .DonePrint
movb $0x0E, %ah
movw $0x07, %bx
int $0x10
jmp Print
DonePrint:
.DonePrint:
retw
Reboot:
/* Display a message, wait for a key press and reboot */
movw $msgAnyKey, %si
movw $.MsgAnyKey, %si
call Print
xorw %ax, %ax
int $0x16
int $0x19
msgAnyKey:
.ascii "Press any key to restart\r\n"
.MsgAnyKey:
.ascii "Press any key to restart...\r\n\0"
msgDiskError:
.ascii "Disk error\r\n"
.MsgDiskError:
.ascii "Disk error!\r\n\0"
msgFsError:
.ascii "File system error\r\n"
.MsgFsError:
.ascii "File system error!\r\n\0"
/* Fill the rest of the VBR with zeros and add VBR signature at the end */
.fill (510 - (. - Start)), 1, 0
.word 0xAA55
StartSectors:
/* Print message */
movw $msgUnavailable, %si
StartExtraCode:
/* Load XTLDR file from disk */
call LoadStage2
/* Enable A20 gate */
call EnableA20
/* Call architecture specific initialization code */
call InitializeCpu
/* Jump to Stage2 */
call RunStage2
Clear8042:
/* Clear 8042 PS/2 buffer */
nop
nop
nop
nop
inb $0x64, %al
cmpb $0xff, %al
je .Clear8042_Done
testb $0x02, %al
jnz Clear8042
.Clear8042_Done:
ret
EnableA20:
/* Enable A20 gate */
pushaw
call Clear8042
movb $0xD1, %al
outb %al, $0x64
call Clear8042
movb $0xDF, %al
outb %al, $0x60
call Clear8042
movb $0xFF, %al
outb %al, $0x64
call Clear8042
popaw
ret
FindFatEntry:
/* Find a file or directory in the FAT table */
pushw %bx
pushw %cx
pushw %dx
pushw %si
pushw %di
.FindFatCluster:
/* Find FAT32 cluster holding the entry */
cmp $0x0FFFFFF8, %eax
jae .FindEntryFail
pushl %eax
movw $0x0200, %bx
movw %bx, %es
call ReadCluster
popl %eax
movb SectorsPerCluster - Start(%bp), %cl
shlw $0x04, %cx
xorw %di, %di
.FindEntryLoop:
/* Find the entry */
movb %es:(%di), %al
cmpb $0x00, %al
je .FindEntryFail
cmpb $0xE5, %al
je .FindSkipEntry
movb %es:0x0B(%di), %ah
cmpb $0x0F, %ah
je .FindSkipEntry
pushw %di
pushw %si
pushw %cx
movw $0x0B, %cx
repe cmpsb
popw %cx
popw %si
popw %di
jnz .FindSkipEntry
movw %es:0x1A(%di), %ax
movw %es:0x14(%di), %dx
shll $0x10, %edx
orl %edx, %eax
clc
jmp .FindEntryDone
.FindSkipEntry:
/* Skip to the next entry */
addw $0x20, %di
decw %cx
jnz .FindEntryLoop
call GetFatEntry
jmp .FindFatCluster
.FindEntryFail:
/* Error, file/directory not found */
stc
.FindEntryDone:
/* Clean up the stack */
popw %di
popw %si
popw %dx
popw %cx
popw %bx
ret
GetFatEntry:
/* Get FAT32 sector and offset from FAT table */
shll $0x02, %eax
movl %eax, %ecx
xorl %edx, %edx
movzwl BytesPerSector - Start(%bp), %ebx
pushl %ebx
divl %ebx
movzwl ReservedSectors - Start(%bp), %ebx
addl %ebx, %eax
movl HiddenSectors - Start(%bp), %ebx
addl %ebx, %eax
popl %ebx
decl %ebx
andl %ebx, %ecx
movzwl ExtendedFlags - Start(%bp), %ebx
andw $0x0F, %bx
jz LoadFatSector
cmpb FatCopies - Start(%bp), %bl
jae FsError
pushl %eax
movl BigSectorsPerFat - Start(%bp), %eax
mull %ebx
popl %edx
addl %edx, %eax
LoadFatSector:
/* Load FAT32 sector from disk */
pushl %ecx
movw $0x9000, %bx
movw %bx, %es
cmpl %esi, %eax
je .LoadFatSectorDone
movl %eax, %esi
xorw %bx, %bx
movw $0x01, %cx
call ReadSectors
.LoadFatSectorDone:
/* Clean up the stack */
popl %ecx
movl %es:(%ecx), %eax
andl $0x0FFFFFFF, %eax
ret
LoadStage2:
/* Load Stage2 executable, first find file in the path */
movl $0xFFFFFFFF, %esi
pushl %esi
movl 0x7C2C, %eax
movw $.EfiDirName, %si
call FindFatEntry
jc Stage2NotLoaded
movw $.BootDirName, %si
call FindFatEntry
jc Stage2NotLoaded
movw $.Stage2FileName, %si
call FindFatEntry
jc Stage2NotLoaded
popl %esi
/* Load XTLDR file from disk */
cmpl $0x02, %eax
jb FileNotFound
cmpl $0x0FFFFFF8, %eax
jae FileNotFound
movw $(0xF800 / 16), %bx
movw %bx, %es
.LoadStage2Loop:
/* Load file data from disk */
pushl %eax
xorw %bx, %bx
pushw %es
call ReadCluster
popw %es
xorw %bx, %bx
movb SectorsPerCluster - Start(%bp), %bl
shlw $0x05, %bx
movw %es, %ax
addw %bx, %ax
movw %ax, %es
popl %eax
pushw %es
call GetFatEntry
popw %es
cmpl $0x0FFFFFF8, %eax
jb .LoadStage2Loop
ret
ParseExecutableHeader:
/* Parse Stage2 PE/COFF executable header */
pushw %es
movw $(0xF800 / 16), %ax
movw %ax, %es
movl %es:60, %eax
addl $(4 + 20), %eax
movl %es:16(%eax), %eax
addl $0xF800, %eax
popw %es
ret
ReadCluster:
/* Read FAT32 cluster from disk */
decl %eax
decl %eax
xorl %edx, %edx
movzbl SectorsPerCluster - Start(%bp), %ebx
mull %ebx
pushl %eax
xorl %edx, %edx
movzbl FatCopies - Start(%bp), %eax
mull BigSectorsPerFat - Start(%bp)
movzwl ReservedSectors - Start(%bp), %ebx
addl %ebx, %eax
addl HiddenSectors - Start(%bp), %eax
popl %ebx
addl %ebx, %eax
xorw %bx, %bx
movzbw SectorsPerCluster - Start(%bp), %cx
call ReadSectors
ret
/* Include architecture specific code */
.include ARCH_ESP_SOURCE
CpuUnsupported:
/* Display CPU unsupported message and reboot */
popal
movw $.MsgCpuUnsupported, %si
call Print
jmp Reboot
/* Wait for key press and reboot */
xorw %ax, %ax
int $0x16
int $0x19
FileNotFound:
/* Display XTLDR not found message and reboot */
movw $.MsgXtLdrNotFound, %si
call Print
jmp Reboot
msgUnavailable:
.ascii "XTLDR requires EFI-based system!\r\nPress any key to restart\r\n"
Stage2NotLoaded:
/* Clean up the stack and display XTLDR not found message and reboot */
popl %esi
jmp FileNotFound
/* Fill the rest of the extra VBR with zeros */
.fill (1024 - (. - Start)), 1, 0
.BootDirName:
/* Boot directory name */
.ascii "BOOT "
.EfiDirName:
/* EFI directory name */
.ascii "EFI "
.MsgCpuUnsupported:
.ascii "CPU not supported!\r\n\0"
.MsgXtLdrNotFound:
.ascii "XTLDR Stage2 not found!\r\n\0"
/* Fill the rest of the extra VBR with zeros and add signature */
.fill (2043 - (. - Start)), 1, 0
.ascii "XTLDR"

124
boot/bootsect/i686/cpu.S Fichier normal
Voir le fichier

@@ -0,0 +1,124 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: boot/bootsect/i686/cpu.S
* DESCRIPTION: Low-level support for CPU initialization
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
BuildPageMap:
/* Generate page map for first 16MB of memory */
pushaw
pushw %es
cld
movw $(0x1000 >> 0x04), %ax
movw %ax, %es
xorw %di, %di
movl $(0x2000 | 0x03), %eax
stosl
movl $(0x3000 | 0x03), %eax
stosl
movl $(0x4000 | 0x03), %eax
stosl
movl $(0x5000 | 0x03), %eax
stosl
xorl %eax, %eax
movw $(1024 - 4), %cx
rep stosl
movl $0x00000003, %eax
movl $4, %edx
movw $(0x2000 >> 0x04), %bx
.BuildPageMapLoop:
/* Identity map 1024 pages of 4KB */
movw %bx, %es
xorw %di, %di
pushl %edx
movw $1024, %cx
.FillPageMapTable:
/* Fill the page table */
movl %eax, %es:(%di)
addl $4096, %eax
addw $0x04, %di
loop .FillPageMapTable
popl %edx
addw $(0x1000 >> 0x04), %bx
decl %edx
jnz .BuildPageMapLoop
popw %es
popaw
ret
InitializeCpu:
/* Check if CPU supports CPUID */
pushal
pushfl
popl %eax
movl %eax, %ebx
xorl $0x00200000, %eax
pushl %eax
popfl
pushfl
popl %eax
cmpl %ebx, %eax
je CpuUnsupported
popal
call LoadGdt
ret
LoadGdt:
/* Load Global Descriptor Table */
lgdt .GdtPointer
ret
RunStage2:
/* Switch to protected mode and pass control to Stage 2 */
call BuildPageMap
call ParseExecutableHeader
pushl %eax
cli
movl %cr0, %eax
orl $0x01, %eax
movl %eax, %cr0
ljmp $0x08, $.Stage2ProtectedMode
.code32
.Stage2ProtectedMode:
/* Set segments and stack, then jump to Stage 2 */
movw $0x10, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
xorw %ax, %ax
movw %ax, %fs
movw %ax, %gs
popl %eax
xorl %ebx, %ebx
xorl %ecx, %ecx
xorl %edx, %edx
xorl %esi, %esi
xorl %edi, %edi
xorl %ebp, %ebp
movl $0x1000, %ebx
movl %ebx, %cr3
movl %cr0, %ebx
orl $0x80000000, %ebx
movl %ebx, %cr0
jmp *%eax
.code16
.GdtDescriptor:
/* Global Descriptor Table */
.quad 0x0000000000000000
.quad 0x00CF9A000000FFFF
.quad 0x00CF92000000FFFF
.quad 0x00009E000000FFFF
.quad 0x000092000000FFFF
.GdtPointer:
/* Pointer to Global Descriptor Table */
.word .GdtPointer - .GdtDescriptor - 1
.long .GdtDescriptor
.Stage2FileName:
/* Name of Stage 2 executable file */
.ascii "BOOTIA32EFI"

Voir le fichier

@@ -4,6 +4,7 @@
* FILE: boot/bootsect/amd64/mbrboot.S
* DESCRIPTION: XT Boot Loader MBR boot code
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <aiken@codingworkshop.eu.org>
*/
.text
@@ -41,7 +42,7 @@ RealStart:
movw %ax, %ss
/* Print welcome message */
leaw msgXtosBoot, %si
leaw .MsgXtosBoot, %si
call Print
/* Get BIOS boot drive and partition table offset */
@@ -90,19 +91,19 @@ PartitionFound:
InvalidSignature:
/* Invalid signature error */
leaw msgInvalidSignature, %si
leaw .MsgInvalidSignature, %si
call Print
jmp HaltSystem
PartitionNotFound:
/* Active partition not found error */
leaw msgPartitionNotFound, %si
leaw .MsgPartitionNotFound, %si
call Print
jmp HaltSystem
VbrReadFail:
/* VBR read failed error */
leaw msgVbrReadFail, %si
leaw .MsgVbrReadFail, %si
call Print
jmp HaltSystem
@@ -136,16 +137,16 @@ DonePrint:
/* Storage for the LBA start */
.long 0
msgInvalidSignature:
.MsgInvalidSignature:
.asciz "Invalid partition signature!"
msgPartitionNotFound:
.MsgPartitionNotFound:
.asciz "Bootable partition not found!"
msgVbrReadFail:
.MsgVbrReadFail:
.asciz "VBR read failed!"
msgXtosBoot:
.MsgXtosBoot:
.asciz "Starting XTOS boot loader...\r\n"
/* Fill the rest of the MBR with zeros and add MBR signature at the end */

Voir le fichier

@@ -16,6 +16,7 @@ list(APPEND LIBXTLDR_SOURCE
# Specify list of source code files
list(APPEND XTLDR_SOURCE
${XTLDR_SOURCE_DIR}/arch/${ARCH}/memory.cc
${XTLDR_SOURCE_DIR}/biosutil.cc
${XTLDR_SOURCE_DIR}/bootutil.cc
${XTLDR_SOURCE_DIR}/config.cc
${XTLDR_SOURCE_DIR}/console.cc
@@ -38,6 +39,9 @@ add_executable(xtldr ${XTLDR_SOURCE})
# Add linker libraries
target_link_libraries(xtldr libxtos)
# Add linker options
target_link_options(xtldr PRIVATE /ALIGN:512)
# Set proper binary name and install target
if(ARCH STREQUAL "i686")
set(BINARY_NAME "bootia32")
@@ -49,5 +53,6 @@ set_install_target(xtldr efi/boot)
# Set loader entrypoint and subsystem
set_entrypoint(xtldr "BlStartXtLoader")
set_imagebase(xtldr ${BASEADDRESS_XTLDR})
set_linker_map(xtldr TRUE)
set_subsystem(xtldr efi_application)

190
boot/xtldr/biosutil.cc Fichier normal
Voir le fichier

@@ -0,0 +1,190 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/biosutil.cc
* DESCRIPTION: Legacy BIOS support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#include <xtldr.hh>
/**
* Clears the entire screen and moves the cursor to the top-left corner.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::ClearScreen()
{
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
USHORT Blank;
UINT Index;
/* Set blank character */
Blank = (0x0F << 8) | L' ';
/* Fill the entire screen with blank characters */
for(Index = 0; Index < VgaWidth * VgaHeight; Index++)
{
VgaBuffer[Index] = Blank;
}
/* Reset cursor position to the top-left corner */
CursorX = 0;
CursorY = 0;
/* Update the hardware cursor position */
UpdateCursor();
}
/**
* Formats the input string and prints it out to the screen.
*
* @param Format
* The formatted string that is to be written to the output.
*
* @param ...
* Depending on the format string, this routine might expect a sequence of additional arguments.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::Print(IN PCWSTR Format,
IN ...)
{
RTL_PRINT_CONTEXT PrintContext;
VA_LIST Arguments;
/* Initialise the print contexts */
PrintContext.WriteWideCharacter = PutChar;
/* Initialise the va_list */
VA_START(Arguments, Format);
/* Format and print the string to the stdout */
RTL::WideString::FormatWideString(&PrintContext, (PWCHAR)Format, Arguments);
/* Clean up the va_list */
VA_END(Arguments);
}
/**
* Writes a single wide character to the screen using legacy BIOS VGA text mode.
*
* @param Character
* The wide character to be printed.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
XTSTATUS
BiosUtils::PutChar(IN WCHAR Character)
{
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
USHORT VgaCharacter;
/* Handle special characters */
if(Character == L'\n')
{
/* Move to the next line */
CursorX = 0;
CursorY++;
}
else if(Character == L'\r')
{
/* Move to the beginning of the current line */
CursorX = 0;
}
else
{
/* Print character and move cursor to the right */
VgaCharacter = (0x0F << 8) | (Character & 0xFF);
VgaBuffer[CursorY * VgaWidth + CursorX] = VgaCharacter;
CursorX++;
}
/* Handle moving to the next line if cursor is at the end of the line */
if(CursorX >= VgaWidth)
{
CursorX = 0;
CursorY++;
}
/* Handle scrolling if cursor is at the end of the screen */
if(CursorY >= VgaHeight)
{
ScrollScreen();
CursorY = VgaHeight - 1;
}
/* Update the hardware cursor position */
UpdateCursor();
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Scrolls the entire screen content up by one line and clears the last line.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::ScrollScreen()
{
VOLATILE PUSHORT VgaBuffer = (PUSHORT)0xB8000;
USHORT Blank;
UINT Index;
/* Set blank character */
Blank = (0x0F << 8) | L' ';
/* Move every line up by one */
for(Index = 0; Index < (VgaHeight - 1) * VgaWidth; Index++)
{
VgaBuffer[Index] = VgaBuffer[Index + VgaWidth];
}
/* Clear the last line */
for(Index = (VgaHeight - 1) * VgaWidth; Index < VgaHeight * VgaWidth; Index++)
{
VgaBuffer[Index] = Blank;
}
}
/**
* Updates the hardware cursor position on the screen.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BiosUtils::UpdateCursor()
{
USHORT Position;
/* Calculate cursor position */
Position = CursorY * VgaWidth + CursorX;
/* Send command to set the high byte of the cursor position */
HL::IoPort::WritePort8(0x3D4, 0x0E);
HL::IoPort::WritePort8(0x3D5, (UCHAR)((Position >> 8) & 0xFF));
/* Send command to set the low byte of the cursor position */
HL::IoPort::WritePort8(0x3D4, 0x0F);
HL::IoPort::WritePort8(0x3D5, (UCHAR)(Position & 0xFF));
}

Voir le fichier

@@ -10,6 +10,18 @@
#include <xtldr.hh>
/* Legacy BIOS cursor X position */
USHORT BiosUtils::CursorX = 0;
/* Legacy BIOS cursor Y position */
USHORT BiosUtils::CursorY = 0;
/* Legacy BIOS screen height */
CONST USHORT BiosUtils::VgaHeight = 25;
/* Legacy BIOS screen width */
CONST USHORT BiosUtils::VgaWidth = 80;
/* XT Boot Loader menu list */
PLIST_ENTRY Configuration::BootMenuList = NULLPTR;

Voir le fichier

@@ -15,6 +15,25 @@
#include <libxtos.hh>
class BiosUtils
{
private:
STATIC USHORT CursorX;
STATIC USHORT CursorY;
STATIC CONST USHORT VgaHeight;
STATIC CONST USHORT VgaWidth;
public:
STATIC XTCDECL VOID ClearScreen();
STATIC XTCDECL VOID Print(IN PCWSTR Format,
IN ...);
STATIC XTCDECL XTSTATUS PutChar(IN WCHAR Character);
private:
STATIC XTCDECL VOID ScrollScreen();
STATIC XTCDECL VOID UpdateCursor();
};
class BootUtils
{
public:

Voir le fichier

@@ -236,6 +236,15 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
PWCHAR Modules;
EFI_STATUS Status;
/* Check if system is EFI-based and provided parameters are valid */
if(ImageHandle == NULLPTR || SystemTable == NULLPTR)
{
/* Invalid parameters, print error message using BIOS calls and hang */
BiosUtils::ClearScreen();
BiosUtils::Print(L"XTLDR requires EFI-based system!");
for(;;);
}
/* Initialize XTLDR and */
XtLoader::InitializeBootLoader(ImageHandle, SystemTable);

Voir le fichier

@@ -1,2 +1,3 @@
# Set base addresses for all modules
set(BASEADDRESS_XTLDR 0x000000000000F800)
set(BASEADDRESS_XTOSKRNL 0x0000000140000000)

Voir le fichier

@@ -1,2 +1,3 @@
# Set base addresses for all modules
set(BASEADDRESS_XTLDR 0x0000F800)
set(BASEADDRESS_XTOSKRNL 0x00400000)

Voir le fichier

@@ -64,11 +64,17 @@ function(compile_bootsector NAME SOURCE BASEADDR ENTRYPOINT)
set(BINARY_NAME "${NAME}.bin")
set(OBJECT_NAME "${NAME}.obj")
get_directory_property(DEFS COMPILE_DEFINITIONS)
foreach(def ${DEFS})
list(APPEND ASM_DEFS "-D${def}")
endforeach()
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BINARY_NAME}
COMMAND ${CMAKE_ASM_COMPILER}
/nologo
--target=i386-none-elf
${ASM_DEFS}
-I${CMAKE_CURRENT_SOURCE_DIR}
/Fo${CMAKE_CURRENT_BINARY_DIR}/${OBJECT_NAME}
-c -- ${SOURCE}

Voir le fichier

@@ -272,11 +272,18 @@ typedef struct _KIDTENTRY
{
USHORT OffsetLow;
USHORT Selector;
USHORT IstIndex:3;
USHORT Reserved0:5;
USHORT Type:5;
USHORT Dpl:2;
USHORT Present:1;
union
{
struct
{
USHORT IstIndex:3;
USHORT Reserved0:5;
USHORT Type:5;
USHORT Dpl:2;
USHORT Present:1;
};
USHORT Access;
};
USHORT OffsetMiddle;
ULONG OffsetHigh;
ULONG Reserved1;

Voir le fichier

@@ -58,12 +58,6 @@
#define KIDT_ACCESS_RING0 0x00
#define KIDT_ACCESS_RING3 0x60
/* IDT gate types */
#define KIDT_TASK 0x05
#define KIDT_CALL 0x0C
#define KIDT_INTERRUPT 0x0E
#define KIDT_TRAP 0x0F
/* TSS Offsets */
#define KTSS_ESP0 0x04
#define KTSS_CR3 0x1C
@@ -284,7 +278,18 @@ typedef struct _KIDTENTRY
{
USHORT Offset;
USHORT Selector;
USHORT Access;
union
{
struct
{
UCHAR Reserved;
UCHAR Type:4;
UCHAR Flag:1;
UCHAR Dpl:2;
UCHAR Present:1;
};
USHORT Access;
};
USHORT ExtendedOffset;
} KIDTENTRY, *PKIDTENTRY;

Voir le fichier

@@ -150,21 +150,23 @@ typedef enum _KTHREAD_STATE
typedef enum _KSPIN_LOCK_QUEUE_LEVEL
{
DispatcherLock,
UnusedSpareLock,
ExpansionLock,
PfnLock,
SystemSpaceLock,
VacbLock,
MasterLock,
NonPagedPoolLock,
NonPagedAllocPoolLock,
IoCancelLock,
WorkQueueLock,
IoVpbLock,
IoDatabaseLock,
IoCompletionLock,
FsStructLock,
FileSystemLock,
AfdWorkQueueLock,
BcbLock,
MmNonPagedPoolLock,
NonPagedPoolLock,
ReservedSystemLock,
TimerTableLock,
MaximumLock
} KSPIN_LOCK_QUEUE_LEVEL, *PKSPIN_LOCK_QUEUE_LEVEL;

Voir le fichier

@@ -49,6 +49,10 @@
#define PFL_DIGIT_PRECISION 0x00002000
#define PFL_THOUSANDS_GROUPING 0x00004000
/* Cryptographic related definitions */
#define SHA1_BLOCK_SIZE 64
#define SHA1_DIGEST_SIZE 20
/* Runtime Library routine callbacks */
typedef XTSTATUS (*PWRITE_CHARACTER)(IN CHAR Character);
typedef XTSTATUS (*PWRITE_WIDE_CHARACTER)(IN WCHAR Character);
@@ -95,4 +99,12 @@ typedef struct _RTL_PRINT_FORMAT_PROPERTIES
LONG Flags;
} RTL_PRINT_FORMAT_PROPERTIES, *PRTL_PRINT_FORMAT_PROPERTIES;
/* Runtime Library SHA-1 context structure definition */
typedef struct _RTL_SHA1_CONTEXT
{
ULONG State[5];
ULONG Count[2];
UCHAR Buffer[SHA1_BLOCK_SIZE];
} RTL_SHA1_CONTEXT, *PRTL_SHA1_CONTEXT;
#endif /* __XTDK_RTLTYPES_H */

Voir le fichier

@@ -12,8 +12,9 @@
#ifdef __cplusplus
/* C++ definitions */
#define XTCLINK extern "C"
#define NULLPTR nullptr
#define VIRTUAL virtual
#define XTCLINK extern "C"
/* C++ boolean type */
typedef bool BOOLEAN, *PBOOLEAN;
@@ -24,8 +25,9 @@
typedef wchar_t wchar;
#else
/* C definitions */
#define XTCLINK
#define NULLPTR ((void *)0)
#define VIRTUAL
#define XTCLINK
/* C boolean type */
typedef enum _BOOLEAN

Voir le fichier

@@ -80,6 +80,10 @@
/* Macro that returns offset of the virtual address */
#define PAGE_OFFSET(VirtualAddress) ((ULONG)((ULONG_PTR)VirtualAddress & MM_PAGE_MASK))
/* Macros for bitwise rotating */
#define ROTATE_LEFT(Value, Count) ((Value << Count) | (Value >> (32 - Count)))
#define ROTATE_RIGHT(Value, Count) ((Value >> Count) | (Value << (32 - Count)))
/* Macro for rounding down */
#define ROUND_DOWN(Value, Alignment) ((Value) & ~((Alignment) - 1))
@@ -104,7 +108,7 @@
/* Variadic ABI functions */
typedef __builtin_va_list VA_LIST, *PVA_LIST;
#define VA_ARG(Marker, Type) ((sizeof (Type) < sizeof(UINT_PTR)) ? \
#define VA_ARG(Marker, Type) ((sizeof(Type) < sizeof(UINT_PTR)) ? \
(Type)(__builtin_va_arg(Marker, UINT_PTR)) : \
(Type)(__builtin_va_arg(Marker, Type)))
#define VA_COPY(Dest, Start) __builtin_va_copy(Dest, Start)

Voir le fichier

@@ -20,6 +20,7 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/cpu.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/pic.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/irq.cc
${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/runlevel.cc
${XTOSKRNL_SOURCE_DIR}/hl/acpi.cc
${XTOSKRNL_SOURCE_DIR}/hl/cport.cc
@@ -31,7 +32,6 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/kd/data.cc
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc
${XTOSKRNL_SOURCE_DIR}/kd/exports.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/proc.cc
@@ -71,6 +71,8 @@ list(APPEND XTOSKRNL_SOURCE
${XTOSKRNL_SOURCE_DIR}/rtl/llist.cc
${XTOSKRNL_SOURCE_DIR}/rtl/math.cc
${XTOSKRNL_SOURCE_DIR}/rtl/memory.cc
${XTOSKRNL_SOURCE_DIR}/rtl/sha1.cc
${XTOSKRNL_SOURCE_DIR}/rtl/slist.cc
${XTOSKRNL_SOURCE_DIR}/rtl/string.cc
${XTOSKRNL_SOURCE_DIR}/rtl/widestr.cc)

Voir le fichier

@@ -13,20 +13,29 @@
/**
* Creates a trap handler for the specified vector.
* Creates a trap or interrupt handler for the specified vector.
*
* @param Vector
* Supplies a trap vector number.
* Supplies a trap/interrupt vector number.
*
* @param Type
* Specifies whether the handler is designed to handle an interrupt or a trap.
*
* @return This macro does not return any value.
*
* @since XT 1.0
*/
.macro ArCreateTrapHandler Vector
.global ArTrap\Vector
ArTrap\Vector:
/* Push fake error code for non-error vectors */
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
.macro ArCreateTrapHandler Vector Type
.global Ar\Type\Vector
Ar\Type\Vector:
/* Check handler type */
.ifc \Type,Trap
/* Push fake error code for non-error vector traps */
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
push $0
.endif
.else
/* Push fake error code for interrupts */
push $0
.endif
@@ -104,24 +113,39 @@ ArTrap\Vector:
/* Test previous mode and swap GS if needed */
movl $0, TrapPreviousMode(%rbp)
mov %cs, %ax
and $1, %al
and $3, %al
mov %al, TrapPreviousMode(%rbp)
jz KernelMode$\Vector
jz KernelMode\Type\Vector
swapgs
jmp UserMode\Type\Vector
KernelMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
KernelMode\Type\Vector:
/* Save kernel stack pointer (SS:RSP) */
movl %ss, %eax
mov %eax, TrapSegSs(%rbp)
lea TRAP_FRAME_SIZE(%rbp), %rax
mov %rax, TrapRsp(%rbp)
UserMode\Type\Vector:
/* Push Frame Pointer and clear direction flag */
mov %rsp, %rcx
cld
call ArDispatchTrap
.ifc \Type,Trap
/* Pass to the trap dispatcher */
call ArDispatchTrap
.else
/* Pass to the interrupt dispatcher */
call ArDispatchTrap
.endif
/* Test previous mode and swapgs if needed */
testb $1, TrapPreviousMode(%rbp)
jz KernelModeReturn$\Vector
jz KernelModeReturn\Type\Vector
cli
swapgs
KernelModeReturn$\Vector:
KernelModeReturn\Type\Vector:
/* Restore XMM registers */
movdqa TrapXmm0(%rbp), %xmm0
movdqa TrapXmm1(%rbp), %xmm1
@@ -173,9 +197,28 @@ KernelModeReturn$\Vector:
iretq
.endm
/* Populate common trap handlers */
/* Populate common interrupt and trap handlers */
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
ArCreateTrapHandler 0x\i\j
ArCreateTrapHandler 0x\i\j Interrupt
ArCreateTrapHandler 0x\i\j Trap
.endr
.endr
/* Define array of pointers to the interrupt handlers */
.global ArInterruptEntry
ArInterruptEntry:
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.quad ArInterrupt0x\i\j
.endr
.endr
/* Define array of pointers to the trap handlers */
.global ArTrapEntry
ArTrapEntry:
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.quad ArTrap0x\i\j
.endr
.endr

Voir le fichier

@@ -249,34 +249,35 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{
/* Set the IDT to handle unexpected interrupts */
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector], KGDT_R0_CODE,
KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
}
/* Setup IDT handlers for known interrupts and traps */
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrap0x1F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrap0x2F, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrap0xE1, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, KIDT_IST_MCA, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x1F, (PVOID)ArTrapEntry[0x1F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING3, AMD64_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2F, (PVOID)ArTrapEntry[0x2F], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0xE1, (PVOID)ArTrapEntry[0xE1], KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0, AMD64_INTERRUPT_GATE);
}
/**
@@ -636,6 +637,9 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
* @param Access
* Supplies the gate access rights.
*
* @param Type
* Supplies the gate type.
*
* @return This routine does not return any value.
*
* @since XT 1.0
@@ -647,15 +651,22 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access)
IN USHORT Dpl,
IN USHORT Type)
{
/* Setup the gate */
/* Set the handler's address */
Idt[Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
Idt[Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
Idt[Vector].Dpl = Access;
/* Set the code segment selector */
Idt[Vector].Selector = Selector;
/* Initialize the gate's attributes and flags */
Idt[Vector].Access = 0;
Idt[Vector].Dpl = Dpl;
Idt[Vector].IstIndex = Ist;
Idt[Vector].Present = 1;
Idt[Vector].Selector = Selector;
Idt[Vector].Type = 0xE;
Idt[Vector].Reserved1 = 0;
Idt[Vector].Type = Type;
}

Voir le fichier

@@ -13,20 +13,29 @@
/**
* This macro creates a trap handler for the specified vector.
* Creates a trap or interrupt handler for the specified vector.
*
* @param Vector
* Supplies a trap vector number.
* Supplies a trap/interrupt vector number.
*
* @param Type
* Specifies whether the handler is designed to handle an interrupt or a trap.
*
* @return This macro does not return any value.
*
* @since XT 1.0
*/
.macro ArCreateTrapHandler Vector
.global _ArTrap\Vector
_ArTrap\Vector:
/* Push fake error code for non-error vectors */
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
.macro ArCreateTrapHandler Vector Type
.global _Ar\Type\Vector
_Ar\Type\Vector:
/* Check handler type */
.ifc \Type,Trap
/* Push fake error code for non-error vector traps */
.if \Vector != 8 && \Vector != 10 && \Vector != 11 && \Vector != 12 && \Vector != 13 && \Vector != 14 && \Vector != 17 && \Vector != 30
push $0
.endif
.else
/* Push fake error code for interrupts */
push $0
.endif
@@ -75,31 +84,47 @@ _ArTrap\Vector:
/* Test previous mode and swap GS if needed */
movl $0, TrapPreviousMode(%ebp)
mov %cs, %ax
and $1, %al
and $3, %al
mov %al, TrapPreviousMode(%ebp)
jz KernelMode$\Vector
jz KernelMode\Type\Vector
swapgs
jmp UserMode\Type\Vector
KernelMode$\Vector:
/* Push Frame Pointer, clear direction flag and pass to trap dispatcher */
KernelMode\Type\Vector:
/* Save kernel stack pointer (SS:ESP) */
movl %ss, %eax
mov %eax, TrapSegSs(%ebp)
lea TrapEsp(%ebp), %eax
mov %eax, TrapEsp(%ebp)
UserMode\Type\Vector:
/* Push Frame Pointer and clear direction flag */
push %esp
cld
call _ArDispatchTrap
.ifc \Type,Trap
/* Pass to the trap dispatcher */
call _ArDispatchTrap
.else
/* Pass to the interrupt dispatcher */
call _ArDispatchTrap
.endif
/* Clean up the stack */
add $4, %esp
/* Test previous mode and swapgs if needed */
testb $1, TrapPreviousMode(%ebp)
jz KernelModeReturn$\Vector
jz KernelModeReturn\Type\Vector
cli
swapgs
KernelModeReturn$\Vector:
KernelModeReturn\Type\Vector:
/* Restore segment selectors */
mov TrapSegDs(%ebp), %ds
mov TrapSegEs(%ebp), %es
mov TrapSegFs(%ebp), %fs
mov TrapSegGs(%ebp), %gs
/* Free stack space */
add $(TRAP_FRAME_SIZE - TRAP_REGISTERS_SIZE), %esp
@@ -118,9 +143,28 @@ KernelModeReturn$\Vector:
iretl
.endm
/* Populate common trap handlers */
/* Populate common interrupt and trap handlers */
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
ArCreateTrapHandler 0x\i\j
ArCreateTrapHandler 0x\i\j Interrupt
ArCreateTrapHandler 0x\i\j Trap
.endr
.endr
/* Define array of pointers to the interrupt handlers */
.global _ArInterruptEntry
_ArInterruptEntry:
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.long _ArInterrupt0x\i\j
.endr
.endr
/* Define array of pointers to the trap handlers */
.global _ArTrapEntry
_ArTrapEntry:
.irp i,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.irp j,0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
.long _ArTrap0x\i\j
.endr
.endr

Voir le fichier

@@ -242,34 +242,35 @@ AR::ProcSup::InitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock)
for(Vector = 0; Vector < IDT_ENTRIES; Vector++)
{
/* Set the IDT to handle unexpected interrupts */
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArTrap0xFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, Vector, (PVOID)ArInterruptEntry[Vector],
KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
}
/* Setup IDT handlers for known interrupts and traps */
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrap0x00, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrap0x01, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrap0x02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrap0x03, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrap0x04, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrap0x05, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrap0x06, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrap0x07, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrap0x08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrap0x09, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrap0x0A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrap0x0B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrap0x0C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrap0x0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrap0x0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrap0x10, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrap0x11, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrap0x12, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrap0x13, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0);
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrap0x2A, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrap0x2B, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrap0x2C, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrap0x2D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrap0x2E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING3);
SetIdtGate(ProcessorBlock->IdtBase, 0x00, (PVOID)ArTrapEntry[0x00], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x01, (PVOID)ArTrapEntry[0x01], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x02, (PVOID)ArTrapEntry[0x02], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_INTERRUPT_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x03, (PVOID)ArTrapEntry[0x03], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x04, (PVOID)ArTrapEntry[0x04], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x05, (PVOID)ArTrapEntry[0x05], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x06, (PVOID)ArTrapEntry[0x06], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x07, (PVOID)ArTrapEntry[0x07], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x08, (PVOID)ArTrapEntry[0x08], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x09, (PVOID)ArTrapEntry[0x09], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0A, (PVOID)ArTrapEntry[0x0A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0B, (PVOID)ArTrapEntry[0x0B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0C, (PVOID)ArTrapEntry[0x0C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0D, (PVOID)ArTrapEntry[0x0D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x0E, (PVOID)ArTrapEntry[0x0E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x10, (PVOID)ArTrapEntry[0x10], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x11, (PVOID)ArTrapEntry[0x11], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x12, (PVOID)ArTrapEntry[0x12], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x13, (PVOID)ArTrapEntry[0x13], KGDT_R0_CODE, 0, KIDT_ACCESS_RING0, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2A, (PVOID)ArTrapEntry[0x2A], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2B, (PVOID)ArTrapEntry[0x2B], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2C, (PVOID)ArTrapEntry[0x2C], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2D, (PVOID)ArTrapEntry[0x2D], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
SetIdtGate(ProcessorBlock->IdtBase, 0x2E, (PVOID)ArTrapEntry[0x2E], KGDT_R0_CODE, 0, KIDT_ACCESS_RING3, I686_TRAP_GATE);
}
/**
@@ -506,7 +507,7 @@ AR::ProcSup::SetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
Tss->CR3 = CpuFunc::ReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = PtrToUlong(ArTrap0x08);
Tss->Eip = PtrToUlong(ArTrapEntry[0x08]);
Tss->Cs = KGDT_R0_CODE;
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
Tss->Es = KGDT_R3_DATA | RPL_MASK;
@@ -656,6 +657,9 @@ AR::ProcSup::SetGdtEntryBase(IN PKGDTENTRY Gdt,
* @param Access
* Supplies the gate access rights.
*
* @param Type
* Supplies the gate type.
*
* @return This routine does not return any value.
*
* @since XT 1.0
@@ -667,13 +671,21 @@ AR::ProcSup::SetIdtGate(IN PKIDTENTRY Idt,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access)
IN USHORT Dpl,
IN USHORT Type)
{
/* Setup the gate */
/* Set the handler's address */
Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
Idt[Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
Idt[Vector].Access = 0x8000 | (Access << 8);
/* Set the code segment selector */
Idt[Vector].Selector = Selector;
/* Initialize the gate's attributes and flags */
Idt[Vector].Access = 0;
Idt[Vector].Dpl = Dpl;
Idt[Vector].Present = 1;
Idt[Vector].Type = Type;
}
/**
@@ -709,7 +721,7 @@ AR::ProcSup::SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock
Tss->CR3 = CpuFunc::ReadControlRegister(3);
Tss->Esp = (ULONG_PTR)KernelFaultStack;
Tss->Esp0 = (ULONG_PTR)KernelFaultStack;
Tss->Eip = PtrToUlong(ArTrap0x02);
Tss->Eip = PtrToUlong(ArTrapEntry[0x02]);
Tss->Cs = KGDT_R0_CODE;
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
Tss->Es = KGDT_R3_DATA | RPL_MASK;

Voir le fichier

@@ -1,9 +1,10 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/i686/irq.cc
* DESCRIPTION: Kernel interrupts support for i686 architecture
* FILE: xtoskrnl/hl/amd64/irq.cc
* DESCRIPTION: Interrupts support for amd64 architecture
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
@@ -24,7 +25,7 @@
*/
XTAPI
VOID
KE::Irq::SetInterruptHandler(IN ULONG Vector,
HL::Irq::SetInterruptHandler(IN ULONG Vector,
IN PVOID Handler)
{
PKPROCESSOR_BLOCK ProcessorBlock;
@@ -33,6 +34,11 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector,
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler */
ProcessorBlock->IdtBase[(UCHAR) Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF);
ProcessorBlock->IdtBase[(UCHAR) Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16);
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
Vector,
Handler,
KGDT_R0_CODE,
0,
KIDT_ACCESS_RING0,
AMD64_INTERRUPT_GATE);
}

Voir le fichier

@@ -1,9 +1,10 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/ke/amd64/irq.cc
* DESCRIPTION: Kernel interrupts support for amd64 architecture
* FILE: xtoskrnl/hl/i686/irq.cc
* DESCRIPTION: Interrupts support for i686 architecture
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
@@ -24,7 +25,7 @@
*/
XTAPI
VOID
KE::Irq::SetInterruptHandler(IN ULONG Vector,
HL::Irq::SetInterruptHandler(IN ULONG Vector,
IN PVOID Handler)
{
PKPROCESSOR_BLOCK ProcessorBlock;
@@ -33,7 +34,11 @@ KE::Irq::SetInterruptHandler(IN ULONG Vector,
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
/* Update interrupt handler */
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetLow = ((ULONG_PTR)Handler & 0xFFFF);
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetMiddle = (((ULONG_PTR)Handler >> 16) & 0xFFFF);
ProcessorBlock->IdtBase[(UCHAR) Vector].OffsetHigh = (ULONG_PTR)Handler >> 32;
AR::ProcSup::SetIdtGate(ProcessorBlock->IdtBase,
Vector,
Handler,
KGDT_R0_CODE,
0,
KIDT_ACCESS_RING0,
I686_INTERRUPT_GATE);
}

Voir le fichier

@@ -9,6 +9,41 @@
#include <xtos.hh>
/**
* Checks whether the APIC is supported by the processor.
*
* @return This routine returns TRUE if APIC is supported, or FALSE otherwise.
*
* @since XT 1.0
*/
XTAPI
BOOLEAN
HL::Pic::CheckApicSupport(VOID)
{
CPUID_REGISTERS CpuRegisters;
/* Prepare CPUID registers */
CpuRegisters.Leaf = CPUID_GET_STANDARD1_FEATURES;
CpuRegisters.SubLeaf = 0;
CpuRegisters.Eax = 0;
CpuRegisters.Ebx = 0;
CpuRegisters.Ecx = 0;
CpuRegisters.Edx = 0;
/* Get CPUID */
AR::CpuFunc::CpuId(&CpuRegisters);
/* Check APIC status from the CPUID results */
if(!(CpuRegisters.Edx & CPUID_FEATURES_EDX_APIC))
{
/* APIC is not supported */
return FALSE;
}
/* APIC is supported */
return TRUE;
}
/**
* Checks whether the x2APIC extension is supported by the processor.
*
@@ -124,6 +159,14 @@ HL::Pic::InitializeApic(VOID)
APIC_LVT_REGISTER LvtRegister;
ULONG CpuNumber;
/* Check APIC support */
if(!CheckApicSupport())
{
/* APIC is not supported, raise kernel panic */
DebugPrint(L"FATAL ERROR: Local APIC not present.\n");
KE::Crash::Panic(0x5D, CPUID_GET_STANDARD1_FEATURES, 0x0, 0x0, CPUID_FEATURES_EDX_APIC);
}
/* Determine APIC mode (xAPIC compatibility or x2APIC) */
if(CheckX2ApicSupport())
{
@@ -206,8 +249,8 @@ HL::Pic::InitializeApic(VOID)
WriteApicRegister(APIC_LINT1, LvtRegister.Long);
/* Register interrupt handlers */
KE::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)HandleApicSpuriousService);
KE::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)HandlePicSpuriousService);
HL::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)HandleApicSpuriousService);
HL::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)HandlePicSpuriousService);
/* Clear any pre-existing errors */
WriteApicRegister(APIC_ESR, 0);

Voir le fichier

@@ -56,6 +56,8 @@
#define TrapSegEs 330
#define TrapSegFs 332
#define TrapSegGs 334
#define TrapRsp 496
#define TrapSegSs 504
/* KTRAP_FRAME length related definitions */
#define TRAP_FRAME_SIZE 512

Voir le fichier

@@ -15,9 +15,14 @@
/* TrampolineEnableXpa end address to calculate trampoline size */
XTCLINK PVOID ArEnableExtendedPhysicalAddressingEnd[];
/* External array of pointers to the interrupt handlers */
XTCLINK ULONG_PTR ArInterruptEntry[256];
/* TrampolineApStartup end address to calculate trampoline size */
XTCLINK PVOID ArStartApplicationProcessorEnd[];
/* External array of pointers to the trap handlers */
XTCLINK ULONG_PTR ArTrapEntry[256];
/* Forward reference for assembler code */
XTCLINK
@@ -30,129 +35,4 @@ XTCDECL
VOID
ArStartApplicationProcessor(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x00(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x01(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x02(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x03(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x04(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x05(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x06(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x07(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x08(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x09(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x10(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x11(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x12(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x13(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x1F(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2F(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xE1(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xFF(VOID);
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */

Voir le fichier

@@ -31,6 +31,13 @@ namespace AR
OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type);
private:
STATIC XTAPI VOID IdentifyProcessor(VOID);
@@ -62,12 +69,6 @@ namespace AR
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access);
};
}

Voir le fichier

@@ -24,9 +24,11 @@
#define TrapSegEs 38
#define TrapSegFs 40
#define TrapSegGs 42
#define TrapEsp 92
#define TrapSegSs 96
/* KTRAP_FRAME length related definitions */
#define TRAP_FRAME_SIZE 100
#define TRAP_REGISTERS_SIZE 56
#endif /* __XTOSKRNL_AMD64_ASMSUP_H */
#endif /* __XTOSKRNL_I686_ASMSUP_H */

Voir le fichier

@@ -12,9 +12,14 @@
#include <xtos.hh>
/* External array of pointers to the interrupt handlers */
XTCLINK ULONG_PTR ArInterruptEntry[256];
/* TrampolineApStartup end address to calculate trampoline size */
XTCLINK PVOID ArStartApplicationProcessorEnd[];
/* External array of pointers to the trap handlers */
XTCLINK ULONG_PTR ArTrapEntry[256];
/* Forward reference for assembler code */
XTCLINK
@@ -22,130 +27,4 @@ XTCDECL
VOID
ArStartApplicationProcessor(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x00(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x01(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x02(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x03(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x04(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x05(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x06(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x07(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x08(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x09(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x0E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x10(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x11(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x12(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x13(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2A(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2B(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2C(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2D(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0x2E(VOID);
XTCLINK
XTCDECL
VOID
ArTrap0xFF(VOID);
#endif /* __XTOSKRNL_AR_ASSEMBLY_HH */

Voir le fichier

@@ -34,6 +34,13 @@ namespace AR
OUT PVOID *TrampolineCode,
OUT PULONG_PTR TrampolineSize);
STATIC XTAPI VOID InitializeProcessor(IN PVOID ProcessorStructures);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Dpl,
IN USHORT Type);
private:
STATIC XTAPI VOID IdentifyProcessor(VOID);
@@ -67,12 +74,6 @@ namespace AR
STATIC XTAPI VOID SetGdtEntryBase(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONG_PTR Base);
STATIC XTAPI VOID SetIdtGate(IN PKIDTENTRY Idt,
IN USHORT Vector,
IN PVOID Handler,
IN USHORT Selector,
IN USHORT Ist,
IN USHORT Access);
STATIC XTAPI VOID SetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock,
IN PVOID KernelFaultStack);

Voir le fichier

@@ -18,6 +18,7 @@
#include <hl/init.hh>
#include <hl/ioport.hh>
#include <hl/ioreg.hh>
#include <hl/irq.hh>
#include <hl/pic.hh>
#include <hl/runlevel.hh>

Voir le fichier

@@ -1,19 +1,19 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/irq.hh
* DESCRIPTION: Kernel interrupts support
* FILE: xtoskrnl/includes/hl/irq.hh
* DESCRIPTION: Interrupts support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_IRQ_HH
#define __XTOSKRNL_KE_IRQ_HH
#ifndef __XTOSKRNL_HL_IRQ_HH
#define __XTOSKRNL_HL_IRQ_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
/* Hardware Layer */
namespace HL
{
class Irq
{
@@ -23,4 +23,4 @@ namespace KE
};
}
#endif /* __XTOSKRNL_KE_IRQ_HH */
#endif /* __XTOSKRNL_HL_IRQ_HH */

Voir le fichier

@@ -32,6 +32,7 @@ namespace HL
IN ULONGLONG Value);
private:
STATIC XTAPI BOOLEAN CheckApicSupport(VOID);
STATIC XTAPI BOOLEAN CheckX2ApicSupport(VOID);
STATIC XTCDECL VOID HandleApicSpuriousService(VOID);
STATIC XTCDECL VOID HandlePicSpuriousService(VOID);

Voir le fichier

@@ -16,7 +16,7 @@
#include <ke/crash.hh>
#include <ke/dpc.hh>
#include <ke/event.hh>
#include <ke/irq.hh>
#include <ke/guard.hh>
#include <ke/kprocess.hh>
#include <ke/krnlinit.hh>
#include <ke/kthread.hh>

Voir le fichier

@@ -20,11 +20,11 @@ namespace KE
public:
STATIC XTAPI VOID HaltSystem(VOID);
STATIC XTAPI VOID Panic(IN ULONG Code);
STATIC XTAPI VOID PanicEx(IN ULONG Code,
IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4);
STATIC XTAPI VOID Panic(IN ULONG Code,
IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4);
};
}

61
xtoskrnl/includes/ke/guard.hh Fichier normal
Voir le fichier

@@ -0,0 +1,61 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/guard.hh
* DESCRIPTION: Kernel synchronization guard
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_GUARD_HH
#define __XTOSKRNL_KE_GUARD_HH
#include <xtos.hh>
#include <ke/spinlock.hh>
/* Kernel Library */
namespace KE
{
class QueuedSpinLockGuard
{
private:
KSPIN_LOCK_QUEUE_LEVEL QueuedLockLevel;
public:
QueuedSpinLockGuard(IN OUT KSPIN_LOCK_QUEUE_LEVEL LockLevel)
{
QueuedLockLevel = LockLevel;
KE::SpinLock::AcquireQueuedSpinLock(QueuedLockLevel);
}
~QueuedSpinLockGuard()
{
KE::SpinLock::ReleaseQueuedSpinLock(QueuedLockLevel);
}
QueuedSpinLockGuard(const QueuedSpinLockGuard&) = delete;
QueuedSpinLockGuard& operator=(const QueuedSpinLockGuard&) = delete;
};
class SpinLockGuard
{
private:
PKSPIN_LOCK Lock;
public:
SpinLockGuard(IN OUT PKSPIN_LOCK SpinLock)
{
Lock = SpinLock;
KE::SpinLock::AcquireSpinLock(Lock);
}
~SpinLockGuard()
{
KE::SpinLock::ReleaseSpinLock(Lock);
}
SpinLockGuard(const SpinLockGuard&) = delete;
SpinLockGuard& operator=(const SpinLockGuard&) = delete;
};
}
#endif /* __XTOSKRNL_KE_GUARD_HH */

Voir le fichier

@@ -1,27 +0,0 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/ke/info.hh
* DESCRIPTION: Generic kernel information support
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
*/
#ifndef __XTOSKRNL_KE_INFO_HH
#define __XTOSKRNL_KE_INFO_HH
#include <xtos.hh>
/* Kernel Library */
namespace KE
{
class Info
{
public:
STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID);
STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName,
OUT PCWSTR *Parameter);
};
}
#endif /* __XTOSKRNL_KE_INFO_HH */

Voir le fichier

@@ -22,6 +22,48 @@ namespace KE
STATIC XTFASTCALL VOID LowerRunLevel(IN KRUNLEVEL RunLevel);
STATIC XTFASTCALL KRUNLEVEL RaiseRunLevel(IN KRUNLEVEL RunLevel);
};
class LowerRunLevel
{
private:
KRUNLEVEL PreviousRunLevel;
public:
LowerRunLevel(KRUNLEVEL RunLevel)
{
PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();
KE::RunLevel::LowerRunLevel(RunLevel);
}
~LowerRunLevel()
{
KE::RunLevel::RaiseRunLevel(PreviousRunLevel);
}
LowerRunLevel(const LowerRunLevel&) = delete;
LowerRunLevel& operator=(const LowerRunLevel&) = delete;
};
class RaiseRunLevel
{
private:
KRUNLEVEL PreviousRunLevel;
public:
RaiseRunLevel(KRUNLEVEL RunLevel)
{
PreviousRunLevel = KE::RunLevel::GetCurrentRunLevel();
KE::RunLevel::RaiseRunLevel(RunLevel);
}
~RaiseRunLevel()
{
KE::RunLevel::LowerRunLevel(PreviousRunLevel);
}
RaiseRunLevel(const RaiseRunLevel&) = delete;
RaiseRunLevel& operator=(const RaiseRunLevel&) = delete;
};
}
#endif /* __XTOSKRNL_KE_RUNLEVEL_HH */

Voir le fichier

@@ -17,12 +17,32 @@ namespace KE
{
class SpinLock
{
private:
STATIC KSPIN_LOCK DispatcherLockQueue;
STATIC KSPIN_LOCK ExpansionLockQueue;
STATIC KSPIN_LOCK FileSystemLockQueue;
STATIC KSPIN_LOCK IoCancelLockQueue;
STATIC KSPIN_LOCK IoCompletionLockQueue;
STATIC KSPIN_LOCK IoDatabaseLockQueue;
STATIC KSPIN_LOCK IoVpbLockQueue;
STATIC KSPIN_LOCK MasterLockQueue;
STATIC KSPIN_LOCK NonPagedAllocLockQueue;
STATIC KSPIN_LOCK NonPagedPoolLockQueue;
STATIC KSPIN_LOCK PfnLockQueue;
STATIC KSPIN_LOCK SystemSpaceLockQueue;
STATIC KSPIN_LOCK TimerTableLockQueue;
STATIC KSPIN_LOCK VacbLockQueue;
STATIC KSPIN_LOCK WorkLockQueue;
public:
STATIC XTFASTCALL VOID AcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
STATIC XTFASTCALL VOID AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock);
STATIC XTAPI VOID InitializeAllLocks();
STATIC XTAPI VOID InitializeLockQueues();
STATIC XTAPI VOID InitializeSpinLock(IN PKSPIN_LOCK SpinLock);
STATIC XTFASTCALL VOID ReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_LEVEL LockLevel);
STATIC XTFASTCALL VOID ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock);
STATIC XTFASTCALL BOOLEAN TestSpinLock(IN PKSPIN_LOCK SpinLock);
};
}

Voir le fichier

@@ -19,6 +19,8 @@
#include <rtl/llist.hh>
#include <rtl/math.hh>
#include <rtl/memory.hh>
#include <rtl/sha1.hh>
#include <rtl/slist.hh>
#include <rtl/string.hh>
#include <rtl/widestr.hh>

Voir le fichier

@@ -4,6 +4,7 @@
* FILE: xtoskrnl/includes/rtl/llist.hh
* DESCRIPTION: Linked list manipulation routines
* DEVELOPERS: Aiken Harris <harraiken91@gmail.com>
* Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_RTL_LLIST_HH
@@ -18,6 +19,7 @@ namespace RTL
class LinkedList
{
public:
STATIC XTCDECL PLIST_ENTRY GetFirstEntry(IN PLIST_ENTRY ListHead);
STATIC XTCDECL VOID InitializeListHead(IN PLIST_ENTRY ListHead);
STATIC XTCDECL VOID InitializeListHead32(IN PLIST_ENTRY32 ListHead);
STATIC XTCDECL VOID InsertHeadList(IN OUT PLIST_ENTRY ListHead,
@@ -27,6 +29,10 @@ namespace RTL
STATIC XTCDECL BOOLEAN ListEmpty(IN PLIST_ENTRY ListHead);
STATIC XTCDECL BOOLEAN ListLoop(IN PLIST_ENTRY ListHead);
STATIC XTCDECL VOID RemoveEntryList(IN PLIST_ENTRY Entry);
STATIC XTCDECL VOID SpliceHeadList(IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY SpliceList);
STATIC XTCDECL VOID SpliceTailList(IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY SpliceList);
};
}

37
xtoskrnl/includes/rtl/sha1.hh Fichier normal
Voir le fichier

@@ -0,0 +1,37 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/rtl/sha1.hh
* DESCRIPTION: SHA1 computation support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_RTL_SHA1_HH
#define __XTOSKRNL_RTL_SHA1_HH
#include <xtos.hh>
/* Runtime Library */
namespace RTL
{
class SHA1
{
public:
STATIC XTAPI XTSTATUS ComputeDigest(IN PCUCHAR Buffer,
IN SIZE_T BufferSize,
OUT PUCHAR Digest);
private:
STATIC XTAPI VOID ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,
OUT PUCHAR Digest);
STATIC XTAPI VOID HashData(IN OUT PRTL_SHA1_CONTEXT Context,
IN PCUCHAR Data,
IN ULONG Length);
STATIC XTAPI XTSTATUS InitializeContext(OUT PRTL_SHA1_CONTEXT Context);
STATIC XTAPI VOID TransformData(IN OUT PULONG State,
IN PCUCHAR Buffer);
};
}
#endif /* __XTOSKRNL_RTL_SHA1_HH */

39
xtoskrnl/includes/rtl/slist.hh Fichier normal
Voir le fichier

@@ -0,0 +1,39 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/includes/rtl/slist.hh
* DESCRIPTION: Singly linked list manipulation routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#ifndef __XTOSKRNL_RTL_SLIST_HH
#define __XTOSKRNL_RTL_SLIST_HH
#include <xtos.hh>
/* Runtime Library */
namespace RTL
{
class SinglyList
{
public:
STATIC XTCDECL PSINGLE_LIST_ENTRY GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTCDECL VOID InitializeListHead(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTCDECL PSINGLE_LIST_ENTRY InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry);
STATIC XTCDECL PSINGLE_LIST_ENTRY InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry);
STATIC XTCDECL BOOLEAN ListEmpty(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTAPI USHORT QueryListDepth(IN PSINGLE_LIST_HEADER ListHead);
STATIC XTCDECL VOID RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry);
STATIC XTCDECL PSINGLE_LIST_ENTRY SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN OUT PSINGLE_LIST_HEADER SpliceList);
STATIC XTCDECL PSINGLE_LIST_ENTRY SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN OUT PSINGLE_LIST_HEADER SpliceList);
STATIC XTCDECL PSINGLE_LIST_ENTRY TakeFirstEntry(IN PSINGLE_LIST_HEADER ListHead);
};
}
#endif /* __XTOSKRNL_RTL_SLIST_HH */

Voir le fichier

@@ -43,7 +43,7 @@ XTAPI
VOID
KE::Crash::Panic(IN ULONG Code)
{
PanicEx(Code, 0, 0, 0, 0);
Panic(Code, 0, 0, 0, 0);
}
/**
@@ -70,12 +70,13 @@ KE::Crash::Panic(IN ULONG Code)
*/
XTAPI
VOID
KE::Crash::PanicEx(IN ULONG Code,
IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4)
KE::Crash::Panic(IN ULONG Code,
IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2,
IN ULONG_PTR Parameter3,
IN ULONG_PTR Parameter4)
{
KD::DebugIo::KdPrint(L"Fatal System Error: 0x%08lx\nKernel Panic!\n\n", Code);
KD::DebugIo::KdPrint(L"Fatal System Error: 0x%08lx (0x%zx 0x%zx 0x%zx 0x%zx)\nKernel Panic!\n\n",
Code, Parameter1, Parameter2, Parameter3, Parameter4);
HaltSystem();
}

Voir le fichier

@@ -12,12 +12,6 @@
/* Kernel initialization block passed by boot loader */
PKERNEL_INITIALIZATION_BLOCK KE::BootInformation::InitializationBlock = {};
/* Kernel boot resources list */
LIST_ENTRY KE::SystemResources::ResourcesListHead;
/* Kernel boot resources lock */
KSPIN_LOCK KE::SystemResources::ResourcesLock;
/* Kernel initial process */
EPROCESS KE::KProcess::InitialProcess;
@@ -26,3 +20,54 @@ ETHREAD KE::KThread::InitialThread = {};
/* Kernel UBSAN active frame flag */
BOOLEAN KE::KUbsan::ActiveFrame = FALSE;
/* Kernel dispatcher lock queue */
KSPIN_LOCK KE::SpinLock::DispatcherLockQueue;
/* Kernel expansion lock queue */
KSPIN_LOCK KE::SpinLock::ExpansionLockQueue;
/* Kernel file system structures lock queue */
KSPIN_LOCK KE::SpinLock::FileSystemLockQueue;
/* Kernel IO cancel lock queue */
KSPIN_LOCK KE::SpinLock::IoCancelLockQueue;
/* Kernel IO completion lock queue */
KSPIN_LOCK KE::SpinLock::IoCompletionLockQueue;
/* Kernel IO database lock queue */
KSPIN_LOCK KE::SpinLock::IoDatabaseLockQueue;
/* Kernel IO VPB lock queue */
KSPIN_LOCK KE::SpinLock::IoVpbLockQueue;
/* Kernel cache master lock queue */
KSPIN_LOCK KE::SpinLock::MasterLockQueue;
/* Kernel non-paged allocator lock queue */
KSPIN_LOCK KE::SpinLock::NonPagedAllocLockQueue;
/* Kernel non-paged pool lock queue */
KSPIN_LOCK KE::SpinLock::NonPagedPoolLockQueue;
/* Kernel PFN lock queue */
KSPIN_LOCK KE::SpinLock::PfnLockQueue;
/* Kernel system space lock queue */
KSPIN_LOCK KE::SpinLock::SystemSpaceLockQueue;
/* Kernel Timer table lock queue */
KSPIN_LOCK KE::SpinLock::TimerTableLockQueue;
/* Kernel VACB lock queue */
KSPIN_LOCK KE::SpinLock::VacbLockQueue;
/* Kernel work queue lock queue */
KSPIN_LOCK KE::SpinLock::WorkLockQueue;
/* Kernel boot resources list */
LIST_ENTRY KE::SystemResources::ResourcesListHead;
/* Kernel boot resources lock */
KSPIN_LOCK KE::SystemResources::ResourcesLock;

Voir le fichier

@@ -4,6 +4,7 @@
* FILE: xtoskrnl/ke/spinlock.cc
* DESCRIPTION: Spinlocks support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
* Aiken Harris <harraiken91@gmail.com>
*/
#include <xtos.hh>
@@ -56,6 +57,78 @@ KE::SpinLock::AcquireSpinLock(IN OUT PKSPIN_LOCK SpinLock)
AR::CpuFunc::ReadWriteBarrier();
}
/**
* Initializes all kernel spinlocks.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KE::SpinLock::InitializeAllLocks()
{
/* Initialize all spin locks */
InitializeSpinLock(&DispatcherLockQueue);
InitializeSpinLock(&PfnLockQueue);
InitializeSpinLock(&SystemSpaceLockQueue);
}
/**
* Initializes spinlock queues for current processor.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KE::SpinLock::InitializeLockQueues()
{
PKPROCESSOR_CONTROL_BLOCK ControlBlock;
/* Get current processor control block */
ControlBlock = KE::Processor::GetCurrentProcessorControlBlock();
/* Initialize PCB lock queues */
ControlBlock->LockQueue[DispatcherLock].Lock = &DispatcherLockQueue;
ControlBlock->LockQueue[DispatcherLock].Next = NULLPTR;
ControlBlock->LockQueue[ExpansionLock].Lock = &ExpansionLockQueue;
ControlBlock->LockQueue[ExpansionLock].Next = NULLPTR;
ControlBlock->LockQueue[PfnLock].Lock = &PfnLockQueue;
ControlBlock->LockQueue[PfnLock].Next = NULLPTR;
ControlBlock->LockQueue[SystemSpaceLock].Lock = &SystemSpaceLockQueue;
ControlBlock->LockQueue[SystemSpaceLock].Next = NULLPTR;
ControlBlock->LockQueue[VacbLock].Lock = &VacbLockQueue;
ControlBlock->LockQueue[VacbLock].Next = NULLPTR;
ControlBlock->LockQueue[MasterLock].Lock = &MasterLockQueue;
ControlBlock->LockQueue[MasterLock].Next = NULLPTR;
ControlBlock->LockQueue[NonPagedAllocPoolLock].Lock = &NonPagedAllocLockQueue;
ControlBlock->LockQueue[NonPagedAllocPoolLock].Next = NULLPTR;
ControlBlock->LockQueue[IoCancelLock].Lock = &IoCancelLockQueue;
ControlBlock->LockQueue[IoCancelLock].Next = NULLPTR;
ControlBlock->LockQueue[WorkQueueLock].Lock = &WorkLockQueue;
ControlBlock->LockQueue[WorkQueueLock].Next = NULLPTR;
ControlBlock->LockQueue[IoVpbLock].Lock = &IoVpbLockQueue;
ControlBlock->LockQueue[IoVpbLock].Next = NULLPTR;
ControlBlock->LockQueue[IoDatabaseLock].Lock = &IoDatabaseLockQueue;
ControlBlock->LockQueue[IoDatabaseLock].Next = NULLPTR;
ControlBlock->LockQueue[IoCompletionLock].Lock = &IoCompletionLockQueue;
ControlBlock->LockQueue[IoCompletionLock].Next = NULLPTR;
ControlBlock->LockQueue[FileSystemLock].Lock = &FileSystemLockQueue;
ControlBlock->LockQueue[FileSystemLock].Next = NULLPTR;
ControlBlock->LockQueue[AfdWorkQueueLock].Lock = NULLPTR;
ControlBlock->LockQueue[AfdWorkQueueLock].Next = NULLPTR;
ControlBlock->LockQueue[BcbLock].Lock = NULLPTR;
ControlBlock->LockQueue[BcbLock].Next = NULLPTR;
ControlBlock->LockQueue[NonPagedPoolLock].Lock = &NonPagedPoolLockQueue;
ControlBlock->LockQueue[NonPagedPoolLock].Next = NULLPTR;
ControlBlock->LockQueue[ReservedSystemLock].Lock = NULLPTR;
ControlBlock->LockQueue[ReservedSystemLock].Next = NULLPTR;
ControlBlock->LockQueue[TimerTableLock].Lock = &TimerTableLockQueue;
ControlBlock->LockQueue[TimerTableLock].Next = NULLPTR;
}
/**
* Initializes a kernel spinlock object.
*
@@ -112,3 +185,29 @@ KE::SpinLock::ReleaseSpinLock(IN OUT PKSPIN_LOCK SpinLock)
/* Add an explicit memory barrier */
AR::CpuFunc::ReadWriteBarrier();
}
/**
* Tests a kernel spin lock.
*
* @param SpinLock
* Supplies a pointer to the kernel spin lock.
*
* @return This routine returns TRUE if the lock is free, FALSE otherwise.
*
* @since XT 1.0
*/
XTFASTCALL
BOOLEAN
TestSpinLock(IN PKSPIN_LOCK SpinLock)
{
/* Check if the lock is free */
if(*SpinLock)
{
/* Spinlock is busy, yield processor and return FALSE */
AR::CpuFunc::YieldProcessor();
return FALSE;
}
/* Spinlock is free, return TRUE */
return TRUE;
}

Voir le fichier

@@ -83,7 +83,7 @@ MM::PageMap::GetPteAddress(PVOID Address)
/* Calculate offset and return PTE address */
Offset = ((((ULONG_PTR)(Address)) >> MM_PTI_SHIFT) << PageMapInfo.PteShift);
return (PMMPTE)(MM_PTE_BASE + Offset);
return (PMMPTE)(PageMapInfo.PteBase + Offset);
}
/**

Voir le fichier

@@ -74,7 +74,7 @@ __CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord,
/* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag();
KE::Crash::Panic(0); // CXX_FRAME_HANDLER_CALLED
KE::Crash::Panic(0);
/* Continue search */
return ExceptionContinueSearch;
@@ -129,5 +129,5 @@ _purecall(VOID)
/* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag();
KE::Crash::Panic(0); // PURE_VIRTUAL_FUNCTION_CALL
KE::Crash::Panic(0);
}

Voir le fichier

@@ -74,7 +74,7 @@ __CxxFrameHandler3(IN PEXCEPTION_RECORD ExceptionRecord,
/* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag();
KE::Crash::Panic(0); // CXX_FRAME_HANDLER_CALLED
KE::Crash::Panic(0);
/* Continue search */
return ExceptionContinueSearch;
@@ -129,5 +129,5 @@ _purecall(VOID)
/* Disable interrupts and hang */
AR::CpuFunc::ClearInterruptFlag();
KE::Crash::Panic(0); // PURE_VIRTUAL_FUNCTION_CALL
KE::Crash::Panic(0);
}

Voir le fichier

@@ -2,7 +2,7 @@
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/rtl/llist.cc
* DESCRIPTION: Linked list manipulation routines
* DESCRIPTION: Doubly linked list manipulation routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
@@ -10,10 +10,35 @@
/**
* This routine initializes a structure representing the head of a double-linked list.
* Retrieves the first entry from a doubly linked list without removing it from the list.
*
* @param ListHead
* Pointer to a structure that serves as the list header.
* Supplies a pointer to a structure that serves as the list header.
*
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
*
* @since XT 1.0
*/
XTCDECL
PLIST_ENTRY
RTL::LinkedList::GetFirstEntry(IN PLIST_ENTRY ListHead)
{
/* Check if the list is empty */
if(ListEmpty(ListHead))
{
/* Empty list, return NULLPTR */
return NULLPTR;
}
/* Return first entry in the list */
return ListHead->Flink;
}
/**
* Initializes a structure representing the head of a doubly linked list.
*
* @param ListHead
* Supplies a pointer to a structure that serves as the list header.
*
* @return This routine does not return any value.
*
@@ -23,15 +48,16 @@ XTCDECL
VOID
RTL::LinkedList::InitializeListHead(IN PLIST_ENTRY ListHead)
{
/* Initialize list head */
ListHead->Blink = ListHead;
ListHead->Flink = ListHead;
}
/**
* This routine initializes a structure representing the head of a 32bit double-linked list.
* Initializes a structure representing the head of a 32bit doubly linked list.
*
* @param ListHead
* Pointer to a structure that serves as the list header.
* Supplies a pointer to a structure that serves as the list header.
*
* @return This routine does not return any value.
*
@@ -41,18 +67,19 @@ XTCDECL
VOID
RTL::LinkedList::InitializeListHead32(IN PLIST_ENTRY32 ListHead)
{
/* Initialize list head */
ListHead->Blink = PtrToUlong(ListHead);
ListHead->Flink = PtrToUlong(ListHead);
}
/**
* This routine inserts an entry at the head of a doubly linked list.
* Inserts an entry at the head of a doubly linked list.
*
* @param ListHead
* Pointer to the head of the list.
* Supplies a pointer to the head of the list.
*
* @param Entry
* Pointer to the entry that will be inserted in the list.
* Supplies a pointer to the entry that will be inserted in the list.
*
* @return This routine does not return any value.
*
@@ -63,6 +90,7 @@ VOID
RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry)
{
/* Insert entry at the head of the list */
Entry->Flink = ListHead->Flink;
Entry->Blink = ListHead;
ListHead->Flink->Blink = Entry;
@@ -70,13 +98,13 @@ RTL::LinkedList::InsertHeadList(IN OUT PLIST_ENTRY ListHead,
}
/**
* This routine inserts an entry at the tail of a doubly linked list.
* Inserts an entry at the tail of a doubly linked list.
*
* @param ListHead
* Pointer to the head of the list.
* Supplies a pointer to the head of the list.
*
* @param Entry
* Pointer to the entry that will be inserted in the list.
* Supplies a pointer to the entry that will be inserted in the list.
*
* @return This routine does not return any value.
*
@@ -87,6 +115,7 @@ VOID
RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry)
{
/* Insert entry at the tail of the list */
Entry->Flink = ListHead;
Entry->Blink = ListHead->Blink;
ListHead->Blink->Flink = Entry;
@@ -97,9 +126,9 @@ RTL::LinkedList::InsertTailList(IN OUT PLIST_ENTRY ListHead,
* Indicates whether a doubly linked list structure is empty, or not initialized at all.
*
* @param ListHead
* Pointer to a structure that represents the head of the list.
* Supplies a pointer to a structure that represents the head of the list.
*
* @return TRUE if there are currently no entries in the list or FALSE otherwise.
* @return This routine returns TRUE if there are currently no entries in the list or FALSE otherwise.
*
* @since XT 1.0
*/
@@ -107,14 +136,15 @@ XTCDECL
BOOLEAN
RTL::LinkedList::ListEmpty(IN PLIST_ENTRY ListHead)
{
/* Check if the list is empty */
return (((ListHead->Flink == NULLPTR) && (ListHead->Blink == NULLPTR)) || (ListHead->Flink == ListHead));
}
/**
* This routine detects a loop in a doubly linked list.
* Detects a loop in a doubly linked list.
*
* @param ListHead
* Pointer to a structure that represents the head of the list.
* Supplies a pointer to a structure that represents the head of the list.
*
* @return TRUE if linked list contains a loop or FALSE otherwise.
*
@@ -157,10 +187,10 @@ RTL::LinkedList::ListLoop(IN PLIST_ENTRY ListHead)
}
/**
* This routine removes an entry from a doubly linked list.
* Removes an entry from a doubly linked list.
*
* @param Entry
* Pointer to the entry that will be removed from the list.
* Supplies a pointer to the entry that will be removed from the list.
*
* @return This routine does not return any value.
*
@@ -170,6 +200,91 @@ XTCDECL
VOID
RTL::LinkedList::RemoveEntryList(IN PLIST_ENTRY Entry)
{
/* Remove entry from the list */
Entry->Flink->Blink = Entry->Blink;
Entry->Blink->Flink = Entry->Flink;
}
/**
* Splices a doubly linked list at the head of another list. The source list is reinitialized to empty.
*
* @param ListHead
* Supplies a pointer to a structure that represents the head of the list.
*
* @param SpliceList
* Supplies a pointer to a structure that represents the head of the list that will be spliced.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RTL::LinkedList::SpliceHeadList(IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY SpliceList)
{
PLIST_ENTRY FirstEntry, LastEntry;
/* Check if the list to splice is empty */
if(SpliceList->Flink == SpliceList)
{
/* Nothing to splice, return */
return;
}
/* Get first and last entries of the list to splice */
FirstEntry = SpliceList->Flink;
LastEntry = SpliceList->Blink;
/* Splice the list at the head of destination */
FirstEntry->Blink = ListHead;
LastEntry->Flink = ListHead->Flink;
ListHead->Flink->Blink = LastEntry;
ListHead->Flink = FirstEntry;
/* Reinitialize the source list to empty */
SpliceList->Blink = SpliceList;
SpliceList->Flink = SpliceList;
}
/**
* Splices a doubly linked list at the tail of another list. The source list is reinitialized to empty.
*
* @param ListHead
* Supplies a pointer to the head of the destination list.
*
* @param SpliceList
* Supplies a pointer to the head of the list that will be spliced.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RTL::LinkedList::SpliceTailList(IN OUT PLIST_ENTRY ListHead,
IN OUT PLIST_ENTRY SpliceList)
{
PLIST_ENTRY FirstEntry, LastEntry;
/* Check if the list to splice is empty */
if(SpliceList->Flink == SpliceList)
{
/* Nothing to splice, return */
return;
}
/* Get first and last entries of the list to splice */
FirstEntry = SpliceList->Flink;
LastEntry = SpliceList->Blink;
/* Splice the list at the tail of destination */
FirstEntry->Blink = ListHead->Blink;
LastEntry->Flink = ListHead;
ListHead->Blink->Flink = FirstEntry;
ListHead->Blink = LastEntry;
/* Reinitialize the source list to empty */
SpliceList->Blink = SpliceList;
SpliceList->Flink = SpliceList;
}

322
xtoskrnl/rtl/sha1.cc Fichier normal
Voir le fichier

@@ -0,0 +1,322 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/rtl/sha1.cc
* DESCRIPTION: SHA1 computation support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/**
* Computes the SHA-1 hash of a buffer in a single step.
*
* @param Buffer
* Supplies a pointer to the buffer containing the data to be hashed.
*
* @param BufferSize
* Specifies the size of the buffer in bytes.
*
* @param Digest
* Supplies a pointer to the buffer that receives the 20-byte SHA-1 hash digest.
*
* @return This routine returns STATUS_SUCCESS if the hash was computed successfully,
* or STATUS_INVALID_PARAMETER if an invalid parameter was supplied.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
RTL::SHA1::ComputeDigest(IN PCUCHAR Buffer,
IN SIZE_T BufferSize,
OUT PUCHAR Digest)
{
RTL_SHA1_CONTEXT Context;
XTSTATUS Status;
/* Validate input parameters */
if(!Digest || (!Buffer && BufferSize > 0))
{
/* Invalid parameters, return error */
return STATUS_INVALID_PARAMETER;
}
/* Initialize SHA-1 context */
Status = InitializeContext(&Context);
if(Status != STATUS_SUCCESS)
{
/* Failed to initialize SHA-1 context, return error */
return Status;
}
/* Hash data and compute SHA-1 digest */
HashData(&Context, Buffer, BufferSize);
ComputeHash(&Context, Digest);
/* Return success */
return STATUS_SUCCESS;
}
/**
* Finalizes the SHA-1 hash computation and provides the digest.
*
* @param Context
* Supplies a pointer to the SHA-1 context structure.
*
* @param Digest
* Supplies a pointer to a buffer that receives the 20-byte SHA-1 hash digest.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
RTL::SHA1::ComputeHash(IN OUT PRTL_SHA1_CONTEXT Context,
OUT PUCHAR Digest)
{
ULONG Index, PaddingLength;
UCHAR Padding[64];
UCHAR Bits[8];
/* Zero padding and append 0x80 to it */
RTL::Memory::ZeroMemory(Padding, 64);
Padding[0] = 0x80;
/* Encode the total message length in bits as a Big Endian 64-bit integer */
*(PULONG)(Bits) = RTL::Endianness::SwapByte32(Context->Count[1]);
*(PULONG)(Bits + 4) = RTL::Endianness::SwapByte32(Context->Count[0]);
/* Calculate padding length needed to align the message to 56 bytes */
Index = (Context->Count[0] >> 3) & 0x3F;
PaddingLength = (Index < 56) ? (56 - Index) : (120 - Index);
/* Append the padding bytes to the message stream to satisfy the block boundary */
HashData(Context, Padding, PaddingLength);
/* Append bits before final transformation */
HashData(Context, Bits, 8);
/* Store hash to output in Big Endian format */
Digest[0] = (UCHAR)((Context->State[0] >> 24) & 0xFF);
Digest[1] = (UCHAR)((Context->State[0] >> 16) & 0xFF);
Digest[2] = (UCHAR)((Context->State[0] >> 8) & 0xFF);
Digest[3] = (UCHAR)(Context->State[0] & 0xFF);
Digest[4] = (UCHAR)((Context->State[1] >> 24) & 0xFF);
Digest[5] = (UCHAR)((Context->State[1] >> 16) & 0xFF);
Digest[6] = (UCHAR)((Context->State[1] >> 8) & 0xFF);
Digest[7] = (UCHAR)(Context->State[1] & 0xFF);
Digest[8] = (UCHAR)((Context->State[2] >> 24) & 0xFF);
Digest[9] = (UCHAR)((Context->State[2] >> 16) & 0xFF);
Digest[10] = (UCHAR)((Context->State[2] >> 8) & 0xFF);
Digest[11] = (UCHAR)(Context->State[2] & 0xFF);
Digest[12] = (UCHAR)((Context->State[3] >> 24) & 0xFF);
Digest[13] = (UCHAR)((Context->State[3] >> 16) & 0xFF);
Digest[14] = (UCHAR)((Context->State[3] >> 8) & 0xFF);
Digest[15] = (UCHAR)(Context->State[3] & 0xFF);
Digest[16] = (UCHAR)((Context->State[4] >> 24) & 0xFF);
Digest[17] = (UCHAR)((Context->State[4] >> 16) & 0xFF);
Digest[18] = (UCHAR)((Context->State[4] >> 8) & 0xFF);
Digest[19] = (UCHAR)(Context->State[4] & 0xFF);
/* Clear context memory for security */
RTL::Memory::ZeroMemory(Context, sizeof(RTL_SHA1_CONTEXT));
}
/**
* Updates the SHA-1 context with the provided data buffer.
*
* @param Context
* Supplies a pointer to the SHA-1 context structure.
*
* @param Data
* Supplies a pointer to the buffer containing the data to be hashed.
*
* @param Length
* Specifies the length of the data buffer in bytes.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
RTL::SHA1::HashData(IN OUT PRTL_SHA1_CONTEXT Context,
IN PCUCHAR Data,
IN ULONG Length)
{
ULONG Index, Input, PartialLength;
/* Calculate byte offset within the 64-byte block buffer */
Index = (Context->Count[0] >> 3) & 0x3F;
/* Update the total bit count, handling overflow from low to high word */
if((Context->Count[0] += (Length << 3)) < (Length << 3))
{
/* Increment high 32-bit counter on low counter overflow */
Context->Count[1]++;
}
/* Add the high-order bits of the length (bytes -> bits overflow) to the high counter */
Context->Count[1] += (Length >> 29);
/* Calculate the number of bytes required to fill the remaining buffer space */
PartialLength = 64 - Index;
/* Transform as many times as possible */
if(Length >= PartialLength)
{
/* Fill the buffer partially and transform */
RTL::Memory::CopyMemory(&Context->Buffer[Index], Data, PartialLength);
TransformData(Context->State, Context->Buffer);
/* Process remaining full 64-byte blocks directly from the input pointer */
for(Input = PartialLength; Input + 63 < Length; Input += 64)
{
/* Transform the full block without copying to the internal buffer */
TransformData(Context->State, &Data[Input]);
}
/* Reset buffer index to indicate the buffer is now empty */
Index = 0;
}
else
{
/* No full block was formed, begin copying from the start of input */
Input = 0;
}
/* Buffer remaining input */
RTL::Memory::CopyMemory(&Context->Buffer[Index], &Data[Input], Length - Input);
}
/**
* Initializes a SHA-1 context structure with the standard initial hash values.
*
* @param Context
* Supplies a pointer to the SHA-1 context structure to initialize.
*
* @return This routine returns STATUS_SUCCESS if the context was initialized successfully,
* or STATUS_INVALID_PARAMETER if the pointer is NULLPTR.
*
* @since XT 1.0
*/
XTAPI
XTSTATUS
RTL::SHA1::InitializeContext(OUT PRTL_SHA1_CONTEXT Context)
{
/* Validate input parameter */
if(!Context)
{
/* Invalid parameter, return error */
return STATUS_INVALID_PARAMETER;
}
/* Initialize hash constants defined by FIPS 180-4 */
Context->State[0] = 0x67452301;
Context->State[1] = 0xEFCDAB89;
Context->State[2] = 0x98BADCFE;
Context->State[3] = 0x10325476;
Context->State[4] = 0xC3D2E1F0;
Context->Count[0] = 0;
Context->Count[1] = 0;
/* Clear buffer */
RTL::Memory::ZeroMemory(Context->Buffer, SHA1_BLOCK_SIZE);
/* Return success */
return STATUS_SUCCESS;
}
/**
* Transforms a single 64-byte block using the SHA-1 compression function.
*
* @param State
* Supplies a pointer to the array containing the current hash state variables.
*
* @param Buffer
* Supplies a pointer to the 64-byte input buffer to be transformed.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
RTL::SHA1::TransformData(IN OUT PULONG State,
IN PCUCHAR Buffer)
{
ULONG Constant, Function, Index, TempHash;
ULONG TempState[5];
ULONG Stack[80];
/* Initialize working variables with current state */
TempState[0] = State[0];
TempState[1] = State[1];
TempState[2] = State[2];
TempState[3] = State[3];
TempState[4] = State[4];
/* Initialize the first 16 words of the message schedule from the input buffer */
for(Index = 0; Index < 16; Index++)
{
/* Convert input words from Little Endian to Big Endian required by SHA-1 */
Stack[Index] = RTL::Endianness::SwapByte32(((const PULONG)Buffer)[Index]);
}
/* Expand the message to 80 words using the SHA-1 algorithm */
for(Index = 16; Index < 80; Index++)
{
/* Compute the next word value based on XOR and left rotation */
Stack[Index] = ROTATE_LEFT((Stack[Index - 3] ^ Stack[Index - 8] ^ Stack[Index - 14] ^ Stack[Index - 16]), 1);
}
/* Execute the main compression loop for 80 rounds */
for(Index = 0; Index < 80; Index++)
{
/* Determine the logical function and constant based on the current round */
if(Index < 20)
{
/* Set the constant defined by FIPS 180-4 for rounds 0-19 and calculate the logical function */
Constant = 0x5A827999;
Function = (TempState[1] & TempState[2]) | ((~TempState[1]) & TempState[3]);
}
else if(Index < 40)
{
/* Set the constant defined by FIPS 180-4 for rounds 20-39 and calculate the logical function */
Constant = 0x6ED9EBA1;
Function = TempState[1] ^ TempState[2] ^ TempState[3];
}
else if(Index < 60)
{
/* Set the constant defined by FIPS 180-4 for rounds 40-59 and calculate the logical function */
Constant = 0x8F1BBCDC;
Function = (TempState[1] & TempState[2]) | (TempState[1] & TempState[3]) | (TempState[2] & TempState[3]);
}
else
{
/* Set the constant defined by FIPS 180-4 for rounds 60-79 and calculate the logical function */
Constant = 0xCA62C1D6;
Function = TempState[1] ^ TempState[2] ^ TempState[3];
}
/* Calculate the temporary hash value for this round */
TempHash = ROTATE_LEFT(TempState[0], 5) + Function + TempState[4] + Constant + Stack[Index];
TempState[4] = TempState[3];
TempState[3] = TempState[2];
TempState[2] = ROTATE_LEFT(TempState[1], 30);
TempState[1] = TempState[0];
TempState[0] = TempHash;
}
/* Add the compressed chunk to the current hash value */
State[0] += TempState[0];
State[1] += TempState[1];
State[2] += TempState[2];
State[3] += TempState[3];
State[4] += TempState[4];
/* Clear sensitive data from stack */
RTL::Memory::ZeroMemory(Stack, sizeof(Stack));
}

390
xtoskrnl/rtl/slist.cc Fichier normal
Voir le fichier

@@ -0,0 +1,390 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtoskrnl/rtl/slist.cc
* DESCRIPTION: Singly linked list manipulation routines
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtos.hh>
/**
* Retrieves the first entry from a singly linked list without removing it from the list.
*
* @param ListHead
* Supplies a pointer to a structure that serves as the list header.
*
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::GetFirstEntry(IN PSINGLE_LIST_HEADER ListHead)
{
/* Check if the list is empty */
if(ListEmpty(ListHead))
{
/* Empty list, return NULLPTR */
return NULLPTR;
}
/* Return first entry in the list */
return ListHead->Next.Next;
}
/**
* Initializes a structure representing the head of a singly linked list.
*
* @param ListHead
* Supplies a pointer to a structure that serves as the list header.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RTL::SinglyList::InitializeListHead(IN PSINGLE_LIST_HEADER ListHead)
{
/* Initialize the singly linked list head */
ListHead->Alignment = 0;
}
/**
* Inserts an entry at the head of a singly linked list.
*
* @param ListHead
* Supplies a pointer to the head of the list.
*
* @param Entry
* Supplies a pointer to the entry that will be inserted in the list.
*
* @return This routine returns a pointer to the original first entry in the list.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::InsertHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry)
{
PSINGLE_LIST_ENTRY OriginalEntry;
/* Store the original first entry */
OriginalEntry = ListHead->Next.Next;
/* Insert entry at the head of the list and increment depth and sequence */
Entry->Next = ListHead->Next.Next;
ListHead->Next.Next = Entry;
ListHead->Depth++;
ListHead->Sequence++;
/* Return original first entry */
return OriginalEntry;
}
/**
* Inserts an entry at the tail of a singly linked list.
*
* @param ListHead
* Supplies a pointer to the head of the list.
*
* @param Entry
* Supplies a pointer to the entry that will be inserted in the list.
*
* @return This routine returns a pointer to the original last entry in the list.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::InsertTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry)
{
PSINGLE_LIST_ENTRY CurrentEntry, OriginalEntry;
/* Set Next pointer of the new entry to NULLPTR */
Entry->Next = NULLPTR;
/* Check if the list is empty */
if(ListEmpty(ListHead))
{
/* Store the original last entry */
OriginalEntry = ListHead->Next.Next;
/* Insert entry at the head */
ListHead->Next.Next = Entry;
}
else
{
/* Traverse the list to find the last entry */
CurrentEntry = ListHead->Next.Next;
while(CurrentEntry->Next != NULLPTR)
{
/* Move to the next entry */
CurrentEntry = CurrentEntry->Next;
}
/* Store the original last entry */
OriginalEntry = CurrentEntry;
/* Insert entry at the tail */
CurrentEntry->Next = Entry;
}
/* Increment list depth and sequence */
ListHead->Depth++;
ListHead->Sequence++;
/* Return original last entry */
return OriginalEntry;
}
/**
* Indicates whether a singly linked list structure is empty, or not initialized at all.
*
* @param ListHead
* Supplies a pointer to a structure that represents the head of the list.
*
* @return This routine returns TRUE if there are currently no entries in the list or FALSE otherwise.
*
* @since XT 1.0
*/
XTCDECL
BOOLEAN
RTL::SinglyList::ListEmpty(IN PSINGLE_LIST_HEADER ListHead)
{
/* Check if the list is empty */
return (ListHead == NULLPTR || ListHead->Next.Next == NULLPTR);
}
/**
* Queries the current depth (number of entries) of a singly linked list.
*
* @param ListHead
* Supplies a pointer to a structure that represents the head of the singly linked list.
*
* @return This routine returns the number of entries currently in the list, or zero if the list head is NULLPTR.
*
* @since XT 1.0
*/
XTAPI
USHORT
RTL::SinglyList::QueryListDepth(IN PSINGLE_LIST_HEADER ListHead)
{
/* Check if the list head is initialized and valid */
if(ListHead == NULLPTR)
{
/* Return zero */
return 0;
}
/* Return the list depth */
return ListHead->Depth;
}
/**
* Removes an entry from a singly linked list.
*
* @param ListHead
* Supplies a pointer to the head of the list.
*
* @param Entry
* Supplies a pointer to the entry that will be removed from the list.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
RTL::SinglyList::RemoveEntryList(IN PSINGLE_LIST_HEADER ListHead,
IN PSINGLE_LIST_ENTRY Entry)
{
PSINGLE_LIST_ENTRY PreviousEntry;
/* Check if the list is empty */
if(ListEmpty(ListHead))
{
/* List is empty, nothing to remove, return */
return;
}
/* Check if the entry is the first one */
if(ListHead->Next.Next == Entry)
{
/* Remove the first entry and decrement depth */
ListHead->Next.Next = Entry->Next;
ListHead->Depth--;
/* Nothing else to do, return */
return;
}
/* Find the previous entry */
PreviousEntry = ListHead->Next.Next;
while(PreviousEntry->Next != Entry)
{
/* Move to the next entry */
PreviousEntry = PreviousEntry->Next;
/* Check if we reached the end of the list */
if(PreviousEntry == NULLPTR)
{
/* Entry not found, return */
return;
}
}
/* Remove the entry and decrement depth */
PreviousEntry->Next = Entry->Next;
ListHead->Depth--;
}
/**
* Splices a singly linked list at the head of another list. The source list is reinitialized to empty.
*
* @param ListHead
* Supplies a pointer to a structure that represents the head of the list.
*
* @param SpliceList
* Supplies a pointer to a structure that represents the head of the list that will be spliced.
*
* @return This routine returns a pointer to the original first entry in the list.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::SpliceHeadList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN OUT PSINGLE_LIST_HEADER SpliceList)
{
PSINGLE_LIST_ENTRY LastEntry, OriginalEntry;
/* Store the original last entry */
OriginalEntry = ListHead->Next.Next;
/* Check if the list to splice is empty */
if(ListEmpty(SpliceList))
{
/* Nothing to splice, return original first entry */
return OriginalEntry;
}
/* Find the last entry of the list to splice */
LastEntry = SpliceList->Next.Next;
while(LastEntry->Next != NULLPTR)
{
/* Move to the next entry */
LastEntry = LastEntry->Next;
}
/* Splice the list at the head of destination */
LastEntry->Next = ListHead->Next.Next;
ListHead->Next.Next = SpliceList->Next.Next;
/* Update depth and sequence of the destination list */
ListHead->Depth += SpliceList->Depth;
ListHead->Sequence++;
/* Reinitialize the source list to empty */
SpliceList->Next.Next = NULLPTR;
SpliceList->Depth = 0;
/* Return the original last entry */
return OriginalEntry;
}
/**
* Splices a singly linked list at the tail of another list. The source list is reinitialized to empty.
*
* @param ListHead
* Supplies a pointer to the head of the destination list.
*
* @param SpliceList
* Supplies a pointer to the head of the list that will be spliced.
*
* @return This routine returns a pointer to the original last entry in the list.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::SpliceTailList(IN OUT PSINGLE_LIST_HEADER ListHead,
IN OUT PSINGLE_LIST_HEADER SpliceList)
{
PSINGLE_LIST_ENTRY LastEntry, OriginalEntry;
/* Check if the destination list is empty */
if(ListEmpty(ListHead))
{
/* Destination is empty, original last entry is NULLPTR */
OriginalEntry = NULLPTR;
/* Move the splice list to the destination head */
ListHead->Next.Next = SpliceList->Next.Next;
}
else
{
/* Find the last entry of the destination list */
LastEntry = ListHead->Next.Next;
while(LastEntry->Next != NULLPTR)
{
/* Move to the next entry */
LastEntry = LastEntry->Next;
}
/* Store the original last entry */
OriginalEntry = LastEntry;
/* Splice the list at the tail of destination */
LastEntry->Next = SpliceList->Next.Next;
}
/* Update depth and sequence of the destination list */
ListHead->Depth += SpliceList->Depth;
ListHead->Sequence++;
/* Reinitialize the source list to empty */
SpliceList->Next.Next = NULLPTR;
SpliceList->Depth = 0;
/* Return the original last entry */
return OriginalEntry;
}
/**
* Retrieves the first entry from a singly linked list and removes it from the list.
*
* @param ListHead
* Pointer to a structure that serves as the list header.
*
* @return This routine returns a pointer to the first entry in the list, or NULLPTR if the list is empty.
*
* @since XT 1.0
*/
XTCDECL
PSINGLE_LIST_ENTRY
RTL::SinglyList::TakeFirstEntry(IN PSINGLE_LIST_HEADER ListHead)
{
PSINGLE_LIST_ENTRY Entry;
/* Check if the list is empty */
if(ListEmpty(ListHead))
{
/* List is empty, return NULLPTR */
return NULLPTR;
}
/* Get the first entry */
Entry = ListHead->Next.Next;
/* Remove entry from the list */
ListHead->Next.Next = Entry->Next;
ListHead->Depth--;
/* Return the first entry */
return Entry;
}