aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMarvin Borner2021-04-14 13:39:42 +0200
committerMarvin Borner2021-04-14 13:39:42 +0200
commit212582f69dea4c99c292081b15ea526014b9ad44 (patch)
treec4fc1643c5acb8821fc0cfbd1b9c0983a50afe97 /kernel
parent9ded3a2bde80eede5fd887812d70c2f834b53c84 (diff)
Even more I/O - started new PS/2 driver
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile5
-rw-r--r--kernel/drivers/fb.c3
-rw-r--r--kernel/drivers/ps2/keyboard.c (renamed from kernel/drivers/keyboard.c)21
-rw-r--r--kernel/drivers/ps2/mouse.c (renamed from kernel/drivers/mouse.c)78
-rw-r--r--kernel/drivers/ps2/ps2.c229
-rw-r--r--kernel/features/io.c41
-rw-r--r--kernel/features/syscall.c11
-rw-r--r--kernel/inc/io.h17
-rw-r--r--kernel/inc/keyboard.h9
-rw-r--r--kernel/inc/mouse.h8
-rw-r--r--kernel/inc/ps2.h46
-rw-r--r--kernel/main.c7
12 files changed, 367 insertions, 108 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 81f19b7..03ad960 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -5,13 +5,14 @@ COBJS = main.o \
drivers/interrupts_asm.o \
drivers/cpu.o \
drivers/serial.o \
- drivers/keyboard.o \
- drivers/mouse.o \
drivers/pci.o \
drivers/rtc.o \
drivers/ide.o \
drivers/fb.o \
drivers/timer.o \
+ drivers/ps2/ps2.o \
+ drivers/ps2/mouse.o \
+ drivers/ps2/keyboard.o \
features/mm.o \
features/fs.o \
features/io.o \
diff --git a/kernel/drivers/fb.c b/kernel/drivers/fb.c
index 7f05014..1d266f7 100644
--- a/kernel/drivers/fb.c
+++ b/kernel/drivers/fb.c
@@ -6,7 +6,6 @@
#include <errno.h>
#include <fb.h>
#include <fs.h>
-#include <ioctl.h>
#include <mem.h>
#include <mm.h>
#include <str.h>
@@ -33,7 +32,7 @@ static res fb_ioctl(u32 request, void *arg1, void *arg2, void *arg3, struct vfs_
UNUSED(dev);
switch (request) {
- case IO_FB_GET: {
+ case 0: {
if (!info)
return -ENOENT;
diff --git a/kernel/drivers/keyboard.c b/kernel/drivers/ps2/keyboard.c
index 6b4b0fa..9a19b5c 100644
--- a/kernel/drivers/keyboard.c
+++ b/kernel/drivers/ps2/keyboard.c
@@ -5,10 +5,10 @@
#include <errno.h>
#include <fs.h>
#include <interrupts.h>
-#include <keyboard.h>
#include <mem.h>
#include <print.h>
#include <proc.h>
+#include <ps2.h>
#include <stack.h>
#include <str.h>
#include <sys.h>
@@ -22,7 +22,7 @@ static int merged = 0;
static void keyboard_handler(struct regs *r)
{
UNUSED(r);
- int scancode = inb(0x60);
+ u8 scancode = ps2_read_data();
// TODO: Support more than two-byte scancodes
if (scancode == 0xe0) {
@@ -46,19 +46,6 @@ static void keyboard_handler(struct regs *r)
merged = 0;
}
-/*static void keyboard_acknowledge(void)
-{
- while (inb(0x60) != 0xfa)
- ;
-}
-
-static void keyboard_rate(void)
-{
- outb(0x60, 0xF3);
- keyboard_acknowledge();
- outb(0x60, 0x0); // Rate{00000} Delay{00} 0
-}*/
-
static res keyboard_read(void *buf, u32 offset, u32 count, struct vfs_dev *dev)
{
UNUSED(dev);
@@ -76,12 +63,12 @@ static res keyboard_ready(void)
return !stack_empty(queue);
}
-CLEAR void keyboard_reset(void)
+CLEAR void ps2_keyboard_reset(void)
{
stack_clear(queue);
}
-CLEAR void keyboard_install(void)
+CLEAR void ps2_keyboard_install(void)
{
//keyboard_rate(); TODO: Fix keyboard rate?
irq_install_handler(1, keyboard_handler);
diff --git a/kernel/drivers/mouse.c b/kernel/drivers/ps2/mouse.c
index 3a78bc8..9b3fa2e 100644
--- a/kernel/drivers/mouse.c
+++ b/kernel/drivers/ps2/mouse.c
@@ -6,9 +6,9 @@
#include <fs.h>
#include <interrupts.h>
#include <mem.h>
-#include <mouse.h>
#include <print.h>
#include <proc.h>
+#include <ps2.h>
#include <stack.h>
#include <str.h>
#include <sys.h>
@@ -24,18 +24,18 @@ static void mouse_handler(struct regs *r)
UNUSED(r);
switch (mouse_cycle) {
case 0:
- mouse_byte[0] = (char)inb(0x60);
+ mouse_byte[0] = ps2_read_data();
if (((mouse_byte[0] >> 3) & 1) == 1)
mouse_cycle++;
else
mouse_cycle = 0;
break;
case 1:
- mouse_byte[1] = (char)inb(0x60);
+ mouse_byte[1] = ps2_read_data();
mouse_cycle++;
break;
case 2:
- mouse_byte[2] = (char)inb(0x60);
+ mouse_byte[2] = ps2_read_data();
event = malloc(sizeof(*event));
event->magic = MOUSE_MAGIC;
@@ -52,34 +52,36 @@ static void mouse_handler(struct regs *r)
}
}
-CLEAR static void mouse_serial_wait(u8 a_type)
+#define MOUSE_WAIT_OUT 0
+#define MOUSE_WAIT_IN 1
+CLEAR static void mouse_serial_wait(u8 in)
{
u32 time_out = 100000;
- if (a_type == 0) {
+ if (in) {
while (time_out--)
- if ((inb(0x64) & 1) == 1)
+ if (ps2_read_status().in_full)
return;
return;
} else {
while (time_out--)
- if ((inb(0x64) & 2) == 0)
+ if (ps2_read_status().out_full)
return;
return;
}
}
-CLEAR static void mouse_serial_write(u8 a_write)
+CLEAR static void mouse_serial_write(u8 data)
{
- mouse_serial_wait(1);
- outb(0x64, 0xD4);
- mouse_serial_wait(1);
- outb(0x60, a_write);
+ mouse_serial_wait(MOUSE_WAIT_IN);
+ ps2_write_command(0xd4);
+ mouse_serial_wait(MOUSE_WAIT_IN);
+ ps2_write_data(data);
}
CLEAR static u8 mouse_serial_read(void)
{
- mouse_serial_wait(0);
- return inb(0x60);
+ mouse_serial_wait(MOUSE_WAIT_OUT);
+ return ps2_read_data();
}
static res mouse_ready(void)
@@ -99,45 +101,45 @@ static res mouse_read(void *buf, u32 offset, u32 count, struct vfs_dev *dev)
return MIN(count, sizeof(*e));
}
-CLEAR void mouse_install(void)
+CLEAR void ps2_mouse_install(void)
{
u8 status;
// Enable auxiliary mouse device
- mouse_serial_wait(1);
- outb(0x64, 0xA8);
+ mouse_serial_wait(MOUSE_WAIT_IN);
+ ps2_write_command(0xa8);
// Enable interrupts
- mouse_serial_wait(1);
- outb(0x64, 0x20);
- mouse_serial_wait(0);
- status = (u8)(inb(0x60) | 3);
- mouse_serial_wait(1);
- outb(0x64, 0x60);
- mouse_serial_wait(1);
- outb(0x60, status);
+ mouse_serial_wait(MOUSE_WAIT_IN);
+ ps2_write_command(0x20);
+ mouse_serial_wait(MOUSE_WAIT_OUT);
+ status = ps2_read_data() | 3;
+ mouse_serial_wait(MOUSE_WAIT_IN);
+ ps2_write_command(0x60);
+ mouse_serial_wait(MOUSE_WAIT_IN);
+ ps2_write_data(status);
// Use default settings
- mouse_serial_write(0xF6);
+ mouse_serial_write(0xf6);
mouse_serial_read();
// Enable mousewheel
- mouse_serial_write(0xF2);
+ mouse_serial_write(0xf2);
mouse_serial_read();
mouse_serial_read();
- mouse_serial_write(0xF3);
+ mouse_serial_write(0xf3);
mouse_serial_read();
mouse_serial_write(200);
mouse_serial_read();
- mouse_serial_write(0xF3);
+ mouse_serial_write(0xf3);
mouse_serial_read();
mouse_serial_write(100);
mouse_serial_read();
- mouse_serial_write(0xF3);
+ mouse_serial_write(0xf3);
mouse_serial_read();
mouse_serial_write(80);
mouse_serial_read();
- mouse_serial_write(0xF2);
+ mouse_serial_write(0xf2);
mouse_serial_read();
status = (u8)mouse_serial_read();
if (status == 3) {
@@ -145,22 +147,22 @@ CLEAR void mouse_install(void)
/* printf("Scrollwheel support!\n"); */
// Activate 4th and 5th mouse buttons
- mouse_serial_write(0xF2);
+ mouse_serial_write(0xf2);
mouse_serial_read();
mouse_serial_read();
- mouse_serial_write(0xF3);
+ mouse_serial_write(0xf3);
mouse_serial_read();
mouse_serial_write(200);
mouse_serial_read();
- mouse_serial_write(0xF3);
+ mouse_serial_write(0xf3);
mouse_serial_read();
mouse_serial_write(200);
mouse_serial_read();
- mouse_serial_write(0xF3);
+ mouse_serial_write(0xf3);
mouse_serial_read();
mouse_serial_write(80);
mouse_serial_read();
- mouse_serial_write(0xF2);
+ mouse_serial_write(0xf2);
mouse_serial_read();
status = (u8)mouse_serial_read();
if (status == 4) {
@@ -178,7 +180,7 @@ CLEAR void mouse_install(void)
mouse_serial_read(); */
// Enable mouse
- mouse_serial_write(0xF4);
+ mouse_serial_write(0xf4);
mouse_serial_read();
// Setup the mouse handler
diff --git a/kernel/drivers/ps2/ps2.c b/kernel/drivers/ps2/ps2.c
new file mode 100644
index 0000000..1c73855
--- /dev/null
+++ b/kernel/drivers/ps2/ps2.c
@@ -0,0 +1,229 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#include <assert.h>
+#include <cpu.h>
+#include <def.h>
+#include <print.h>
+#include <ps2.h>
+
+#define PS2_TIMEOUT 100000
+
+struct ps2_status ps2_read_status(void)
+{
+ u8 byte = inb(0x64);
+ return *(struct ps2_status *)&byte;
+}
+
+static u8 ps2_wait_readable(void)
+{
+ u32 time_out = PS2_TIMEOUT;
+ while (time_out--)
+ if (ps2_read_status().in_full)
+ return 1;
+ /* print("PS/2 readable timeout\n"); */
+ return 0;
+}
+
+static u8 ps2_wait_writable(void)
+{
+ u32 time_out = PS2_TIMEOUT;
+ while (time_out--)
+ if (!ps2_read_status().out_full)
+ return 1;
+ /* print("PS/2 writable timeout\n"); */
+ return 0;
+}
+
+u8 ps2_read_data(void)
+{
+ if (ps2_wait_readable()) {
+ return inb(0x60);
+ } else {
+ return 0;
+ }
+}
+
+u8 ps2_write_data(u8 byte)
+{
+ if (ps2_wait_writable()) {
+ outb(0x60, byte);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+u8 ps2_write_command(u8 byte)
+{
+ if (ps2_wait_writable()) {
+ outb(0x64, byte);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+CLEAR static struct ps2_config ps2_read_config(void)
+{
+ assert(ps2_write_command(0x20));
+ u8 config = ps2_read_data();
+ return *(struct ps2_config *)&config;
+}
+
+CLEAR static u8 ps2_write_config(struct ps2_config config)
+{
+ // Select first byte
+ if (!ps2_write_command(0x60))
+ return 0;
+
+ return ps2_write_data(*(u8 *)&config);
+}
+
+#define PS2_TYPE_STANDARD_MOUSE 0x0000
+#define PS2_TYPE_WHEEL_MOUSE 0x0003
+#define PS2_TYPE_BUTTON_MOUSE 0x0004
+#define PS2_TYPE_TRANSLATION_KEYBOARD1 0xab41
+#define PS2_TYPE_TRANSLATION_KEYBOARD2 0xabc1
+#define PS2_TYPE_STANDARD_KEYBOARD 0xab83
+
+PROTECTED static struct {
+ u8 detected : 1;
+ struct {
+ u8 exists : 1;
+ u16 type;
+ } first;
+ struct {
+ u8 exists : 1;
+ u16 type;
+ } second;
+} info = { 0 };
+
+CLEAR static u8 ps2_write_device(u8 device, u8 data)
+{
+ u8 resp = PS2_RESEND;
+ for (u8 i = 0; resp == PS2_RESEND && i < 3; i++) {
+ if (device == 1)
+ ps2_write_command(0xd4);
+ ps2_write_data(data);
+ resp = ps2_read_data();
+ }
+
+ if (resp != PS2_ACK)
+ return 0;
+
+ return 1;
+}
+
+CLEAR static u8 ps2_device_keyboard(u16 type)
+{
+ return type == PS2_TYPE_TRANSLATION_KEYBOARD1 || type == PS2_TYPE_TRANSLATION_KEYBOARD2 ||
+ type == PS2_TYPE_STANDARD_KEYBOARD;
+}
+
+CLEAR static u8 ps2_device_mouse(u16 type)
+{
+ return type == PS2_TYPE_STANDARD_MOUSE || type == PS2_TYPE_WHEEL_MOUSE ||
+ type == PS2_TYPE_BUTTON_MOUSE;
+}
+
+CLEAR u8 ps2_keyboard_support(void)
+{
+ if (!info.detected)
+ return 0;
+
+ // Find, reset and self-test
+ if ((info.first.exists && ps2_device_keyboard(info.first.type) &&
+ ps2_write_device(0, 0xff)) ||
+ (info.second.exists && ps2_device_keyboard(info.second.type) &&
+ ps2_write_device(1, 0xff)))
+ return ps2_read_data() == 0xaa;
+
+ return 0;
+}
+
+CLEAR u8 ps2_mouse_support(void)
+{
+ if (!info.detected)
+ return 0;
+
+ // Find, reset and self-test
+ if ((info.first.exists && ps2_device_mouse(info.first.type) && ps2_write_device(0, 0xff)) ||
+ (info.second.exists && ps2_device_mouse(info.second.type) && ps2_write_device(1, 0xff)))
+ return ps2_read_data() == 0xaa;
+
+ return 0;
+}
+
+CLEAR void ps2_detect(void)
+{
+ // TODO: Read ACPI 8042 flag in FADT to verify PS/2 support
+
+ // Disable PS/2 ports
+ ps2_write_command(0xad);
+ ps2_write_command(0xa7);
+
+ // Get config and disable IRQs
+ struct ps2_config config = ps2_read_config();
+ assert(!config.zero1 && !config.zero2);
+ config.first_int = 0;
+ config.second_int = 0;
+ ps2_write_config(config);
+
+ // Test PS/2 controller
+ ps2_write_command(0xaa);
+ if (ps2_read_data() != 0x55)
+ return;
+ ps2_write_config(config);
+
+ // Test first PS/2 port
+ ps2_write_command(0xab);
+ if (ps2_read_data() == 0x0) {
+ // Enable first port
+ ps2_write_command(0xae);
+ config.first_int = 1;
+ config.first_clock_disabled = 0;
+ info.first.exists = 1;
+ }
+
+ // Test and enable second PS/2 port if available
+ if (config.second_clock_disabled) {
+ ps2_write_command(0xa9);
+ if (ps2_read_data() == 0x0) {
+ // Enable second port
+ ps2_write_command(0xa8);
+ config.second_int = 1;
+ config.second_clock_disabled = 0;
+ info.second.exists = 1;
+ }
+ }
+
+ ps2_write_config(config);
+
+ // Detect device type of first port
+ if (info.first.exists) {
+ if (!ps2_write_device(0, 0xf5))
+ return;
+
+ if (!ps2_write_device(0, 0xf2))
+ return;
+
+ u8 first = ps2_read_data();
+ u8 second = ps2_read_data();
+ info.first.type = (first << 8) | second;
+ }
+
+ // Detect device type of second port
+ if (info.second.exists) {
+ if (!ps2_write_device(1, 0xf5))
+ return;
+
+ if (!ps2_write_device(1, 0xf2))
+ return;
+
+ u8 first = ps2_read_data();
+ u8 second = ps2_read_data(); // This shall timeout if it's a mouse
+ info.second.type = (first << 8) | second;
+ }
+
+ info.detected = 1;
+}
diff --git a/kernel/features/io.c b/kernel/features/io.c
index 2bd925b..5d69b8e 100644
--- a/kernel/features/io.c
+++ b/kernel/features/io.c
@@ -5,6 +5,7 @@
#include <io.h>
#include <list.h>
#include <mm.h>
+#include <ps2.h>
#include <rand.h>
#include <str.h>
@@ -29,12 +30,13 @@ CLEAR void io_add(enum io_type io, struct io_dev *dev)
io_mappings[io] = dev;
}
-res io_control(enum io_type io)
+res io_control(enum io_type io, u32 request, void *arg1, void *arg2, void *arg3)
{
- if (!io_get(io))
+ struct io_dev *dev;
+ if (!(dev = io_get(io)) || !dev->control)
return -ENOENT;
- return -ENOENT;
+ return dev->control(request, arg1, arg2, arg3);
}
res io_write(enum io_type io, void *buf, u32 offset, u32 count)
@@ -42,8 +44,11 @@ res io_write(enum io_type io, void *buf, u32 offset, u32 count)
if (!memory_readable(buf))
return -EFAULT;
- if (!io_get(io))
+ struct io_dev *dev;
+ if (!(dev = io_get(io)) || !dev->write)
return -ENOENT;
+
+ return dev->write(buf, offset, count);
}
res io_read(enum io_type io, void *buf, u32 offset, u32 count)
@@ -51,17 +56,35 @@ res io_read(enum io_type io, void *buf, u32 offset, u32 count)
if (!memory_readable(buf))
return -EFAULT;
- if (!io_get(io))
+ struct io_dev *dev;
+ if (!(dev = io_get(io)) || !dev->read)
return -ENOENT;
+
+ return dev->read(buf, offset, count);
}
-res io_poll(enum io_type io)
+res io_poll(u32 *devs)
{
- if (!io_get(io))
- return -ENOENT;
+ if (!memory_readable(devs))
+ return -EFAULT;
+
+ for (u32 *p = devs; p && memory_readable(p) && *p; p++) {
+ if (!io_get(*p))
+ return -ENOENT;
+ }
+
+ return -EFAULT;
}
CLEAR void io_install(void)
{
- // TODO: Install I/O devices by selecting best working driver
+ ps2_detect();
+
+ if (ps2_keyboard_support()) {
+ print("KBD!\n");
+ }
+
+ if (ps2_mouse_support()) {
+ print("MOUSE!\n");
+ }
}
diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c
index 1e21edd..abd7130 100644
--- a/kernel/features/syscall.c
+++ b/kernel/features/syscall.c
@@ -53,15 +53,10 @@ static void syscall_handler(struct regs *r)
r->eax = vfs_write((char *)r->ebx, (void *)r->ecx, r->edx, r->esi);
break;
}
- case SYS_IOCTL: {
- r->eax = vfs_ioctl((char *)r->ebx, r->ecx, (void *)r->edx, (void *)r->esi,
- (void *)r->edi);
- break;
- }
// I/O operations
case SYS_IOPOLL: {
- r->eax = io_poll((void *)r->ebx);
+ r->eax = io_poll((u32 *)r->ebx);
break;
}
case SYS_IOREAD: {
@@ -72,6 +67,10 @@ static void syscall_handler(struct regs *r)
r->eax = io_write(r->ebx, (void *)r->ecx, r->edx, r->esi);
break;
}
+ case SYS_IOCONTROL: {
+ r->eax = io_control(r->ebx, r->ecx, (void *)r->edx, (void *)r->esi, (void *)r->edi);
+ break;
+ }
// Process operations
case SYS_EXEC: {
diff --git a/kernel/inc/io.h b/kernel/inc/io.h
index e05a419..fc294f1 100644
--- a/kernel/inc/io.h
+++ b/kernel/inc/io.h
@@ -6,25 +6,18 @@
#include <def.h>
#include <sys.h>
-enum io_type {
- IO_MIN,
- IO_FRAMEBUFFER,
- IO_NETWORK,
- IO_KEYBOARD,
- IO_MOUSE,
- IO_BUS,
- IO_MAX,
-};
-
struct io_dev {
const char *name;
+ res (*read)(void *buf, u32 offset, u32 count) NONNULL;
+ res (*write)(void *buf, u32 offset, u32 count) NONNULL;
+ res (*control)(u32 request, void *arg1, void *arg2, void *arg3);
};
void io_install(void);
-res io_control();
+res io_control(enum io_type io, u32 request, void *arg1, void *arg2, void *arg3);
res io_write(enum io_type io, void *buf, u32 offset, u32 count);
res io_read(enum io_type io, void *buf, u32 offset, u32 count);
-res io_poll();
+res io_poll(u32 *devs);
#endif
diff --git a/kernel/inc/keyboard.h b/kernel/inc/keyboard.h
deleted file mode 100644
index 22120e5..0000000
--- a/kernel/inc/keyboard.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef KEYBOARD_H
-#define KEYBOARD_H
-
-void keyboard_install(void);
-void keyboard_reset(void);
-
-#endif
diff --git a/kernel/inc/mouse.h b/kernel/inc/mouse.h
deleted file mode 100644
index e8072aa..0000000
--- a/kernel/inc/mouse.h
+++ /dev/null
@@ -1,8 +0,0 @@
-// MIT License, Copyright (c) 2020 Marvin Borner
-
-#ifndef MOUSE_H
-#define MOUSE_H
-
-void mouse_install(void);
-
-#endif
diff --git a/kernel/inc/ps2.h b/kernel/inc/ps2.h
new file mode 100644
index 0000000..fb923bf
--- /dev/null
+++ b/kernel/inc/ps2.h
@@ -0,0 +1,46 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#ifndef PS2_H
+#define PS2_H
+
+#include <def.h>
+
+#define PS2_ACK 0xfa
+#define PS2_RESEND 0xfe
+
+struct ps2_status {
+ u8 in_full : 1;
+ u8 out_full : 1;
+ u8 system : 1;
+ u8 command : 1;
+ u8 reserved : 2;
+ u8 error_time : 1;
+ u8 error_parity : 1;
+};
+
+struct ps2_config {
+ u8 first_int : 1;
+ u8 second_int : 1;
+ u8 running : 1;
+ u8 zero1 : 1;
+ u8 first_clock_disabled : 1;
+ u8 second_clock_disabled : 1;
+ u8 first_translation : 1;
+ u8 zero2 : 1;
+};
+
+u8 ps2_read_data(void);
+u8 ps2_write_data(u8 byte);
+struct ps2_status ps2_read_status(void);
+u8 ps2_write_command(u8 byte);
+
+void ps2_detect(void);
+u8 ps2_keyboard_support(void);
+u8 ps2_mouse_support(void);
+
+void ps2_keyboard_install(void);
+void ps2_keyboard_reset(void);
+
+void ps2_mouse_install(void);
+
+#endif
diff --git a/kernel/main.c b/kernel/main.c
index fe1f75f..3b961f2 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -6,11 +6,10 @@
#include <fs.h>
#include <ide.h>
#include <interrupts.h>
-#include <keyboard.h>
+#include <io.h>
#include <load.h>
#include <mem.h>
#include <mm.h>
-#include <mouse.h>
#include <net.h>
#include <pci.h>
#include <rand.h>
@@ -52,14 +51,12 @@ int kernel_main(struct boot_info *boot)
interrupts_install();
timer_install();
rtc_install();
- keyboard_install();
- mouse_install();
+ io_install();
fb_install(boot->vid);
/* net_install(); */
// Enable drivers
sti();
- keyboard_reset();
syscall_init();