implementation of TSS

This commit is contained in:
brenozd
2024-11-04 18:09:30 -03:00
parent 6585102503
commit 16a6bafa24
9 changed files with 119 additions and 15 deletions

View File

@@ -10,6 +10,14 @@ add_custom_target(
COMMENT "Running versioning script") COMMENT "Running versioning script")
add_dependencies(${PROJECT_NAME} run_versioning_script-kernel) 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 name to be "${PROJECT_NAME}.bin"
set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "")
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}") set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")

View File

@@ -1,15 +1,31 @@
#include "gdt.h" #include "gdt.h"
#include "tss.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.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_segment_descriptor_t gdt_descriptors[GDT_ENTRY_SIZE];
static gdt_entry_t gdt; 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 // https://forum.osdev.org/viewtopic.php?t=37245
void gdt_flush() { void gdt_flush() {
uint32_t ptr = (uint32_t)&gdt; const uint32_t ptr = (uint32_t)&gdt;
asm volatile("movl %0,%%eax \n\t" asm volatile("movl %0,%%eax \n\t"
"lgdt (%%eax) \n\t" "lgdt (%%eax) \n\t"
@@ -25,45 +41,68 @@ void gdt_flush() {
"movw %%ax, %%gs \n\t" "movw %%ax, %%gs \n\t"
"movw %%ax, %%ss \n\t" "movw %%ax, %%ss \n\t"
"ljmp $0x0008,$.gdt_flush_end%=\n\t" "ljmp $0x0008,$.gdt_flush_end%=\n\t"
".gdt_flush_end%=:" ".gdt_flush_end%=:\n\t"
"ret\n\t"
: :
: "r"(ptr) : "r"(ptr)
: "eax"); : "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() { void gdt_init() {
// This is setting up 4 large seguments overlapped to use paging // This is setting up 4 large seguments overlapped to use paging
// https://stackoverflow.com/a/23979175 // 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; gdt.base = (uint32_t)gdt_descriptors;
// Null Segment // Null Segment
gdt_descriptors[0] = gdt_create_segment_descriptor(0, 0, 0, 0); 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_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_PRESENT(1) | GDT_ACCESS_PRIVILEGE(0) |
GDT_ACCESS_DESCRIPTOR_TYPE(1) | GDT_CODE_EXRD); 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_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_PRESENT(1) | GDT_ACCESS_PRIVILEGE(0) |
GDT_ACCESS_DESCRIPTOR_TYPE(1) | GDT_DATA_RDWR); 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_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_PRESENT(1) | GDT_ACCESS_PRIVILEGE(3) |
GDT_ACCESS_DESCRIPTOR_TYPE(1) | GDT_CODE_EXRD); 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_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_PRESENT(1) | GDT_ACCESS_PRIVILEGE(3) |
GDT_ACCESS_DESCRIPTOR_TYPE(1) | GDT_DATA_RDWR); GDT_ACCESS_DESCRIPTOR_TYPE(1) | GDT_DATA_RDWR);
// TODO: add Task State Segment tss_init();
// Load and flush the GDT // Load and flush the GDT
gdt_flush(); 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) { gdt_segment_descriptor_t gdt_create_segment_descriptor(uint32_t base, uint32_t limit, uint8_t flags, uint8_t access) {
if (limit > UINT32_MAX) { if (limit > UINT32_MAX) {
printf("GDT cannot encode limits larger than 0xFFFFF"); printf("GDT cannot encode limits larger than %X", UINT32_MAX);
abort(); abort();
} }

View File

@@ -65,6 +65,7 @@ gdt_segment_descriptor_t gdt_create_segment_descriptor(uint32_t base, uint32_t l
void gdt_init(); void gdt_init();
void gdt_flush(); extern void gdt_flush();
extern void tts_flush();
#endif // INCLUDE_GDT_H_ #endif // INCLUDE_GDT_H_

View File

View 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_

View File

@@ -1,4 +1,4 @@
#include "gdt.h" #include "arch/i386/gdt.h"
#include "kernel/tty.h" #include "kernel/tty.h"
#include "version.h" #include "version.h"
#include <stdint.h> #include <stdint.h>
@@ -23,7 +23,6 @@ void kprintf(const char *format, ...) {
} }
} }
void __attribute__((noinline)) kernel_main(void) { void __attribute__((noinline)) kernel_main(void) {
tty_initialize(); tty_initialize();
kprintf("Appa-OS version %s\n", VERSION); kprintf("Appa-OS version %s\n", VERSION);

View File

@@ -1,6 +1,6 @@
#ifndef INCLUDE_KERNEL_KERNEL_H_ #ifndef INCLUDE_KERNEL_KERNEL_H_
#define INCLUDE_KERNEL_KERNEL_H_ #define INCLUDE_KERNEL_KERNEL_H_
void kprintf(const char *format, ...) void kprintf(const char *format, ...);
#endif // INCLUDE_KERNEL_KERNEL_H_ #endif // INCLUDE_KERNEL_KERNEL_H_

View File

@@ -8,9 +8,9 @@
#define APPA_OS_VERSION_MAJOR 0 #define APPA_OS_VERSION_MAJOR 0
#define APPA_OS_VERSION_MINOR 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_COMMIT_HASH cd01d7d8d36862bc00ae88f7cd185c352a7b7eda
#define APPA_OS_BUILD_TIMESTAMP 1730732925 #define APPA_OS_BUILD_TIMESTAMP 1730754533
#endif // INCLUDE_APPA_OS_VERSION_H_ #endif // INCLUDE_APPA_OS_VERSION_H_

View File

@@ -8,9 +8,9 @@
#define LIB_C_VERSION_MAJOR 0 #define LIB_C_VERSION_MAJOR 0
#define LIB_C_VERSION_MINOR 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_COMMIT_HASH cd01d7d8d36862bc00ae88f7cd185c352a7b7eda
#define LIB_C_BUILD_TIMESTAMP 1730732925 #define LIB_C_BUILD_TIMESTAMP 1730754533
#endif // INCLUDE_LIB_C_VERSION_H_ #endif // INCLUDE_LIB_C_VERSION_H_