Skip to content

Commit

Permalink
merge(kernel): add a scheduler
Browse files Browse the repository at this point in the history
Starting from this commit, we have the first working implementation of
a scheduler for our kernel.

This scheduler is a basic pre-emptive single processor round robin one.
There are many improvements possible, which will be added later.
For more information, please refer to the documentation.

Merges #14

Signed-off-by: Léo DUBOIN <[email protected]>
  • Loading branch information
d4ilyrun committed May 17, 2024
2 parents 51a2fc5 + aedce51 commit b3c541a
Show file tree
Hide file tree
Showing 39 changed files with 1,421 additions and 291 deletions.
41 changes: 23 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,27 +52,32 @@ I try to keep the codebase well-documented. You can generate the full doc using
$ doxygen docs/doxygen/Doxyfile # Requires you to also pull the git submodules
```

## What's available ?

- GDT segments
- Interrupts
- Logging
- PIT & Timer

## Things I'd like to learn/implement
## Things I'd like to learn

- [X] Interrupts
- Memory management
- [X] Paging
- [X] PMM (physical)
- [X] VMM (virtual)
- [ ] Scheduler
- [ ] Filesystem
- [ ] Syscalls
- User interaction
- [X] Keyboard
- [ ] CoW
- [ ] Guard pages
- Drivers
- [X] Timer
- [ ] Mouse
- [ ] Screen
- [ ] Porting an already existing program (Can it run DOOM?)
- [ ] Multitasking
- [ ] Semaphores
- [ ] Networking
- [ ] Loadable kernel modules
- Scheduling
- [X] Multitasking
- [ ] Priority
- [ ] Multiprocessor
- Filesystems
- [ ] ext2
- [ ] VFS
- Userland
- [ ] context switching
- [ ] syscalls
- Porting
- [ ] Load/Execute ELF programs
- [ ] Porting an already existing program (Can it run DOOM?)
- [ ] Dynamic ELF relocation
- [ ] IPC
- [ ] SMP
6 changes: 5 additions & 1 deletion include/kernel/arch/i686/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
ASM("movl %0, %%" #_reg : : "r"(value)); \
}

#define CPU_32BIT_REGISTERS cr0, cr1, cr2, cr3, cr4, esp, cs, ss
#define CPU_32BIT_REGISTERS cr0, cr1, cr2, cr3, cr4, esp, cs, ds, es, fs, gs, ss

MAP(READ_REGISTER_OPS, CPU_32BIT_REGISTERS, )
MAP(WRITE_REGISTER_OPS, CPU_32BIT_REGISTERS, )
Expand Down Expand Up @@ -73,4 +73,8 @@ static ALWAYS_INLINE uint32_t inl(uint16_t port)
return val;
}

static ALWAYS_INLINE void hlt(void)
{
ASM("hlt");
}
#endif /* KERNEL_I686_UTILS_CPU_OPS_H */
9 changes: 6 additions & 3 deletions include/kernel/arch/i686/gdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ typedef struct gdt_descriptor {
} gdt_descriptor;

/**
* @struct gdt_tss Task State Segment
* @struct tss Task State Segment
*
* A Task State Segment (TSS) is a binary data structure specific to the IA-32
* and x86-64 architectures.
Expand All @@ -74,7 +74,7 @@ typedef struct gdt_descriptor {
*
* @see https://wiki.osdev.org/Task_State_Segment
*/
typedef struct PACKED gdt_tss {
typedef struct PACKED tss {
u16 link;
u16 _reserved1;
u32 esp0;
Expand Down Expand Up @@ -114,7 +114,7 @@ typedef struct PACKED gdt_tss {
u16 _reserved12;
u16 iopb;
u32 ssp;
} gdt_tss;
} tss_t;

/**
* @union segment_selector
Expand Down Expand Up @@ -150,4 +150,7 @@ void gdt_load_segment(gdt_descriptor, u16 index);
/** Print the content of the GDT and GDTR. */
void gdt_log(void);

/** Modify the kernel stack pointer inside the current TSS */
void gdt_set_esp0(u32);

#endif /* KERNEL_ARCH_I686_GDT_H */
10 changes: 10 additions & 0 deletions include/kernel/arch/i686/interrupts.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,14 @@ static inline void interrupts_enable(void)
ASM("sti");
}

/* @brief Disable CPU interrupts
* @return Whether the interrupts where previously enabled
*/
static inline bool interrupts_test_and_disable(void)
{
u32 eflags;
ASM("pushf; cli; popl %0" : "=r"(eflags)::"memory");
return boolean(eflags & 0x200); // flag: IF
}

#endif /* KERNEL_I686_INTERRUPTS_H */
35 changes: 35 additions & 0 deletions include/kernel/arch/i686/process.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

/**
* @file kernel/arch/i686/process.h
*
* @defgroup x86_process Processes - x86
* @ingroup process
* @ingroup x86
*
* @{
*/

#include <kernel/types.h>

/**
* Contains all the system-level information about a task
* @struct x86_process
*/
typedef struct x86_process {

u32 cr3; ///< Physical address of the process's page directory

/**
* @brief Address of the top of the process's kernel stack.
*
* This is the value used by the kernel to locate the
* stack to use when switching from ring3 -> ring0.
* It should be loaded inside the current cpu's
* @link tss TSS.ESP0 @endlink when switching process.
*/
u32 esp0;

u32 esp; ///< The current stack pointer of the process

} process_context_t;
2 changes: 1 addition & 1 deletion include/kernel/devices/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

#include <kernel/types.h>

/** The frequency used for the timer (in KHz) */
/** The frequency used for the timer (in Hz) */
#define TIMER_TICK_FREQUENCY (1000) // 1KHz

/**
Expand Down
3 changes: 2 additions & 1 deletion include/kernel/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
*/
typedef enum error {
E_NONE, ///< No error
E_NOMEM = 12, ///< Out of memory
E_INVAL = 22, ///< Invalid argument
} error_t;

/** Check if an integer can be interpreted as an error */
#define IS_ERR(_x) ((_x) < 0)
#define IS_ERR(_x) ((s32)(_x) < 0)
7 changes: 6 additions & 1 deletion include/kernel/interrupts.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@

#ifndef INLINED_INTERRUPTS_DISABLE_ENABLE

/**@brief Disable CPU interrupts */
/** @brief Disable CPU interrupts */
void interrupts_disable(void);

/* @brief Disable CPU interrupts
* @return Whether the interrupts where previously enabled
*/
bool interrupts_test_and_disable(void);

/**@brief Enable CPU interrupts */
void interrupts_enable(void);

Expand Down
1 change: 1 addition & 0 deletions include/kernel/kmalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
*/
typedef enum kmalloc_flags {
KMALLOC_DEFAULT = 0x0, ///< Default
KMALLOC_KERNEL = 0x8, ///< Use kernel pages only (@ref VMA_KERNEL)
} kmalloc_flags;

/**
Expand Down
12 changes: 7 additions & 5 deletions include/kernel/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@ void log(const char *type, const char *domain, const char *msg, ...);
void panic(u32 esp, const char *msg, ...) __attribute__((__noreturn__));

/** @brief Call the panic function with the appropriate parameters */
#define PANIC(...) \
do { \
u32 esp = read_esp(); \
panic(esp, __VA_ARGS__); \
} while (0)
#define PANIC(...) \
{ \
do { \
u32 esp = read_esp(); \
panic(esp, __VA_ARGS__); \
} while (0); \
}

// TODO: LOG_LEVEL filter

Expand Down
35 changes: 33 additions & 2 deletions include/kernel/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,34 @@
*
* 0xFFFF_FFFF --------------------
* | |
* | Page Tables |
* 0xFFC0_0000 |------------------|
* | Kernel |
* | VMM Reserved |
* 0xFFB0_0000 |------------------|
* | |
* | |
* | |
* | Kernel Memory |
* | |
* | |
* | |
* 0xC000_0000 |------------------|
* | |
* | |
* | |
* | |
* | ... |
* | |
* | |
* | |
* | |
* | |
* 0x0110_0000 |------------------|
* | VMM Reserved |
* | VMM Reserved |
* 0x0100_0000 |------------------|
* | Reserved |
* 0x0000_0000 |------------------|
* 0x0000_0000 --------------------
*
* @{
*/
Expand Down Expand Up @@ -103,6 +118,22 @@ extern u32 _kernel_code_end;

#endif /* __ASSEMBLER__ */

#define PAGE_TABLES_START (0xFFC00000)

/** @brief Location of the reserved range for the kernel's VMM structure
* @ref kernel_vmm
* @{
*/
#define KERNEL_VMM_RESERVED_END (PAGE_TABLES_START)
#define KERNEL_VMM_RESERVED_START (KERNEL_VMM_RESERVED_END - VMM_RESERVED_SIZE)
/** @} */

#define KERNEL_MEMORY_END (KERNEL_VMM_RESERVED_START)
#define KERNEL_MEMORY_START (KERNEL_CODE_END)

#define USER_MEMORY_END KERNEL_MEMORY_START
#define USER_MEMORY_START VMM_RESERVED_END

/**
* @brief Size of the area reserved fo rallovation memory management structures
*
Expand Down
32 changes: 25 additions & 7 deletions include/kernel/mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,30 @@ typedef enum mmu_prot {
PROT_WRITE = 0x4, /*!< Pages may be written */
} mmu_prot;

/** @brief Inititialize the MMU's underlying structures */
bool mmu_init(void);

/**
* @brief Enable paging and automatic virtual address translation.
/** Initialize the MMU's paging system
*
* This function is responsible for setting any required bit inside the CPU's
* register.
*
* @warning After calling this function, each and every address will
* It is also responsible of remapping the kernel's code and addresses before
* enabling paging.
*
* @warning After calling this function, each and every address will
* automatically be translated into its physical equivalent using the paging
* mechanism. Be sure to remap known addresses to avoid raising exceptions.
*/
bool mmu_start_paging(void);
bool mmu_init(void);

/** @brief Inititialize a new page directory
* @return The physical address of the new page_directory, 0 if error.
*/
paddr_t mmu_new_page_directory(void);

/**
* @brief Replace the current page directory.
* @param page_directory The physical address of the page directory
*/
void mmu_load_page_directory(paddr_t);

/**
* @brief Map a virtual address to a physical one
Expand Down Expand Up @@ -89,4 +102,9 @@ paddr_t mmu_unmap(vaddr_t virt);
*/
void mmu_identity_map(paddr_t start, paddr_t end, int prot);

/** Find the physical mapping of a virtual address
* @return -E_INVAL if error, a physical address if none
*/
paddr_t mmu_find_physical(vaddr_t);

#endif /* KERNEL_MMU_H */
Loading

0 comments on commit b3c541a

Please sign in to comment.