implementation of TSS
This commit is contained in:
@@ -10,6 +10,14 @@ add_custom_target(
|
||||
COMMENT "Running versioning script")
|
||||
add_dependencies(${PROJECT_NAME} run_versioning_script-kernel)
|
||||
|
||||
add_custom_target(
|
||||
generate-iso ALL
|
||||
COMMAND "${PROJECT_SOURCE_DIR}/scripts/create_iso.sh"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
BYPRODUCTS "${PROJECT_SOURCE_DIR}/appa-os.iso"
|
||||
COMMENT "Creating ISO")
|
||||
add_dependencies(generate-iso ${PROJECT_NAME})
|
||||
|
||||
# Set target name to be "${PROJECT_NAME}.bin"
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
#include "gdt.h"
|
||||
#include "tss.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GDT_ENTRY_SIZE 5
|
||||
#define GDT_ENTRY_SIZE 6
|
||||
|
||||
static gdt_segment_descriptor_t gdt_descriptors[GDT_ENTRY_SIZE];
|
||||
static gdt_entry_t gdt;
|
||||
static tss_descriptor_t tss;
|
||||
|
||||
// https://github.com/szhou42/osdev/blob/52c02f0d4327442493459253a5c6c83c5f378765/src/kernel/descriptor_tables/tss_helper.asm#L3
|
||||
void tss_flush() {
|
||||
// TSS is the last entry on our gdt table
|
||||
const uint32_t tss_offset = sizeof(gdt_segment_descriptor_t) * (GDT_ENTRY_SIZE - 1);
|
||||
|
||||
asm volatile("mov %0, %%eax\n\t"
|
||||
"ltr %%eax\n\t" // Load the Task Register with the TSS selector in AX
|
||||
"ret\n\t" // Return to the caller
|
||||
:
|
||||
: "r"(tss_offset)
|
||||
: "eax");
|
||||
}
|
||||
|
||||
// https://forum.osdev.org/viewtopic.php?t=37245
|
||||
void gdt_flush() {
|
||||
uint32_t ptr = (uint32_t)&gdt;
|
||||
const uint32_t ptr = (uint32_t)&gdt;
|
||||
|
||||
asm volatile("movl %0,%%eax \n\t"
|
||||
"lgdt (%%eax) \n\t"
|
||||
@@ -25,45 +41,68 @@ void gdt_flush() {
|
||||
"movw %%ax, %%gs \n\t"
|
||||
"movw %%ax, %%ss \n\t"
|
||||
"ljmp $0x0008,$.gdt_flush_end%=\n\t"
|
||||
".gdt_flush_end%=:"
|
||||
".gdt_flush_end%=:\n\t"
|
||||
"ret\n\t"
|
||||
:
|
||||
: "r"(ptr)
|
||||
: "eax");
|
||||
}
|
||||
|
||||
void tss_init() {
|
||||
const uint32_t tss_base = (uint32_t)&tss;
|
||||
const uint32_t tss_limit = tss_base + sizeof(tss_descriptor_t);
|
||||
|
||||
// TODO: Somehow setting TSS to 0 crashes the system, why?
|
||||
// memset(&tss, 0, sizeof(tss));
|
||||
|
||||
// 0x10 corresponds to Kernel Mode Data Segment (gdt_descriptors[2]), 3rd entry on gdt table
|
||||
tss.ss0 = (uint16_t)(sizeof(gdt_segment_descriptor_t) * (2));
|
||||
tss.esp0 = (uint32_t)0x00;
|
||||
tss.iopb = (uint16_t)sizeof(tss_descriptor_t);
|
||||
|
||||
gdt_descriptors[5] = gdt_create_segment_descriptor(tss_base, tss_limit, 0x00, GDT_ACCESS_PRESENT(1) | GDT_CODE_EXA);
|
||||
}
|
||||
|
||||
void gdt_init() {
|
||||
// This is setting up 4 large seguments overlapped to use paging
|
||||
// https://stackoverflow.com/a/23979175
|
||||
gdt.limit = (sizeof(struct gdt_segment_descriptor) * GDT_ENTRY_SIZE) - 1;
|
||||
gdt.limit = (sizeof(gdt_segment_descriptor_t) * GDT_ENTRY_SIZE) - 1;
|
||||
gdt.base = (uint32_t)gdt_descriptors;
|
||||
|
||||
// Null Segment
|
||||
gdt_descriptors[0] = gdt_create_segment_descriptor(0, 0, 0, 0);
|
||||
|
||||
// Kernel Mode Code Segment with 4 megabytes
|
||||
// Kernel Mode Code Segment
|
||||
gdt_descriptors[1] = gdt_create_segment_descriptor(0, 0xFFFFFFFF, (GDT_FLAG_GRANULARITY(1) | GDT_FLAG_SIZE(1)) << 4,
|
||||
GDT_ACCESS_PRESENT(1) | GDT_ACCESS_PRIVILEGE(0) |
|
||||
GDT_ACCESS_DESCRIPTOR_TYPE(1) | GDT_CODE_EXRD);
|
||||
|
||||
// Kernel Mode Data Segment
|
||||
gdt_descriptors[2] = gdt_create_segment_descriptor(0, 0xFFFFFFFF, (GDT_FLAG_GRANULARITY(1) | GDT_FLAG_SIZE(1)) << 4,
|
||||
GDT_ACCESS_PRESENT(1) | GDT_ACCESS_PRIVILEGE(0) |
|
||||
GDT_ACCESS_DESCRIPTOR_TYPE(1) | GDT_DATA_RDWR);
|
||||
|
||||
// User Mode Code Segment
|
||||
gdt_descriptors[3] = gdt_create_segment_descriptor(0, 0xFFFFFFFF, (GDT_FLAG_GRANULARITY(1) | GDT_FLAG_SIZE(1)) << 4,
|
||||
GDT_ACCESS_PRESENT(1) | GDT_ACCESS_PRIVILEGE(3) |
|
||||
GDT_ACCESS_DESCRIPTOR_TYPE(1) | GDT_CODE_EXRD);
|
||||
|
||||
// User Mode Data Segment
|
||||
gdt_descriptors[4] = gdt_create_segment_descriptor(0, 0xFFFFFFFF, (GDT_FLAG_GRANULARITY(1) | GDT_FLAG_SIZE(1)) << 4,
|
||||
GDT_ACCESS_PRESENT(1) | GDT_ACCESS_PRIVILEGE(3) |
|
||||
GDT_ACCESS_DESCRIPTOR_TYPE(1) | GDT_DATA_RDWR);
|
||||
// TODO: add Task State Segment
|
||||
tss_init();
|
||||
|
||||
// Load and flush the GDT
|
||||
gdt_flush();
|
||||
|
||||
// Load the TSS
|
||||
tss_flush();
|
||||
}
|
||||
|
||||
gdt_segment_descriptor_t gdt_create_segment_descriptor(uint32_t base, uint32_t limit, uint8_t flags, uint8_t access) {
|
||||
if (limit > UINT32_MAX) {
|
||||
printf("GDT cannot encode limits larger than 0xFFFFF");
|
||||
printf("GDT cannot encode limits larger than %X", UINT32_MAX);
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ gdt_segment_descriptor_t gdt_create_segment_descriptor(uint32_t base, uint32_t l
|
||||
|
||||
void gdt_init();
|
||||
|
||||
void gdt_flush();
|
||||
extern void gdt_flush();
|
||||
extern void tts_flush();
|
||||
|
||||
#endif // INCLUDE_GDT_H_
|
||||
0
src/kernel/arch/i386/gdt.s
Normal file
0
src/kernel/arch/i386/gdt.s
Normal file
57
src/kernel/arch/i386/tss.h
Normal file
57
src/kernel/arch/i386/tss.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#ifndef INCLUDE_INCLUDE_TSS_H_
|
||||
#define INCLUDE_INCLUDE_TSS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct tss_descriptor {
|
||||
uint32_t link;
|
||||
uint32_t esp0;
|
||||
uint32_t ss0;
|
||||
uint32_t esp1;
|
||||
uint32_t ss1;
|
||||
uint32_t esp2;
|
||||
uint32_t ss2;
|
||||
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;
|
||||
uint32_t es;
|
||||
uint32_t cs;
|
||||
uint32_t ss;
|
||||
uint32_t ds;
|
||||
uint32_t fs;
|
||||
uint32_t gs;
|
||||
uint32_t ldtr;
|
||||
// Some places place those two below as uint16_t? // http://www.brokenthorn.com/Resources/OSDev23.html
|
||||
uint16_t iopb;
|
||||
uint16_t ssp;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct tss_descriptor tss_descriptor_t;
|
||||
|
||||
void tss_flush();
|
||||
|
||||
#endif // INCLUDE_INCLUDE_TSS_H_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "gdt.h"
|
||||
#include "arch/i386/gdt.h"
|
||||
#include "kernel/tty.h"
|
||||
#include "version.h"
|
||||
#include <stdint.h>
|
||||
@@ -23,7 +23,6 @@ void kprintf(const char *format, ...) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((noinline)) kernel_main(void) {
|
||||
tty_initialize();
|
||||
kprintf("Appa-OS version %s\n", VERSION);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef INCLUDE_KERNEL_KERNEL_H_
|
||||
#define INCLUDE_KERNEL_KERNEL_H_
|
||||
|
||||
void kprintf(const char *format, ...)
|
||||
void kprintf(const char *format, ...);
|
||||
|
||||
#endif // INCLUDE_KERNEL_KERNEL_H_
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
#define APPA_OS_VERSION_MAJOR 0
|
||||
#define APPA_OS_VERSION_MINOR 0
|
||||
#define APPA_OS_VERSION_PATCH 154
|
||||
#define APPA_OS_VERSION_PATCH 233
|
||||
#define APPA_OS_COMMIT_HASH cd01d7d8d36862bc00ae88f7cd185c352a7b7eda
|
||||
#define APPA_OS_BUILD_TIMESTAMP 1730732925
|
||||
#define APPA_OS_BUILD_TIMESTAMP 1730754533
|
||||
|
||||
#endif // INCLUDE_APPA_OS_VERSION_H_
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
#define LIB_C_VERSION_MAJOR 0
|
||||
#define LIB_C_VERSION_MINOR 0
|
||||
#define LIB_C_VERSION_PATCH 148
|
||||
#define LIB_C_VERSION_PATCH 227
|
||||
#define LIB_C_COMMIT_HASH cd01d7d8d36862bc00ae88f7cd185c352a7b7eda
|
||||
#define LIB_C_BUILD_TIMESTAMP 1730732925
|
||||
#define LIB_C_BUILD_TIMESTAMP 1730754533
|
||||
|
||||
#endif // INCLUDE_LIB_C_VERSION_H_
|
||||
|
||||
|
||||
Reference in New Issue
Block a user