Skip to content

Commit 1e4ccc9

Browse files
authored
Merge pull request #114 from assembler-0/Development
RW lock improvements, EXT2 delete
2 parents 0bbde84 + 06c4c8b commit 1e4ccc9

File tree

14 files changed

+1312
-169
lines changed

14 files changed

+1312
-169
lines changed

README.md

Lines changed: 103 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,13 @@
1414

1515
![License](https://img.shields.io/badge/License-GPLv2-orange)
1616

17-
![Version](https://img.shields.io/badge/Current%20Version-v0.0.1%20beta6-blue)
17+
![Version](https://img.shields.io/badge/Current%20Version-v0.0.1%20beta6.1-blue)
1818

19-
![Build](https://img.shields.io/badge/GCC-faliling-red)
20-
21-
![Build](https://img.shields.io/badge/Clang-passing-brightgreen)
19+
![Build](https://img.shields.io/badge/Build-passing-brightgreen)
2220

2321
## About
2422

25-
VoidFrame is a 64-bit syscall-less **monolithic** kernel designed for the x86_64 architecture written in C and assembly (nasm).
23+
VoidFrame is a 64-bit syscall-less **monolithic** kernel (sounds weird and contradicting right?) designed for the x86_64 architecture written in C and assembly (nasm).
2624
This kernel was intended and targeted for people who want to learn about operating systems and want to make a piece of their own.
2725
As the designer of this kernel, I wanted to make something that is simple, fast, secure and easy to understand.
2826
Which obviously means that it is not a perfect kernel. And it breaks all the time.
@@ -36,7 +34,7 @@ It would be amazing if you could contribute to this project!
3634
- ninja >= 1.11
3735
- clang >= 18.0.0 (or any C-compliant compiler)
3836
- nasm >= 2.16
39-
- qemu >= 7.0.0
37+
- qemu >= 7.0.0 (minimum, failed to run on Limbo emulator (v5.x))
4038
- mkfs.fat (dosfstools)
4139
- mkfs.ext2
4240
- grub-mkrescue
@@ -63,4 +61,102 @@ meson setup build -Dexclude_extra_objects=true
6361
cd build
6462
ninja
6563
ninja runmin
66-
```
64+
```
65+
66+
## Features
67+
### Architecture
68+
- [x] x86_64
69+
- [ ] AArch64
70+
- [ ] MIPS
71+
- [ ] SPARC
72+
- [ ] RISC-V (RV64)
73+
- [ ] Power (modern)
74+
### Boot
75+
- [x] Multiboot2
76+
- [x] GRUB (BIOS)
77+
- [ ] GRUB (UEFI)
78+
- [ ] GRUB (Hybrid)
79+
- [x] Vesa (VBE)
80+
- [x] Multiboot2 Info parsing
81+
### Core
82+
- [x] Multi-tasking (MLFQ)
83+
- [x] Per-process authentication check (Astra)
84+
- [x] Dynamic ML-inspired PIT frequency scaling (DynamoX)
85+
- [x] Virtual Memory (canonical)
86+
- [x] Physical Memory
87+
- [x] Memory Pool
88+
- [x] AVX2/SSE2 accelerated memory operations
89+
- [x] Memory & user protection
90+
- [x] Memory canaries, guard pages
91+
- [x] Per-process memory checks (Cerberus)
92+
- [x] Stack guard
93+
- [x] Stack trace
94+
- [x] Heap (Class-based)
95+
- [x] Paging
96+
- [x] Interrupts
97+
- [x] Process Management
98+
- [x] Locks (MCS/RW/norm)
99+
- [x] Atomics
100+
- [x] IPC
101+
- [x] Compositor
102+
- [x] Embedded shell
103+
- [x] Builtin Editor
104+
- [x] ELF64 loader
105+
- [ ] PE32+/COFF loader
106+
- [ ] a.out loader
107+
### Filesystems
108+
- FAT1x
109+
- [x] Read
110+
- [x] Write
111+
- [x] Create
112+
- [x] Delete
113+
- [x] List
114+
- EXT2
115+
- [x] Read
116+
- [x] Write
117+
- [x] Create
118+
- [x] Delete
119+
- [x] List
120+
- VFRFS (VoidFrame RAMFS)
121+
- [x] Read
122+
- [x] Write
123+
- [x] Create
124+
- [x] Delete
125+
- [x] List
126+
- ISO9660 (RO)
127+
- [x] Read
128+
- [x] List
129+
- VFS (Virtual File System)
130+
- [x] Full abstraction
131+
- [x] EXT2
132+
- [x] FAT1x
133+
- [x] VFRFS
134+
- [ ] ISO9660
135+
### Drivers
136+
- Network
137+
- [x] RTL8139 (PCI)
138+
- Sound
139+
- [x] SB16 (PCI)
140+
- USB
141+
- [x] xHCI
142+
- VirtIO
143+
- [x] Block
144+
- Graphics
145+
- [x] Vesa (VBE)
146+
- [x] VMWare SVGA II
147+
- [x] VGA text mode
148+
- Timer
149+
- [x] PIT
150+
- [x] PIC
151+
- [x] APIC (not working)
152+
- [x] RTC
153+
- Generic
154+
- [x] PCI
155+
- [x] ISA
156+
- [x] xHCI
157+
- [x] Serial
158+
- [x] PS/2
159+
- [x] LPT
160+
- Storage
161+
- [x] PATA (IDE)
162+
- [x] VirtIO Block

docs/ARCHITECTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# The VoidFrame monolithic kernel 💫 v0.0.1-beta6
1+
# The VoidFrame monolithic kernel 💫 v0.0.1-beta6.1
22

33
## Table of Contents
44

drivers/RTC/Rtc.c

Lines changed: 120 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,131 @@
1-
#include "Rtc.h"
1+
#include "RTC/Rtc.h"
22
#include "Io.h"
3+
#include "stdbool.h"
34

4-
#define CMOS_ADDRESS 0x70
5-
#define CMOS_DATA 0x71
6-
7-
// CMOS Register numbers
8-
#define CMOS_REG_SECONDS 0x00
9-
#define CMOS_REG_MINUTES 0x02
10-
#define CMOS_REG_HOURS 0x04
11-
#define CMOS_REG_DAY 0x07
12-
#define CMOS_REG_MONTH 0x08
13-
#define CMOS_REG_YEAR 0x09
14-
#define CMOS_REG_CENTURY 0x32 // Common on newer systems
15-
16-
#define CMOS_REG_STATUS_A 0x0A
17-
#define CMOS_REG_STATUS_B 0x0B
18-
19-
static uint8_t cmos_read(uint8_t reg) {
20-
// Select the register, making sure NMI is disabled
21-
outb(CMOS_ADDRESS, (1 << 7) | reg);
22-
// Read the data
23-
return inb(CMOS_DATA);
5+
#define RTC_CMOS_ADDRESS 0x70
6+
#define RTC_CMOS_DATA 0x71
7+
8+
#define RTC_SECONDS 0x00
9+
#define RTC_MINUTES 0x02
10+
#define RTC_HOURS 0x04
11+
#define RTC_DAY_OF_WEEK 0x06
12+
#define RTC_DAY_OF_MONTH 0x07
13+
#define RTC_MONTH 0x08
14+
#define RTC_YEAR 0x09
15+
#define RTC_CENTURY 0x32 // Most common century register
16+
#define RTC_STATUS_A 0x0A
17+
#define RTC_STATUS_B 0x0B
18+
#define RTC_STATUS_C 0x0C
19+
20+
typedef rtc_time_t RtcDateTime;
21+
22+
static uint8_t Rtc_ReadRegister(uint8_t reg) {
23+
outb(RTC_CMOS_ADDRESS, reg);
24+
return inb(RTC_CMOS_DATA);
2425
}
2526

26-
static int get_update_in_progress_flag() {
27-
return cmos_read(CMOS_REG_STATUS_A) & 0x80;
27+
static void Rtc_WriteRegister(uint8_t reg, uint8_t value) {
28+
outb(RTC_CMOS_ADDRESS, reg);
29+
outb(RTC_CMOS_DATA, value);
2830
}
2931

30-
static uint8_t bcd_to_bin(uint8_t bcd) {
31-
return (bcd & 0x0F) + ((bcd >> 4) * 10);
32+
int Rtc_BcdToBinary(uint8_t bcd) {
33+
return (bcd & 0x0F) + ((bcd / 16) * 10);
3234
}
3335

34-
void RtcReadTime(rtc_time_t* rtc_time) {
35-
rtc_time_t last_time;
36-
uint8_t status_b;
37-
38-
// The robust way to read the RTC is to read it twice and see if the
39-
// values match. This ensures an update didn't happen in the middle of our read.
40-
do {
41-
// Wait until no update is in progress
42-
while (get_update_in_progress_flag()) {}
43-
44-
rtc_time->second = cmos_read(CMOS_REG_SECONDS);
45-
rtc_time->minute = cmos_read(CMOS_REG_MINUTES);
46-
rtc_time->hour = cmos_read(CMOS_REG_HOURS);
47-
rtc_time->day = cmos_read(CMOS_REG_DAY);
48-
rtc_time->month = cmos_read(CMOS_REG_MONTH);
49-
rtc_time->year = cmos_read(CMOS_REG_YEAR);
50-
rtc_time->century = cmos_read(CMOS_REG_CENTURY);
51-
// Make a copy of the values we just read
52-
last_time = *rtc_time;
53-
54-
// Wait again to ensure we are past the update
55-
while (get_update_in_progress_flag()){}
56-
57-
// Read a second time
58-
last_time.second = cmos_read(CMOS_REG_SECONDS);
59-
last_time.minute = cmos_read(CMOS_REG_MINUTES);
60-
last_time.hour = cmos_read(CMOS_REG_HOURS);
61-
last_time.day = cmos_read(CMOS_REG_DAY);
62-
last_time.month = cmos_read(CMOS_REG_MONTH);
63-
last_time.year = cmos_read(CMOS_REG_YEAR);
64-
#ifdef VF_CONFIG_RTC_CENTURY
65-
last_time.century = cmos_read(CMOS_REG_CENTURY);
66-
#endif
67-
68-
} while ( (last_time.second != rtc_time->second) ||
69-
(last_time.minute != rtc_time->minute) ||
70-
(last_time.hour != rtc_time->hour) ||
71-
(last_time.day != rtc_time->day) ||
72-
(last_time.month != rtc_time->month) ||
73-
(last_time.year != rtc_time->year)
74-
#ifdef VF_CONFIG_RTC_CENTURY
75-
|| (last_time.century != rtc_time->century)
76-
#endif
77-
);
78-
79-
80-
// Now that we have a stable read, convert from BCD if necessary
81-
status_b = cmos_read(CMOS_REG_STATUS_B);
82-
83-
if (!(status_b & 0x04)) { // Bit 2 clear means BCD mode
84-
rtc_time->second = bcd_to_bin(rtc_time->second);
85-
rtc_time->minute = bcd_to_bin(rtc_time->minute);
86-
// Handle 12/24 hour clock for the hour value
87-
rtc_time->hour = ((rtc_time->hour & 0x7F) + 12 * ((rtc_time->hour & 0x80) != 0)) % 24;
88-
rtc_time->day = bcd_to_bin(rtc_time->day);
89-
rtc_time->month = bcd_to_bin(rtc_time->month);
90-
rtc_time->year = bcd_to_bin(rtc_time->year);
36+
uint8_t Rtc_BinaryToBcd(uint8_t binary) {
37+
return ((binary / 10) << 4) | (binary % 10);
38+
}
39+
40+
static bool Rtc_IsUpdating() {
41+
outb(RTC_CMOS_ADDRESS, 0x80 | RTC_STATUS_A); // select reg A, NMI masked
42+
return (inb(RTC_CMOS_DATA) & 0x80) != 0; // UIP bit
43+
}
44+
45+
void RtcReadTime(RtcDateTime *dateTime) {
46+
uint8_t second, minute, hour, day, month, year, century;
47+
uint8_t statusB;
48+
49+
// Wait until the update in progress bit is 0
50+
while (Rtc_IsUpdating());
51+
52+
// Read RTC registers
53+
second = Rtc_ReadRegister(RTC_SECONDS);
54+
minute = Rtc_ReadRegister(RTC_MINUTES);
55+
hour = Rtc_ReadRegister(RTC_HOURS);
56+
day = Rtc_ReadRegister(RTC_DAY_OF_MONTH);
57+
month = Rtc_ReadRegister(RTC_MONTH);
58+
year = Rtc_ReadRegister(RTC_YEAR);
59+
century = Rtc_ReadRegister(RTC_CENTURY); // Read century byte
60+
61+
statusB = Rtc_ReadRegister(RTC_STATUS_B);
62+
63+
if (!(statusB & 0x04)) { // If BCD mode
64+
dateTime->second = Rtc_BcdToBinary(second);
65+
dateTime->minute = Rtc_BcdToBinary(minute);
66+
dateTime->hour = Rtc_BcdToBinary(hour);
67+
dateTime->day = Rtc_BcdToBinary(day);
68+
dateTime->month = Rtc_BcdToBinary(month);
69+
dateTime->year = Rtc_BcdToBinary(year);
70+
dateTime->century = Rtc_BcdToBinary(century);
71+
} else { // Binary mode
72+
dateTime->second = second;
73+
dateTime->minute = minute;
74+
dateTime->hour = hour;
75+
dateTime->day = day;
76+
dateTime->month = month;
77+
dateTime->year = year;
78+
dateTime->century = century;
9179
}
92-
#ifdef VF_CONFIG_RTC_CENTURY
93-
{
94-
uint16_t cval = (uint16_t)rtc_time->century;
95-
if (cval != 0) {
96-
cval = bcd_to_bin((uint8_t)cval);
97-
rtc_time->year += (uint16_t)(cval * 100);
98-
} else {
99-
rtc_time->year += 2000;
100-
}
80+
81+
if (!(statusB & 0x02) && (dateTime->hour & 0x80)) { // 12-hour format and PM
82+
dateTime->hour = ((dateTime->hour & 0x7F) + 12) % 24;
83+
}
84+
85+
// Calculate full year
86+
dateTime->year += dateTime->century * 100;
87+
}
88+
89+
void RtcSetTime(const RtcDateTime *dateTime) {
90+
uint8_t statusB;
91+
uint8_t second, minute, hour, day, month, year, century;
92+
93+
// Read current status B to preserve settings
94+
statusB = Rtc_ReadRegister(RTC_STATUS_B);
95+
96+
// Disable NMI and updates while setting time
97+
Rtc_WriteRegister(RTC_CMOS_ADDRESS, RTC_STATUS_B | 0x80); // Disable NMI
98+
Rtc_WriteRegister(RTC_STATUS_B, statusB | 0x80); // Disable updates
99+
100+
// Convert to BCD if necessary
101+
if (!(statusB & 0x04)) { // If BCD mode
102+
second = Rtc_BinaryToBcd(dateTime->second);
103+
minute = Rtc_BinaryToBcd(dateTime->minute);
104+
hour = Rtc_BinaryToBcd(dateTime->hour);
105+
day = Rtc_BinaryToBcd(dateTime->day);
106+
month = Rtc_BinaryToBcd(dateTime->month);
107+
year = Rtc_BinaryToBcd(dateTime->year % 100);
108+
century = Rtc_BinaryToBcd(dateTime->year / 100);
109+
} else { // Binary mode
110+
second = dateTime->second;
111+
minute = dateTime->minute;
112+
hour = dateTime->hour;
113+
day = dateTime->day;
114+
month = dateTime->month;
115+
year = dateTime->year % 100;
116+
century = dateTime->year / 100;
101117
}
102-
#else
103-
rtc_time->year += 2000;
104-
#endif
118+
119+
// Write to RTC registers
120+
Rtc_WriteRegister(RTC_SECONDS, second);
121+
Rtc_WriteRegister(RTC_MINUTES, minute);
122+
Rtc_WriteRegister(RTC_HOURS, hour);
123+
Rtc_WriteRegister(RTC_DAY_OF_MONTH, day);
124+
Rtc_WriteRegister(RTC_MONTH, month);
125+
Rtc_WriteRegister(RTC_YEAR, year);
126+
Rtc_WriteRegister(RTC_CENTURY, century);
127+
128+
// Re-enable updates and NMI
129+
Rtc_WriteRegister(RTC_STATUS_B, statusB);
130+
Rtc_WriteRegister(RTC_CMOS_ADDRESS, RTC_STATUS_B); // Re-enable NMI
105131
}

drivers/RTC/Rtc.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef VOIDFRAME_RTC_H
22
#define VOIDFRAME_RTC_H
33

4-
#include <stdint.h>
4+
#include "stdint.h"
55

66
// A structure to hold the date and time.
77
typedef struct {
@@ -16,5 +16,8 @@ typedef struct {
1616

1717
// Reads the current date and time from the RTC into the provided struct.
1818
void RtcReadTime(rtc_time_t* rtc_time);
19+
void RtcSetTime(const rtc_time_t *dateTime);
20+
uint8_t Rtc_BinaryToBcd(uint8_t binary);
21+
int Rtc_BcdToBinary(uint8_t bcd);
1922

2023
#endif // VOIDFRAME_RTC_H

0 commit comments

Comments
 (0)