Skip to content
This repository was archived by the owner on Jan 4, 2026. It is now read-only.

Commit 0f3c5b0

Browse files
authored
Merge pull request #170 from assembler-0/Development
Development
2 parents f177c06 + f570445 commit 0f3c5b0

21 files changed

Lines changed: 319 additions & 116 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ add_custom_target(extra-img
217217
COMMAND ${QEMU_IMG} create -f raw VirtioDisk.img 128M
218218
COMMAND ${MKFS_EXT2} VirtioDisk.img
219219
COMMAND ${QEMU_IMG} create -f raw SataDisk.img 128M
220-
COMMAND ${MKFS_EXT2} SataDisk.img
220+
COMMAND ${MKFS_FAT} -F12 SataDisk.img
221221
COMMAND ${QEMU_IMG} create -f raw NVMeDisk.img 256M
222222
COMMAND ${MKFS_EXT2} NVMeDisk.img
223223
COMMENT "Creating extra disk images"

README.md

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# [VoidFrame] - a ring 0 kernel 💫
22

3-
> A fast, simple, secure 64-bit ring-0 kernel written in C and assembly. With modern capabilities.
3+
> A fast, simple, secure 64-bit ring-0 kernel written in C (Rust) and assembly. With modern capabilities.
44
55
---
66

7-
- How it works: [here!](docs/ARCHITECTURE.md)
7+
- How it works (outdated): [here!](docs/ARCHITECTURE.md)
88
- Development Guide: [here!](docs/DEVELOPMENT.md)
99

1010
---
@@ -28,7 +28,6 @@ It would be amazing if you could contribute to this project!
2828
- x64-compatible cpu (used: Intel i3-12100F)
2929
- POSIX-compliant OS (SysV ABI) (used: Arch Linux 6.16.9-arch1-1)
3030
- cmake >= 3.20 (used: cmake 4.1.2)
31-
- meson >= 1.4 (used: meson 1.9.1)
3231
- ninja >= 1.11 (used: ninja 1.21.1)
3332
- clang/++ >= 18.0.0 (used: 20.1.8)
3433
- rustup (nightly, bare metal toolchain) >= 1.89.0 (used: 1.92.0-nightly)
@@ -40,18 +39,6 @@ It would be amazing if you could contribute to this project!
4039
- Note: depending on your distro, grub-mkrescue may require xorriso and mtools packages.
4140

4241
### Quickstart
43-
#### Full development setup
44-
```bash
45-
# Meson
46-
git clone https://github.com/assembler-0/VoidFrame.git
47-
cd VoidFrame
48-
meson setup build
49-
cd build
50-
ninja -j$(nproc)
51-
ninja img
52-
ninja extra-img
53-
ninja run
54-
```
5542
```bash
5643
# CMake
5744
git clone https://github.com/assembler-0/VoidFrame.git
@@ -61,7 +48,7 @@ cd build
6148
cmake .. -DCMAKE_BUILD_TYPE=Release \
6249
-DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain/linux-x64.cmake \
6350
-G Ninja \
64-
-DVF_SCHEDULER=<MLFQ/EEVDF>
51+
-DVF_SCHEDULER=EEVDF
6552
ccmake . # Optinal, tune as needed
6653
ninja -j$(nproc)
6754
ninja run

drivers/ACPI.c

Lines changed: 85 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
#include "Console.h"
33
#include "Io.h"
44
#include "MemOps.h"
5+
#include "Scheduler.h"
56
#include "StringOps.h"
67
#include "VMem.h"
78
#include "TSC.h"
9+
#include "VFS.h"
810

911
static ACPIFADT* g_fadt = NULL;
1012
static bool g_acpi_initialized = false;
@@ -47,128 +49,126 @@ static bool ValidateChecksum(void* table, uint32_t length) {
4749

4850
// Map ACPI table to virtual memory
4951
static void* MapACPITable(uint32_t phys_addr, uint32_t size) {
50-
// Align to page boundaries
51-
uint32_t aligned_addr = phys_addr & ~0xFFF;
52-
uint32_t offset = phys_addr - aligned_addr;
53-
uint32_t aligned_size = ((size + offset + 0xFFF) & ~0xFFF);
54-
52+
uint64_t aligned_addr = phys_addr & ~0xFFF;
53+
uint64_t offset = phys_addr - aligned_addr;
54+
uint64_t aligned_size = ((size + offset + 0xFFF) & ~0xFFF);
55+
5556
void* virt_addr = VMemAlloc(aligned_size);
56-
if (!virt_addr) return NULL;
57-
57+
if (!virt_addr) {
58+
PrintKernelError("ACPI: Failed to allocate virtual memory for ACPI table\n");
59+
return NULL;
60+
}
61+
5862
if (VMemUnmap((uint64_t)virt_addr, aligned_size) != VMEM_SUCCESS) {
5963
VMemFree(virt_addr, aligned_size);
64+
PrintKernelError("ACPI: Failed to unmap virtual memory for ACPI table\n");
6065
return NULL;
6166
}
62-
67+
6368
if (VMemMapMMIO((uint64_t)virt_addr, aligned_addr, aligned_size, PAGE_WRITABLE | PAGE_NOCACHE) != VMEM_SUCCESS) {
64-
VMemFree(virt_addr, aligned_size);
69+
// No need to free here as VMemMapMMIO should handle cleanup on failure
70+
PrintKernelError("ACPI: Failed to map MMIO for ACPI table\n");
6571
return NULL;
6672
}
67-
73+
6874
return (uint8_t*)virt_addr + offset;
6975
}
7076

77+
static ACPIRSDT* g_rsdt = NULL;
78+
79+
void* AcpiFindTable(const char* signature) {
80+
if (!g_rsdt) {
81+
return NULL;
82+
}
83+
84+
uint32_t entries = (g_rsdt->header.length - sizeof(ACPISDTHeader)) / 4;
85+
for (uint32_t i = 0; i < entries; i++) {
86+
ACPISDTHeader* header = (ACPISDTHeader*)MapACPITable(g_rsdt->table_pointers[i], sizeof(ACPISDTHeader));
87+
if (!header) {
88+
continue;
89+
}
90+
91+
if (FastMemcmp(header->signature, signature, 4) == 0) {
92+
void* table = MapACPITable(g_rsdt->table_pointers[i], header->length);
93+
VMemUnmap((uint64_t)header - (g_rsdt->table_pointers[i] & 0xFFF), ((sizeof(ACPISDTHeader) + (g_rsdt->table_pointers[i] & 0xFFF) + 0xFFF) & ~0xFFF));
94+
return table;
95+
}
96+
97+
VMemUnmap((uint64_t)header - (g_rsdt->table_pointers[i] & 0xFFF), ((sizeof(ACPISDTHeader) + (g_rsdt->table_pointers[i] & 0xFFF) + 0xFFF) & ~0xFFF));
98+
}
99+
100+
return NULL;
101+
}
102+
71103
bool ACPIInit(void) {
72104
PrintKernel("ACPI: Initializing ACPI subsystem...\n");
73-
74-
// Find RSDP
105+
75106
ACPIRSDPv1* rsdp = FindRSDP();
76107
if (!rsdp) {
77108
PrintKernelError("ACPI: RSDP not found\n");
78109
return false;
79110
}
80-
81-
PrintKernel("ACPI: Found RSDP at 0x");
82-
PrintKernelHex((uint64_t)rsdp);
83-
PrintKernel("\n");
84-
85-
// Validate RSDP checksum
111+
86112
if (!ValidateChecksum(rsdp, sizeof(ACPIRSDPv1))) {
87113
PrintKernelError("ACPI: Invalid RSDP checksum\n");
88114
return false;
89115
}
90116

91-
ACPIRSDT* rsdt = (ACPIRSDT*)MapACPITable(rsdp->rsdt_address,
92-
sizeof(ACPISDTHeader));
93-
if (!rsdt) {
94-
PrintKernelError("ACPI: Failed to map RSDT\n");
117+
g_rsdt = (ACPIRSDT*)MapACPITable(rsdp->rsdt_address, sizeof(ACPISDTHeader));
118+
if (!g_rsdt) {
119+
PrintKernelError("ACPI: Failed to map RSDT header\n");
95120
return false;
96121
}
97-
// Validate RSDT signature
98-
if (FastMemcmp(rsdt->header.signature, ACPI_RSDT_SIG, 4) != 0) {
122+
123+
if (FastMemcmp(g_rsdt->header.signature, ACPI_RSDT_SIG, 4) != 0) {
99124
PrintKernelError("ACPI: Invalid RSDT signature\n");
100-
// Clean up the initial header‐only mapping
101-
VMemUnmap((uint64_t)rsdt - (rsdp->rsdt_address & 0xFFF),
102-
((sizeof(ACPISDTHeader) + (rsdp->rsdt_address & 0xFFF) + 0xFFF)
103-
& ~0xFFF));
125+
VMemUnmap((uint64_t)g_rsdt - (rsdp->rsdt_address & 0xFFF), ((sizeof(ACPISDTHeader) + (rsdp->rsdt_address & 0xFFF) + 0xFFF) & ~0xFFF));
104126
return false;
105127
}
106-
// Remap with the full table length
107-
uint32_t rsdt_size = rsdt->header.length;
108-
// Remember the old header mapping so we can free it afterward
109-
void* old_rsdt = rsdt;
110-
uint32_t old_offset = rsdp->rsdt_address & 0xFFF;
111-
rsdt = (ACPIRSDT*)MapACPITable(rsdp->rsdt_address, rsdt_size);
112-
// Now unmap the temporary header‐only region
113-
VMemUnmap((uint64_t)old_rsdt - old_offset,
114-
((sizeof(ACPISDTHeader) + old_offset + 0xFFF) & ~0xFFF));
115-
116-
PrintKernel("ACPI: RSDT mapped, length=");
117-
PrintKernelInt(rsdt_size);
118-
PrintKernel("\n");
119-
120-
// Find FADT
121-
uint32_t entries = (rsdt_size - sizeof(ACPISDTHeader)) / 4;
122-
for (uint32_t i = 0; i < entries; i++) {
123-
ACPISDTHeader* header = (ACPISDTHeader*)MapACPITable(
124-
rsdt->table_pointers[i],
125-
sizeof(ACPISDTHeader)
126-
);
127-
if (!header) continue;
128-
129-
bool is_fadt = FastMemcmp(header->signature, ACPI_FADT_SIG, 4) == 0;
130-
uint32_t table_length = header->length;
131-
uint32_t header_offset = rsdt->table_pointers[i] & 0xFFF;
132-
133-
// Unmap the header mapping now that we've inspected it
134-
VMemUnmap(
135-
(uint64_t)header - header_offset,
136-
( (sizeof(ACPISDTHeader) + header_offset + 0xFFF) & ~0xFFF )
137-
);
138-
139-
if (is_fadt) {
140-
PrintKernel("ACPI: Found FADT\n");
141-
g_fadt = (ACPIFADT*)MapACPITable(
142-
rsdt->table_pointers[i],
143-
table_length
144-
);
145-
break;
146-
}
128+
129+
uint32_t rsdt_size = g_rsdt->header.length;
130+
VMemUnmap((uint64_t)g_rsdt - (rsdp->rsdt_address & 0xFFF), ((sizeof(ACPISDTHeader) + (rsdp->rsdt_address & 0xFFF) + 0xFFF) & ~0xFFF));
131+
g_rsdt = (ACPIRSDT*)MapACPITable(rsdp->rsdt_address, rsdt_size);
132+
if (!g_rsdt) {
133+
PrintKernelError("ACPI: Failed to map full RSDT\n");
134+
return false;
147135
}
148-
149-
PrintKernelError("ACPI: FADT not found or invalid\n");
150-
return false;
136+
137+
g_fadt = (ACPIFADT*)AcpiFindTable(ACPI_FADT_SIG);
138+
if (!g_fadt) {
139+
PrintKernelError("ACPI: FADT not found or invalid\n");
140+
return false;
141+
}
142+
143+
g_acpi_initialized = true;
144+
PrintKernelSuccess("ACPI: Subsystem initialized\n");
145+
return true;
146+
}
147+
148+
void ACPIResetProcedure() {
149+
PrintKernel("ACPI: Unmounting Filesystems...\n");
150+
VfsUnmountAll();
151+
PrintKernelSuccess("ACPI: Filesystems unmounted\n");
152+
153+
PrintKernel("ACPI: Stopping all processes and services...\n");
154+
KillAllProcess("SHUTDOWN");
155+
PrintKernelSuccess("ACPI: All processes and services stopped\n");
151156
}
152157

153158
void ACPIShutdown(void) {
154-
if (!g_acpi_initialized || !g_fadt) {
155-
PrintKernel("ACPI: Shutdown not available, using fallback\n");
156-
outw(0x604, 0x2000);
157-
return;
158-
}
159-
160159
PrintKernel("ACPI: Initiating shutdown...\n");
161160

162161
// Enable ACPI mode if needed
163162
if (g_fadt->smi_command_port && g_fadt->acpi_enable) {
164163
PrintKernel("ACPI: Enabling ACPI mode via SMI\n");
165164
outb(g_fadt->smi_command_port, g_fadt->acpi_enable);
166165
}
167-
166+
167+
ACPIResetProcedure();
168+
168169
// Try multiple shutdown methods
169-
uint16_t shutdown_values[] = {0x2000, 0x3C00, 0x1400, 0x0000};
170-
171170
for (int i = 0; i < 4; i++) {
171+
const uint16_t shutdown_values[] = {0x2000, 0x3C00, 0x1400, 0x0000};
172172
PrintKernel("ACPI: Trying shutdown value 0x");
173173
PrintKernelHex(shutdown_values[i]);
174174
PrintKernel(" on port 0x");
@@ -180,18 +180,17 @@ void ACPIShutdown(void) {
180180
// Wait a bit
181181
delay(10);
182182
}
183-
184-
// Fallback methods
185-
PrintKernel("ACPI: Trying QEMU shutdown\n");
186-
outw(0x604, 0x2000);
187-
183+
188184
PrintKernel("ACPI: Trying Bochs shutdown\n");
189185
outw(0xB004, 0x2000);
190186

191187
PrintKernelError("ACPI: All shutdown methods failed\n");
192188
}
193189

194190
void ACPIReboot(void) {
191+
192+
ACPIResetProcedure();
193+
195194
PrintKernel("ACPI: Initiating reboot...\n");
196195

197196
// Try keyboard controller reset

drivers/ACPI.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,5 @@ typedef struct {
8282
// Function declarations
8383
bool ACPIInit(void);
8484
void ACPIShutdown(void);
85-
void ACPIReboot(void);
85+
void ACPIReboot(void);
86+
void* AcpiFindTable(const char* signature);

fs/EXT/Ext2.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ int Ext2ReadBlock(uint32_t block, void* buffer) {
118118
return 0;
119119
}
120120

121-
static FileSystemDriver ext2_driver = {"EXT2", Ext2Detect, Ext2Mount};
121+
static FileSystemDriver ext2_driver = {"EXT2", Ext2Detect, Ext2Mount, Ext2Unmount};
122122

123123
int Ext2Mount(BlockDevice* device, const char* mount_point) {
124124
// Prepare or reuse per-device volume
@@ -222,11 +222,37 @@ int Ext2Mount(BlockDevice* device, const char* mount_point) {
222222
}
223223
PrintKernelF("EXT2: Mounted filesystem\n");
224224

225-
PrintKernelSuccess("EXT2: Filesystem initialized successfully.\n");
225+
PrintKernelSuccess("EXT2: Filesystem mounted.\n");
226226
rust_rwlock_write_unlock(volume.lock);
227227
return 0;
228228
}
229229

230+
int Ext2Unmount(BlockDevice* device) {
231+
if (!device) { return -1; }
232+
int device_id = device->id;
233+
if (device_id < 0 || device_id >= MAX_BLOCK_DEVICES) { return -1; }
234+
Ext2Volume* vol = g_ext2_by_dev[device_id];
235+
if (!vol) { return -1; } // Not mounted
236+
RustRwLock* lock = vol->lock;
237+
if (lock) {
238+
rust_rwlock_write_lock(lock, GetCurrentProcess()->pid);
239+
}
240+
if (g_ext2_active == vol) {
241+
g_ext2_active = NULL;
242+
}
243+
if (vol->group_descs) {
244+
KernelFree(vol->group_descs);
245+
vol->group_descs = NULL;
246+
}
247+
g_ext2_by_dev[device_id] = NULL;
248+
if (lock) {
249+
rust_rwlock_write_unlock(lock);
250+
rust_rwlock_free(lock);
251+
}
252+
KernelFree(vol);
253+
return 0;
254+
}
255+
230256
int Ext2ReadInode(uint32_t inode_num, Ext2Inode* inode) {
231257
rust_rwlock_read_lock(volume.lock, GetCurrentProcess()->pid);
232258
if (inode_num == 0) {

fs/EXT/Ext2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ typedef struct {
101101

102102
// Function prototypes for VFS integration
103103
int Ext2Mount(BlockDevice* device, const char* mount_point);
104+
int Ext2Unmount(BlockDevice* device);
104105
int Ext2Detect(BlockDevice* device);
105106
void Ext2SetActive(BlockDevice* device);
106107
int Ext2ReadFile(const char* path, void* buffer, uint32_t max_size);

0 commit comments

Comments
 (0)