|
|
@@ -1,44 +1,89 @@
|
|
|
/**
|
|
|
* @brief 安装 TSS 到 GDT,安装用户代码段、数据段到 GDT
|
|
|
* @note 安装后系统 GDT 显示如下:
|
|
|
- * gdt (base=0x00000000c0000900, limit=55):
|
|
|
- * gdt[0x0000]=<null entry>
|
|
|
- * gdt[0x0008]=Code segment, base=0x00000000, limit=0xffffffff, Execute-Only, Non-Conforming, Accessed, 32-bit
|
|
|
- * gdt[0x0010]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
|
|
|
- * gdt[0x0018]=Data segment, base=0xc00b8000, limit=0x00007fff, Read/Write, Accessed
|
|
|
- * gdt[0x0020]=32-Bit TSS (Busy) at 0xc0005560, length 0x0006b
|
|
|
- * gdt[0x0028]=Code segment, base=0x00000000, limit=0xffffffff, Execute-Only, Non-Conforming, 32-bit
|
|
|
- * gdt[0x0030]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write
|
|
|
+ * <bochs:6> info gdt
|
|
|
+ * gdt (base=0x00000000c0000900, limit=55):
|
|
|
+ * gdt[0x0000]=<null entry>
|
|
|
+ * gdt[0x0008]=Code segment, base=0x00000000, limit=0xffffffff, Execute-Only, Non-Conforming, Accessed, 32-bit
|
|
|
+ * gdt[0x0010]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write, Accessed
|
|
|
+ * gdt[0x0018]=Data segment, base=0xc00b8000, limit=0x00007fff, Read/Write, Accessed
|
|
|
+ * gdt[0x0020]=32-Bit TSS (Busy) at 0xc0006b40, length 0x0006b
|
|
|
+ * gdt[0x0028]=Code segment, base=0x00000000, limit=0xffffffff, Execute-Only, Non-Conforming, 32-bit
|
|
|
+ * gdt[0x0030]=Data segment, base=0x00000000, limit=0xffffffff, Read/Write
|
|
|
+ * You can list individual entries with 'info gdt [NUM]' or groups with 'info gdt [NUM] [NUM]'
|
|
|
*/
|
|
|
#include "tss.h"
|
|
|
#include "../kernel/global.h"
|
|
|
#include "../lib/kernel/print.h"
|
|
|
#include "../lib/string.h"
|
|
|
|
|
|
-/// @brief TSS implementation
|
|
|
-static Tss tss;
|
|
|
+/**
|
|
|
+ * @file tss.c
|
|
|
+ * @brief Header file for the Task State Segment (TSS) structure.
|
|
|
+ *
|
|
|
+ * This file contains the definition of the TSS structure used in the
|
|
|
+ * operating system kernel's user program module. The TSS is used to
|
|
|
+ * store information about a task, such as stack pointers and segment
|
|
|
+ * selectors, which are essential for task switching in protected mode.
|
|
|
+ */
|
|
|
+struct tss
|
|
|
+{
|
|
|
+ uint32_t backlink; // 上一个任务的 TSS 指针
|
|
|
+ uint32_t *esp0;
|
|
|
+ uint32_t ss0;
|
|
|
+ uint32_t *esp1;
|
|
|
+ uint32_t ss1;
|
|
|
+ uint32_t *esp2;
|
|
|
+ uint32_t ss2;
|
|
|
+ uint32_t cr3;
|
|
|
+ uint32_t (*eip)(void);
|
|
|
+ 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 ldt;
|
|
|
+ uint32_t trace;
|
|
|
+ uint32_t io_base;
|
|
|
+};
|
|
|
+static struct tss tss;
|
|
|
+
|
|
|
/// @brief 创建 GDT 描述符
|
|
|
/// @param desc_addr 基址
|
|
|
/// @param limit 界限
|
|
|
/// @param attr_low 属性(低位)
|
|
|
-/// @param attr_high 属性(低位)
|
|
|
+/// @param attr_high 属性(高位)
|
|
|
/// @return GdtDescriptor
|
|
|
-static GdtDesc make_gdt_desc(uint32_t *desc_addr, uint32_t limit, uint8_t attr_low, uint8_t attr_high);
|
|
|
+static struct gdt_desc make_gdt_desc(uint32_t *desc_addr, uint32_t limit, uint8_t attr_low, uint8_t attr_high);
|
|
|
+
|
|
|
+#pragma GCC diagnostic push
|
|
|
+#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
|
|
|
+#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
|
|
|
|
|
|
void update_tss_esp(struct task_struct *pthread)
|
|
|
{
|
|
|
- tss.esp0 = (uint32_t *)((uintptr_t)pthread + PG_SIZE); // 0 级线程的 esp0 指向 pthread 的 0 级线程的 ESP
|
|
|
+ tss.esp0 = (uint32_t *)((uint32_t)pthread + PG_SIZE); // 0 级线程的 esp0 指向 pthread 的 0 级线程的 ESP
|
|
|
}
|
|
|
|
|
|
-static GdtDesc make_gdt_desc(uint32_t *desc_addr, uint32_t limit, uint8_t attr_low, uint8_t attr_high)
|
|
|
+static struct gdt_desc make_gdt_desc(uint32_t *desc_addr, uint32_t limit, uint8_t attr_low, uint8_t attr_high)
|
|
|
{
|
|
|
- uint32_t desc_base = (uint32_t)(uintptr_t)desc_addr;
|
|
|
+ uint32_t desc_base = (uint32_t)desc_addr;
|
|
|
struct gdt_desc desc;
|
|
|
desc.limit_low_word = limit & 0xFFFF;
|
|
|
desc.base_low_word = desc_base & 0xFFFF;
|
|
|
desc.base_middle_byte = ((desc_base & 0x00ff0000) >> 16);
|
|
|
desc.attr_low_byte = (uint8_t)attr_low;
|
|
|
- desc.limit_high_attr_high = ((uint8_t)(attr_high) + ((limit & 0x000f0000) >> 16));
|
|
|
+ desc.limit_high_attr_high = (((limit & 0x000f0000) >> 16) + (uint8_t)(attr_high));
|
|
|
desc.base_high_byte = desc_base >> 24;
|
|
|
|
|
|
return desc;
|
|
|
@@ -51,15 +96,15 @@ void tss_init(void)
|
|
|
_memset(&tss, 0, tss_size);
|
|
|
|
|
|
tss.ss0 = SELECTOR_K_STACK;
|
|
|
- tss.iomap = tss_size;
|
|
|
+ tss.io_base = tss_size;
|
|
|
|
|
|
/* gdt 段基址为 0x900,把 tss 放到第 4 个位置,也就是 0x900+0x20 的位置 */
|
|
|
|
|
|
// 在 gdt 中添加 dpl 为 0 的 TSS 描述符
|
|
|
- *((GdtDesc *)0xc0000920) = make_gdt_desc((uint32_t *)&tss, tss_size - 1, TSS_ATTR_LOW, TSS_ATTR_HIGH);
|
|
|
+ *((struct gdt_desc *)0xc0000920) = make_gdt_desc((uint32_t *)&tss, tss_size - 1, TSS_ATTR_LOW, TSS_ATTR_HIGH);
|
|
|
// 在 gdt 中添加 dpl 为 3 的数据段和代码段描述符
|
|
|
- *((GdtDesc *)0xc0000928) = make_gdt_desc((uint32_t *)0, 0xfffff, GDT_CODE_ATTR_LOW_DPL3, GDT_ATTR_HIGH);
|
|
|
- *((GdtDesc *)0xc0000930) = make_gdt_desc((uint32_t *)0, 0xfffff, GDT_DATA_ATTR_LOW_DPL3, GDT_ATTR_HIGH);
|
|
|
+ *((struct gdt_desc *)0xc0000928) = make_gdt_desc((uint32_t *)0, 0xfffff, GDT_CODE_ATTR_LOW_DPL3, GDT_ATTR_HIGH);
|
|
|
+ *((struct gdt_desc *)0xc0000930) = make_gdt_desc((uint32_t *)0, 0xfffff, GDT_DATA_ATTR_LOW_DPL3, GDT_ATTR_HIGH);
|
|
|
|
|
|
// gdt 的指针,前 2 个字节(16 位)是 gdt 界限 limit,后 4 字节(32位)是 gdt 起始地址 Base
|
|
|
uint64_t gdt_operand_ptr = (8 * 7 - 1) | ((uint64_t)(uint32_t)0xc0000900 << 16); // 7 个描述符大小
|
|
|
@@ -68,4 +113,6 @@ void tss_init(void)
|
|
|
asm volatile("ltr %w0" ::"r"(SELECTOR_TSS));
|
|
|
|
|
|
put_str("tss_init and ltr done\n");
|
|
|
-}
|
|
|
+}
|
|
|
+
|
|
|
+#pragma GCC diagnostic pop
|