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
|
#pragma once
|
||||||
|
|
||||||
|
#include "tss.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define GDT_ADDRESS 0xC0105040
|
#define GDT_ADDRESS 0xC0105040
|
||||||
#define GDT_SIZE 7
|
#define GDT_SIZE 8
|
||||||
|
|
||||||
// https://wiki.osdev.org/Global_Descriptor_Table#GDTR
|
// https://wiki.osdev.org/Global_Descriptor_Table#GDTR
|
||||||
struct gdt_descriptor {
|
struct gdt_descriptor {
|
||||||
@ -11,6 +12,8 @@ struct gdt_descriptor {
|
|||||||
uint32_t base;
|
uint32_t base;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
extern struct tss TSS;
|
||||||
|
|
||||||
void init_gdt();
|
void init_gdt();
|
||||||
|
|
||||||
#define GDT_FLAG_64BIT_MODE 0b0010
|
#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_CODE 0x20
|
||||||
#define GDT_OFFSET_USER_DATA 0x28
|
#define GDT_OFFSET_USER_DATA 0x28
|
||||||
#define GDT_OFFSET_USER_STACK 0x30
|
#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 "kprintf.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "sys/io.h"
|
#include "sys/io.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
#define PIT_CHANNEL0 0x40
|
#define PIT_CHANNEL0 0x40
|
||||||
#define PIT_FREQUENCY 1193182
|
#define PIT_FREQUENCY 1193182
|
||||||
#define PIT_COUNT (65535 / 2)
|
#define PIT_COUNT (65535 / 2)
|
||||||
#define DELAY (1000 / (PIT_FREQUENCY / PIT_COUNT))
|
#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);
|
static void clock_handler(struct registers *regs);
|
||||||
|
|
||||||
@ -36,12 +38,15 @@ void clock_init(struct registers *regs)
|
|||||||
static void clock_handler(struct registers *regs)
|
static void clock_handler(struct registers *regs)
|
||||||
{
|
{
|
||||||
(void)regs;
|
(void)regs;
|
||||||
counter--;
|
if (scheduler_counter % 10)
|
||||||
|
scheduler();
|
||||||
|
scheduler_counter++;
|
||||||
|
sleep_counter--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep(uint64_t delay)
|
void sleep(uint64_t delay)
|
||||||
{
|
{
|
||||||
counter = delay / DELAY;
|
sleep_counter = delay / DELAY;
|
||||||
while (counter)
|
while (sleep_counter)
|
||||||
;
|
;
|
||||||
}
|
}
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
extern void set_gdt(uint32_t gdt_ptr);
|
extern void set_gdt(uint32_t gdt_ptr);
|
||||||
|
|
||||||
|
struct tss TSS;
|
||||||
uint8_t gdt_entries[GDT_SIZE * 8];
|
uint8_t gdt_entries[GDT_SIZE * 8];
|
||||||
struct gdt_descriptor *gdtr = (struct gdt_descriptor *)GDT_ADDRESS;
|
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_RW_READABLE_FOR_CODE_WRITABLE_FOR_DATA |
|
||||||
GDT_ACCESS_A_ACCESSED,
|
GDT_ACCESS_A_ACCESSED,
|
||||||
GDT_FLAG_32BIT_MODE | GDT_FLAG_PAGE_MODE); // User stack
|
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));
|
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 "
|
/* "complex 8*unknown quantity -byte descriptor table. -- Troy "
|
||||||
*/
|
*/
|
||||||
/* "Martin 03:50, 22 March 2009 (UTC)\n"); */
|
/* "Martin 03:50, 22 March 2009 (UTC)\n"); */
|
||||||
/* terminal_putchar('A'); */
|
|
||||||
/* memset(display.buff, 255, 1024 * 1024); */
|
|
||||||
shell_init();
|
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