Skip to content

Commit 11e4c42

Browse files
authored
Process (#10)
* Process and process manager * Task switching * Event bus / queue * Add KPANIC * Auto mount * Move idle to idle.c * System call args as pointer * Add yield and pull_event * Add queue_event * Update term to use pull_event
1 parent 9744084 commit 11e4c42

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1271
-404
lines changed

cmake/targets.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function(cross_target_binary target)
3131
-nostdlib
3232
"-L${CROSS_PREFIX}/lib/gcc/i386-elf/12.2.0"
3333
-lgcc
34-
DEPENDS ${target} ${TARGET_LINK_FILES})
34+
DEPENDS ${target} ${TARGET_LINK_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/link.ld)
3535

3636
add_custom_target(${target}_image ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${target}.bin)
3737

src/apps/foo/src/foo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
void foo() {
55
uint32_t res = puts("Hello\n");
66

7-
proc_exit(0);
7+
pull_event(EBUS_EVENT_KEY, 0);
88

99
res = printf("Hello 0x%X\n", res);
1010

src/cpu/i386/src/cpu.asm

Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -31,85 +31,3 @@ flush_tss:
3131
mov ax, (5 * 8) | 0 ; fifth 8-byte selector, symbolically OR-ed with 0 to set the RPL (requested privilege level).
3232
ltr ax
3333
ret
34-
35-
global jump_usermode
36-
jump_usermode:
37-
mov ebx, [esp+4]
38-
mov ax, (4 * 8) | 3 ; ring 3 data with bottom 2 bits set for ring 3
39-
mov ds, ax
40-
mov es, ax
41-
mov fs, ax
42-
mov gs, ax ; SS is handled by iret
43-
44-
; set up the stack frame iret expects
45-
mov eax, esp
46-
push (4 * 8) | 3 ; data selector
47-
push eax ; current esp
48-
pushf ; eflags
49-
push (3 * 8) | 3 ; code selector (ring 3 code with bottom 2 bits set for ring 3)
50-
push ebx ; instruction address to return to
51-
iret
52-
53-
; https://wiki.osdev.org/Brendan%27s_Multi-tasking_Tutorial
54-
55-
;C declaration:
56-
; void switch_to_task(thread_control_block *next_thread);
57-
;
58-
;WARNING: Caller is expected to disable IRQs before calling, and enable IRQs again after function returns
59-
60-
TCB_EIP equ 4
61-
TCB_ESP equ 8
62-
TCB_CR3 equ 12
63-
TCB_ESP0 equ 16
64-
TSS_ESP0 equ 20
65-
66-
current_task_TCB: dd 0
67-
68-
global set_first_task
69-
set_first_task:
70-
mov eax, [esp + 4]
71-
mov [current_task_TCB], eax
72-
ret
73-
74-
global switch_to_task
75-
switch_to_task:
76-
77-
;Save previous task's state
78-
79-
;Notes:
80-
; For cdecl; EAX, ECX, and EDX are already saved by the caller and don't need to be saved again
81-
; EIP is already saved on the stack by the caller's "CALL" instruction
82-
; The task isn't able to change CR3 so it doesn't need to be saved
83-
; Segment registers are constants (while running kernel code) so they don't need to be saved
84-
85-
push ebx
86-
push esi
87-
push edi
88-
push ebp
89-
90-
mov edi,[current_task_TCB] ;edi = address of the previous task's "thread control block"
91-
mov [edi+TCB_ESP],esp ;Save ESP for previous task's kernel stack in the thread's TCB
92-
93-
;Load next task's state
94-
95-
mov esi,[esp+(4+1)*4] ;esi = address of the next task's "thread control block" (parameter passed on stack)
96-
mov [current_task_TCB],esi ;Current task's TCB is the next task TCB
97-
98-
mov esp,[esi+TCB_ESP] ;Load ESP for next task's kernel stack from the thread's TCB
99-
mov eax,[esi+TCB_CR3] ;eax = address of page directory for next task
100-
mov ebx,[esi+TCB_ESP0] ;ebx = address for the top of the next task's kernel stack
101-
mov [TSS_ESP0],ebx ;Adjust the ESP0 field in the TSS (used by CPU for for CPL=3 -> CPL=0 privilege level changes)
102-
mov ecx,cr3 ;ecx = previous task's virtual address space
103-
104-
cmp eax,ecx ;Does the virtual address space need to being changed?
105-
je .doneVAS ; no, virtual address space is the same, so don't reload it and cause TLB flushes
106-
mov cr3,eax ; yes, load the next task's virtual address space
107-
108-
.doneVAS:
109-
110-
pop ebp
111-
pop edi
112-
pop esi
113-
pop ebx
114-
115-
ret ;Load next task's EIP from its kernel stack

src/cpu/i386/src/isr.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "cpu/idt.h"
44
#include "cpu/ports.h"
5+
#include "kernel.h"
56
#include "libc/proc.h"
67
#include "libc/stdio.h"
78

@@ -161,7 +162,7 @@ void isr_handler(registers_t r) {
161162
default:
162163
break;
163164
}
164-
PANIC("STOP HERE");
165+
KPANIC("STOP HERE");
165166
}
166167

167168
/*
@@ -191,7 +192,7 @@ void irq_handler(registers_t r) {
191192
if (r.int_no >= 256) {
192193
printf("BAD INTERRUPT 0x%X\n", r.int_no);
193194
print_trace(&r);
194-
PANIC("BAD INTERRUPT");
195+
KPANIC("BAD INTERRUPT");
195196
return;
196197
}
197198

src/cpu/i386/src/tss.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ tss_entry_t * tss_get_entry(size_t i) {
2424
return &tss_stack[i];
2525
}
2626

27-
void set_kernel_stack(uint32_t stack) { // Used when an interrupt occurs
27+
uint32_t tss_get_esp0() {
28+
return tss_stack[0].esp0;
29+
}
30+
31+
void tss_set_esp0(uint32_t stack) { // Used when an interrupt occurs
2832
tss_stack[0].esp0 = stack;
2933
}

src/cpu/include/cpu/tss.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ void init_tss();
5151

5252
tss_entry_t * tss_get_entry(size_t i);
5353

54-
void set_kernel_stack(uint32_t stack);
54+
uint32_t tss_get_esp0(void);
55+
void tss_set_esp0(uint32_t stack);
5556

5657
#endif // TSS_H

src/drivers/include/drivers/keyboard.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,4 @@ typedef enum keyboard_key {
8282

8383
void init_keyboard();
8484

85-
char keyboard_char(uint8_t code, bool shift);
86-
8785
#endif // KEYBOARD_H

src/drivers/src/keyboard.c

Lines changed: 79 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,104 @@
11
#include "drivers/keyboard.h"
22

3+
#include <stdbool.h>
4+
35
#include "cpu/isr.h"
46
#include "cpu/ports.h"
5-
#include "libc/signal.h"
7+
#include "libc/proc.h"
68
#include "libc/stdio.h"
9+
#include "libc/string.h"
10+
11+
static bool e0_mode;
12+
static uint32_t keystate[8];
13+
static char keyMap[0xFF] = {0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '+', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, 0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
14+
static char shiftKeyMap[0xFF] = {0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0, 0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
15+
16+
static void keyboard_callback(registers_t * regs);
17+
static char keyboard_char(uint8_t code, bool shift);
18+
static bool get_key_state(uint8_t keycode);
19+
static void set_key_state(uint8_t keycode, bool state);
20+
static uint8_t get_mods();
21+
22+
void init_keyboard() {
23+
e0_mode = false;
24+
kmemset(keystate, 0, sizeof(keystate));
25+
register_interrupt_handler(IRQ1, keyboard_callback);
26+
}
27+
28+
static bool get_key_state(uint8_t keycode) {
29+
int i = keycode / 32;
30+
int b = keycode % 32;
731

8-
static uint8_t last_code = 0;
9-
static bool lctrl = false;
10-
static bool rctrl = false;
11-
static bool lalt = false;
12-
static bool ralt = false;
13-
static bool lshift = false;
14-
static bool rshift = false;
15-
static bool lsuper = false;
16-
static bool rsuper = false;
32+
return keystate[i] & (1 << b);
33+
}
34+
35+
static void set_key_state(uint8_t keycode, bool state) {
36+
int i = keycode / 32;
37+
int b = keycode % 32;
38+
39+
if (state) {
40+
keystate[i] |= (1 << b);
41+
}
42+
else {
43+
keystate[i] &= ~(1 << b);
44+
}
45+
}
46+
47+
static uint8_t get_mods() {
48+
uint8_t mods = 0;
49+
// TODO handle 0xE0 to get right ctrl
50+
if (get_key_state(KEY_LCTRL)) {
51+
mods |= KEY_MOD_CTRL;
52+
}
53+
// TODO handle 0xE0 to get right alt
54+
if (get_key_state(KEY_LALT)) {
55+
mods |= KEY_MOD_ALT;
56+
}
57+
if (get_key_state(KEY_LSHIFT) || get_key_state(KEY_RSHIFT)) {
58+
mods |= KEY_MOD_SHIFT;
59+
}
60+
// TODO handle 0xE0 to get right super
61+
if (get_key_state(KEY_SUPER)) {
62+
mods |= KEY_MOD_SUPER;
63+
}
64+
return mods;
65+
}
66+
67+
static char keyboard_char(uint8_t code, bool shift) {
68+
code = code & 0x7F;
69+
if (shift) {
70+
return shiftKeyMap[code];
71+
}
72+
return keyMap[code];
73+
}
1774

1875
static void keyboard_callback(registers_t * regs) {
1976
/* The PIC leaves us the scancode in port 0x60 */
20-
uint8_t scancode = port_byte_in(0x60);
77+
uint8_t scancode = port_byte_in(0x60);
78+
if (scancode == 0xE0) {
79+
e0_mode = true;
80+
return;
81+
}
82+
// printf("%02X ", scancode);
2183
uint8_t keycode = scancode;
2284
keyboard_event_t key_event = KEY_EVENT_PRESS;
85+
uint8_t mods = get_mods();
2386
bool press = keycode < 0x80;
2487

2588
if (press) {
26-
if (keycode == last_code) {
89+
if (get_key_state(keycode)) {
2790
key_event = KEY_EVENT_REPEAT;
2891
}
29-
else {
30-
if (keycode == KEY_LSHIFT) {
31-
lshift = true;
32-
}
33-
if (keycode == KEY_RSHIFT) {
34-
lshift = true;
35-
}
36-
}
37-
last_code = keycode;
92+
set_key_state(keycode, true);
3893
}
3994

4095
else {
4196
keycode -= 0x80;
4297
key_event = KEY_EVENT_RELEASE;
43-
last_code = 0;
44-
45-
if (keycode == KEY_LSHIFT) {
46-
lshift = false;
47-
}
48-
if (keycode == KEY_RSHIFT) {
49-
lshift = false;
50-
}
98+
set_key_state(keycode, false);
5199
}
52100

53-
char c = keyboard_char(keycode, lshift || rshift);
54-
55-
keyboard_mod_t mods = 0;
56-
if (lctrl || rctrl) {
57-
mods |= KEY_MOD_CTRL;
58-
}
59-
if (lalt || ralt) {
60-
mods |= KEY_MOD_ALT;
61-
}
62-
if (lshift || rshift) {
63-
mods |= KEY_MOD_SHIFT;
64-
}
65-
if (lsuper || rsuper) {
66-
mods |= KEY_MOD_SUPER;
67-
}
101+
char c = keyboard_char(keycode, mods & KEY_MOD_SHIFT);
68102

69103
ebus_event_t event;
70104
event.event_id = EBUS_EVENT_KEY;
@@ -74,19 +108,5 @@ static void keyboard_callback(registers_t * regs) {
74108
event.key.keycode = keycode;
75109
event.key.scancode = scancode;
76110
queue_event(&event);
77-
}
78-
79-
void init_keyboard() {
80-
register_interrupt_handler(IRQ1, keyboard_callback);
81-
}
82-
83-
char keyMap[0xFF] = {0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '+', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, 0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
84-
char shiftKeyMap[0xFF] = {0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0, 0, 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
85-
86-
char keyboard_char(uint8_t code, bool shift) {
87-
code = code & 0x7F;
88-
if (shift) {
89-
return shiftKeyMap[code];
90-
}
91-
return keyMap[code];
111+
e0_mode = false;
92112
}

src/drivers/src/timer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "cpu/ports.h"
55
#include "ebus.h"
66
#include "libc/datastruct/array.h"
7-
#include "libc/signal.h"
7+
#include "libc/proc.h"
88
#include "libc/stdio.h"
99

1010
// https://wiki.osdev.org/PIT

src/ebus/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
set(TARGET ebus)
22

33
cross_target(${TARGET})
4-
target_link_libraries(${TARGET} libc)
4+
target_link_libraries(${TARGET} libc kernel)

0 commit comments

Comments
 (0)