aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/drivers/rtc.c91
-rw-r--r--kernel/features/mm.c11
-rw-r--r--kernel/features/proc.c6
-rw-r--r--kernel/features/syscall.c4
-rw-r--r--kernel/inc/proc.h1
-rw-r--r--kernel/inc/rtc.h21
-rw-r--r--kernel/main.c15
-rw-r--r--libs/libc/crt/crt0.c22
-rw-r--r--libs/libc/inc/random.h1
-rw-r--r--libs/libc/inc/sys.h2
-rw-r--r--libs/libc/random.c32
-rw-r--r--libs/libc/sanitize.c4
-rw-r--r--libs/libc/sys.c5
13 files changed, 180 insertions, 35 deletions
diff --git a/kernel/drivers/rtc.c b/kernel/drivers/rtc.c
new file mode 100644
index 0000000..a82864f
--- /dev/null
+++ b/kernel/drivers/rtc.c
@@ -0,0 +1,91 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#include <cpu.h>
+#include <def.h>
+#include <fs.h>
+#include <mem.h>
+#include <rtc.h>
+#include <str.h>
+#include <timer.h>
+
+static u8 rtc_busy(void)
+{
+ outb(0x70, 0x0A);
+ return (inb(0x71) & 0x80) == 0x80;
+}
+
+static u8 rtc_register(u8 reg)
+{
+ outb(0x70, reg);
+ return inb(0x71);
+}
+
+static void rtc_fill(struct rtc *rtc)
+{
+ while (rtc_busy())
+ ;
+
+ rtc->second = rtc_register(0x00);
+ rtc->minute = rtc_register(0x02);
+ rtc->hour = rtc_register(0x04);
+ rtc->day = rtc_register(0x07);
+ rtc->month = rtc_register(0x08);
+ rtc->year = rtc_register(0x09);
+ //obj.century = 20; //rtc_register(0x00);
+}
+
+struct rtc rtc_read(void)
+{
+ struct rtc rtc = { 0 };
+ rtc_fill(&rtc);
+
+ struct rtc last = { 0 };
+ do {
+ rtc_fill(&last);
+ } while (memcmp(&rtc, &last, sizeof(rtc)) != 0);
+
+ u32 reg_b = rtc_register(0x0B);
+
+ if (!(reg_b & 0x04)) {
+ rtc.second = (u8)((rtc.second & 0x0F) + ((rtc.second / 16) * 10));
+ rtc.minute = (u8)((rtc.minute & 0x0F) + ((rtc.minute / 16) * 10));
+ rtc.hour = (u8)(((rtc.hour & 0x0F) + (((rtc.hour & 0x70) / 16) * 10)) |
+ (rtc.hour & 0x80));
+ rtc.day = (u8)((rtc.day & 0x0F) + ((rtc.day / 16) * 10));
+ rtc.month = (u8)((rtc.month & 0x0F) + ((rtc.month / 16) * 10));
+ rtc.year = (rtc.year & 0x0F) + ((rtc.year / 16) * 10);
+ /* rtc.century = (century & 0x0F) + ((century / 16) * 10); */
+ }
+
+ if (!(reg_b & 0x02) && (rtc.hour & 0x80))
+ rtc.hour = (u8)(((rtc.hour & 0x7F) + 12) % 24);
+
+ return rtc;
+}
+
+u32 rtc_stamp(void)
+{
+ struct rtc rtc = rtc_read();
+ return timer_get() + rtc.second + rtc.minute * 60 + rtc.hour * 360 + rtc.day * 360 * 24 +
+ rtc.year * 360 * 24 * 365;
+}
+
+static res rtc_dev_read(void *buf, u32 offset, u32 count, struct device *dev)
+{
+ UNUSED(offset);
+ UNUSED(dev);
+
+ u32 stamp = rtc_stamp();
+ memcpy_user(buf, &stamp, MIN(count, sizeof(stamp)));
+
+ return MIN(count, sizeof(stamp));
+}
+
+CLEAR void rtc_install(void)
+{
+ struct device *dev = zalloc(sizeof(*dev));
+ dev->name = strdup("rtc");
+ dev->type = DEV_CHAR;
+ dev->read = rtc_dev_read;
+ device_add(dev);
+}
diff --git a/kernel/features/mm.c b/kernel/features/mm.c
index 76049ef..a0ed280 100644
--- a/kernel/features/mm.c
+++ b/kernel/features/mm.c
@@ -84,6 +84,9 @@ void page_fault_handler(struct regs *r)
// Print!
printf("%s process tried to %s a %s page at [vaddr=%x; paddr=%x]\n", super, operation, type,
vaddr, paddr);
+ if (proc && vaddr > proc->regs.ebp - PROC_STACK_SIZE - PAGE_SIZE &&
+ vaddr < proc->regs.ebp + PAGE_SIZE)
+ print("Probably a stack overflow\n");
printf("Sections: [vaddr_section=%s; paddr_section=%s; eip_section=%s]\n",
page_fault_section(vaddr), page_fault_section(paddr), page_fault_section(r->eip));
@@ -667,10 +670,13 @@ CLEAR void memory_install(struct mem_info *mem_info, struct vid_info *vid_info)
/* printf("Memory region: %x-%x\n", p->lbase, p->lbase + size); */
if (p->type == MEMORY_AVAILABLE) {
- physical_set_free(memory_range_around(p->lbase, size / PAGE_SIZE));
+ physical_set_free(memory_range_around(p->lbase, size));
memory_total += size;
} else if (p->type == MEMORY_DEFECT) {
printf("Defect memory at 0x%x-0x%x!\n", p->lbase, p->lbase + size);
+ physical_set_used(memory_range_around(p->lbase, size));
+ } else {
+ physical_set_used(memory_range_around(p->lbase, size));
}
}
@@ -685,6 +691,9 @@ CLEAR void memory_install(struct mem_info *mem_info, struct vid_info *vid_info)
memory_used = 0;
printf("Detected memory: %dKiB (%dMiB)\n", memory_total >> 10, memory_total >> 20);
+ // Set first MiB 'used' (bootloader(s), VESA tables, memory maps, ...)
+ physical_set_used(memory_range(0, 0x00100000));
+
// Map kernel
memory_map_identity(&kernel_dir, kernel_ro_memory_range(), MEMORY_READONLY);
memory_map_identity(&kernel_dir, kernel_rw_memory_range(), MEMORY_NONE);
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index 21e63b3..0cca50f 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -183,6 +183,7 @@ void proc_yield(struct regs *r)
scheduler(r);
}
+// TODO: Rewrite block/unblock mechanisms
void proc_block(u32 id, enum proc_block_type type, u32 func_ptr)
{
u8 already_exists = 0;
@@ -298,8 +299,6 @@ struct proc *proc_make(enum proc_priv priv)
void proc_stack_push(struct proc *proc, u32 data)
{
- assert(proc->regs.useresp > sizeof(data));
-
struct page_dir *prev;
memory_backup_dir(&prev);
memory_switch_dir(proc->page_dir);
@@ -560,6 +559,8 @@ NORETURN void proc_init(void)
// TODO: Reimplement hlt privileges in idle proc (SMEP!)
struct proc *kernel_proc = proc_make(PROC_PRIV_NONE);
assert(elf_load("/bin/idle", kernel_proc) == EOK);
+ proc_stack_push(kernel_proc, 0);
+ proc_stack_push(kernel_proc, 0);
kernel_proc->state = PROC_BLOCKED;
kernel_proc->quantum.val = 0;
kernel_proc->quantum.cnt = 0;
@@ -570,6 +571,7 @@ NORETURN void proc_init(void)
struct proc *init = proc_make(PROC_PRIV_ROOT);
assert(elf_load("/bin/init", init) == EOK);
proc_stack_push(init, 0);
+ proc_stack_push(init, 0);
current = list_first_data(proc_list_running, init);
_eip = init->regs.eip;
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index b5c08da..98a7ff9 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -121,10 +121,6 @@ static void syscall_handler(struct regs *r)
proc_yield(r);
break;
}
- case SYS_TIME: {
- r->eax = timer_get();
- break;
- }
// TODO: Reimplement network functions using VFS
default: {
printf("Unknown syscall %d!\n", num);
diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h
index 8a172c9..d20a1b0 100644
--- a/kernel/inc/proc.h
+++ b/kernel/inc/proc.h
@@ -10,6 +10,7 @@
#include <sys.h>
#define PROC_QUANTUM 42 // Milliseconds or something // TODO
+#define PROC_STACK_SIZE (1 << 20) // 1MiB
#define EFLAGS_ALWAYS 0x2 // Always one
#define EFLAGS_INTERRUPTS 0x200 // Enable interrupts
diff --git a/kernel/inc/rtc.h b/kernel/inc/rtc.h
new file mode 100644
index 0000000..44a9c9e
--- /dev/null
+++ b/kernel/inc/rtc.h
@@ -0,0 +1,21 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#ifndef RTC_H
+#define RTC_H
+
+#include <def.h>
+
+struct rtc {
+ u8 second;
+ u8 minute;
+ u8 hour;
+ u8 day;
+ u8 month;
+ u32 year;
+};
+
+struct rtc rtc_read(void);
+u32 rtc_stamp(void);
+CLEAR void rtc_install(void);
+
+#endif
diff --git a/kernel/main.c b/kernel/main.c
index 6752fcf..faac719 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -14,12 +14,16 @@
#include <net.h>
#include <pci.h>
#include <random.h>
+#include <rtc.h>
#include <serial.h>
#include <syscall.h>
#include <timer.h>
-void kernel_main(struct mem_info *mem_info, struct vid_info *vid_info); // Decl
-void kernel_main(struct mem_info *mem_info, struct vid_info *vid_info)
+extern u32 __stack_chk_guard;
+u32 __stack_chk_guard;
+
+int kernel_main(struct mem_info *mem_info, struct vid_info *vid_info); // Decl
+int kernel_main(struct mem_info *mem_info, struct vid_info *vid_info)
{
// Serial connection
serial_install();
@@ -31,7 +35,9 @@ void kernel_main(struct mem_info *mem_info, struct vid_info *vid_info)
cpu_enable_features();
cpu_print();
- srand(rand());
+
+ srand(rtc_stamp());
+ __stack_chk_guard = rand();
// Install drivers
vfs_install();
@@ -40,6 +46,7 @@ void kernel_main(struct mem_info *mem_info, struct vid_info *vid_info)
pci_install();
interrupts_install();
timer_install();
+ rtc_install();
keyboard_install();
mouse_install();
fb_install(vid_info);
@@ -52,4 +59,6 @@ void kernel_main(struct mem_info *mem_info, struct vid_info *vid_info)
syscall_init();
proc_init();
+
+ return 1;
}
diff --git a/libs/libc/crt/crt0.c b/libs/libc/crt/crt0.c
index 6c38474..3bd413f 100644
--- a/libs/libc/crt/crt0.c
+++ b/libs/libc/crt/crt0.c
@@ -1,18 +1,28 @@
// MIT License, Copyright (c) 2021 Marvin Borner
+#include <assert.h>
#include <def.h>
+#include <random.h>
#include <sys.h>
#ifdef USER
-extern int main(int, char **);
+extern u32 __stack_chk_guard;
+u32 __stack_chk_guard;
-void _start(void);
-void _start(void)
+int main(int, char **);
+
+int _start(int argc, char **argv);
+int _start(int argc, char **argv)
{
- exit(main(0, NULL));
- while (1)
- ;
+ u32 stamp = 0;
+ assert(read("/dev/rtc", &stamp, 0, sizeof(stamp)) == sizeof(stamp) && stamp);
+ srand(stamp);
+ rand_fill(&__stack_chk_guard, sizeof(__stack_chk_guard));
+
+ exit(main(argc, argv));
+
+ return 1;
}
#endif
diff --git a/libs/libc/inc/random.h b/libs/libc/inc/random.h
index 6360625..1b41df5 100644
--- a/libs/libc/inc/random.h
+++ b/libs/libc/inc/random.h
@@ -9,6 +9,7 @@
void srand(u32 seed);
u32 rand(void);
+void rand_fill(void *buf, u32 size);
char *randstr(u32 size);
#endif
diff --git a/libs/libc/inc/sys.h b/libs/libc/inc/sys.h
index b435899..58d7969 100644
--- a/libs/libc/inc/sys.h
+++ b/libs/libc/inc/sys.h
@@ -28,7 +28,6 @@ enum sys {
SYS_EXIT, // Exit current process
SYS_BOOT, // Boot functions (e.g. reboot/shutdown)
SYS_YIELD, // Switch to next process
- SYS_TIME, // Get kernel time
/* SYS_NET_OPEN, // Open network socket */
/* SYS_NET_CLOSE, // Close network socket */
/* SYS_NET_CONNECT, // Connect to destination */
@@ -75,7 +74,6 @@ res poll(const char **files) NONNULL;
res exec(const char *path, ...) ATTR((nonnull(1))) SENTINEL;
res yield(void);
res boot(u32 cmd);
-u32 time(void);
res sys_alloc(u32 size, u32 *addr) NONNULL;
res sys_free(void *ptr) NONNULL;
diff --git a/libs/libc/random.c b/libs/libc/random.c
index 983357f..2cd7f93 100644
--- a/libs/libc/random.c
+++ b/libs/libc/random.c
@@ -15,36 +15,52 @@ void srand(u32 seed)
g_seed = seed;
}
-static u32 default_rand(void)
+static u32 rand_default(void)
{
g_seed = g_seed * 1103515245 + 12345;
return (g_seed >> 16) & 0x7FFF;
}
-u32 rand(void)
+static u32 rand_once(void)
{
#ifdef KERNEL
- u32 rd;
+ u32 val = 0;
if (cpu_extended_features.ebx & CPUID_EXT_FEAT_EBX_RDSEED) {
__asm__ volatile("1:\n"
"rdseed %0\n"
"jnc 1b\n"
- : "=r"(rd));
+ : "=r"(val));
} else if (cpu_features.ecx & CPUID_FEAT_ECX_RDRND) {
__asm__ volatile("1:\n"
"rdrand %0\n"
"jnc 1b\n"
- : "=r"(rd));
+ : "=r"(val));
} else {
- rd = default_rand();
+ val = rand_default();
}
- return rd;
+ return val;
#else
- return default_rand();
+ return rand_default();
#endif
}
+u32 rand(void)
+{
+ u32 ret = 0;
+ ret |= (rand_once() & (0xffu << 0));
+ ret |= (rand_once() & (0xffu << 8));
+ ret |= (rand_once() & (0xffu << 16));
+ ret |= (rand_once() & (0xffu << 24));
+ return ret;
+}
+
+void rand_fill(void *buf, u32 size)
+{
+ for (u32 i = 0; i < size; i++)
+ ((u8 *)buf)[i] = rand_once() & 0xff;
+}
+
char *randstr(u32 size)
{
if (!size)
diff --git a/libs/libc/sanitize.c b/libs/libc/sanitize.c
index 415b790..d31c20c 100644
--- a/libs/libc/sanitize.c
+++ b/libs/libc/sanitize.c
@@ -8,10 +8,6 @@
* Stack protector
*/
-#define STACK_CHK_GUARD 0xdeadbeef
-
-u32 __stack_chk_guard = STACK_CHK_GUARD;
-
void __stack_chk_fail(void);
NORETURN void __stack_chk_fail(void)
{
diff --git a/libs/libc/sys.c b/libs/libc/sys.c
index 15a9669..139f523 100644
--- a/libs/libc/sys.c
+++ b/libs/libc/sys.c
@@ -170,11 +170,6 @@ res boot(u32 cmd)
return sys2(SYS_BOOT, SYS_BOOT_MAGIC, cmd);
}
-u32 time(void)
-{
- return (u32)sys0(SYS_TIME);
-}
-
/**
* At exit
*/