wip: TSS added to the gdt and start to implement scheduler
This commit is contained in:
parent
916e8b6f19
commit
b9691b1948
@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "tss.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define GDT_ADDRESS 0xC0105040
|
||||
#define GDT_SIZE 7
|
||||
#define GDT_SIZE 8
|
||||
|
||||
// https://wiki.osdev.org/Global_Descriptor_Table#GDTR
|
||||
struct gdt_descriptor {
|
||||
@ -11,6 +12,8 @@ struct gdt_descriptor {
|
||||
uint32_t base;
|
||||
} __attribute__((packed));
|
||||
|
||||
extern struct tss TSS;
|
||||
|
||||
void init_gdt();
|
||||
|
||||
#define GDT_FLAG_64BIT_MODE 0b0010
|
||||
@ -39,3 +42,4 @@ extern uint8_t gdt_entries[GDT_SIZE * 8];
|
||||
#define GDT_OFFSET_USER_CODE 0x20
|
||||
#define GDT_OFFSET_USER_DATA 0x28
|
||||
#define GDT_OFFSET_USER_STACK 0x30
|
||||
#define GDT_OFFSET_TSS 0x38
|
||||
|
23
headers/task.h
Normal file
23
headers/task.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "list.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum status { ZOMBIE, THREAD, RUN };
|
||||
|
||||
struct task {
|
||||
uint32_t *esp;
|
||||
uint32_t *esp0;
|
||||
uint32_t *cr3;
|
||||
uint16_t pid;
|
||||
uint8_t status;
|
||||
struct task *daddy;
|
||||
struct task *child;
|
||||
struct list **signals;
|
||||
uint8_t owner_id;
|
||||
struct task *next;
|
||||
};
|
||||
|
||||
void scheduler(void);
|
||||
void switch_to_task(struct task *next_task);
|
60
headers/tss.h
Normal file
60
headers/tss.h
Normal file
@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// _h fields are for the offset
|
||||
struct tss {
|
||||
uint16_t link;
|
||||
uint16_t link_h;
|
||||
|
||||
uint32_t esp0;
|
||||
uint16_t ss0;
|
||||
uint16_t ss0_h;
|
||||
|
||||
uint32_t esp1;
|
||||
uint16_t ss1;
|
||||
uint16_t ss1_h;
|
||||
|
||||
uint32_t esp2;
|
||||
uint16_t ss2;
|
||||
uint16_t ss2_h;
|
||||
|
||||
uint32_t cr3;
|
||||
uint32_t eip;
|
||||
uint32_t eflags;
|
||||
|
||||
uint32_t eax;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
uint32_t ebx;
|
||||
|
||||
uint32_t esp;
|
||||
uint32_t ebp;
|
||||
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
|
||||
uint16_t es;
|
||||
uint16_t es_h;
|
||||
|
||||
uint16_t cs;
|
||||
uint16_t cs_h;
|
||||
|
||||
uint16_t ss;
|
||||
uint16_t ss_h;
|
||||
|
||||
uint16_t ds;
|
||||
uint16_t ds_h;
|
||||
|
||||
uint16_t fs;
|
||||
uint16_t fs_h;
|
||||
|
||||
uint16_t gs;
|
||||
uint16_t gs_h;
|
||||
|
||||
uint16_t ldt;
|
||||
uint16_t ldt_h;
|
||||
|
||||
uint16_t trap;
|
||||
uint16_t iomap;
|
||||
};
|
6
libbozo/headers/list.h
Normal file
6
libbozo/headers/list.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct list {
|
||||
void *content;
|
||||
struct list *next;
|
||||
};
|
@ -6,13 +6,15 @@
|
||||
#include "kprintf.h"
|
||||
#include "memory.h"
|
||||
#include "sys/io.h"
|
||||
#include "task.h"
|
||||
|
||||
#define PIT_CHANNEL0 0x40
|
||||
#define PIT_FREQUENCY 1193182
|
||||
#define PIT_COUNT (65535 / 2)
|
||||
#define DELAY (1000 / (PIT_FREQUENCY / PIT_COUNT))
|
||||
|
||||
uint32_t counter = 0;
|
||||
uint32_t sleep_counter;
|
||||
uint32_t scheduler_counter;
|
||||
|
||||
static void clock_handler(struct registers *regs);
|
||||
|
||||
@ -36,12 +38,15 @@ void clock_init(struct registers *regs)
|
||||
static void clock_handler(struct registers *regs)
|
||||
{
|
||||
(void)regs;
|
||||
counter--;
|
||||
if (scheduler_counter % 10)
|
||||
scheduler();
|
||||
scheduler_counter++;
|
||||
sleep_counter--;
|
||||
}
|
||||
|
||||
void sleep(uint64_t delay)
|
||||
{
|
||||
counter = delay / DELAY;
|
||||
while (counter)
|
||||
sleep_counter = delay / DELAY;
|
||||
while (sleep_counter)
|
||||
;
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
|
||||
extern void set_gdt(uint32_t gdt_ptr);
|
||||
|
||||
struct tss TSS;
|
||||
uint8_t gdt_entries[GDT_SIZE * 8];
|
||||
struct gdt_descriptor *gdtr = (struct gdt_descriptor *)GDT_ADDRESS;
|
||||
|
||||
@ -90,6 +91,9 @@ void init_gdt(void)
|
||||
GDT_ACCESS_RW_READABLE_FOR_CODE_WRITABLE_FOR_DATA |
|
||||
GDT_ACCESS_A_ACCESSED,
|
||||
GDT_FLAG_32BIT_MODE | GDT_FLAG_PAGE_MODE); // User stack
|
||||
// TSS
|
||||
set_gdt_entry_value(gdt_entries + GDT_OFFSET_TSS, (uint32_t)&TSS,
|
||||
sizeof(struct tss) - 1, 0x89, 0);
|
||||
|
||||
set_gdt(((uint32_t)gdtr));
|
||||
}
|
||||
|
@ -41,7 +41,5 @@ void kernel_main(multiboot_info_t *mbd, uint32_t magic)
|
||||
/* "complex 8*unknown quantity -byte descriptor table. -- Troy "
|
||||
*/
|
||||
/* "Martin 03:50, 22 March 2009 (UTC)\n"); */
|
||||
/* terminal_putchar('A'); */
|
||||
/* memset(display.buff, 255, 1024 * 1024); */
|
||||
shell_init();
|
||||
}
|
||||
|
11
src/multitasking/scheduler.c
Normal file
11
src/multitasking/scheduler.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include "task.h"
|
||||
|
||||
struct task *current_task;
|
||||
|
||||
void scheduler(void)
|
||||
{
|
||||
struct task *it = current_task->next;
|
||||
while (it->status != RUN)
|
||||
it = it->next;
|
||||
switch_to_task(it);
|
||||
}
|
37
src/multitasking/switch_to_task.s
Normal file
37
src/multitasking/switch_to_task.s
Normal file
@ -0,0 +1,37 @@
|
||||
.intel_syntax noprefix
|
||||
|
||||
.section .text
|
||||
.global switch_to_task
|
||||
|
||||
switch_to_task:
|
||||
push ebx
|
||||
push ebp
|
||||
push edi
|
||||
push esi
|
||||
|
||||
// save the current stack pointer to the old stack
|
||||
mov [current_task], esp
|
||||
|
||||
// stack pointer + the 4 regs pushed
|
||||
// and + 1 to get the argument (next task)
|
||||
mov esi, [esp+(4+1)*4]
|
||||
mov [current_task], esi
|
||||
|
||||
mov esp, [current_task]
|
||||
mov eax, [current_task+4]
|
||||
mov ebx, [current_task+8]
|
||||
mov [TSS + 4], eax
|
||||
mov ecx, cr3
|
||||
|
||||
// if cr3 hasn't change, do nothing
|
||||
cmp ecx, ebx
|
||||
je .END
|
||||
mov cr3, ebx
|
||||
|
||||
.END:
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
pop ebx
|
||||
|
||||
ret
|
Loading…
Reference in New Issue
Block a user