Install new GDT in C code.
This commit is contained in:
parent
f6bbebbee3
commit
fb88c62f67
2
Makefile
2
Makefile
@ -39,7 +39,7 @@ image.bin: mbr.bin fs.img
|
||||
cat $^ >$@
|
||||
|
||||
kernel.bin: kernel.o console.o drivers/vga.o drivers/keyboard.o \
|
||||
string.o drivers/ata.o cpu/vectors.o cpu/idt.o drivers/uart.o
|
||||
string.o drivers/ata.o cpu/vectors.o cpu/idt.o cpu/gdt.o drivers/uart.o
|
||||
$(LD) $(LDFLAGS) -o $@ -Ttext 0x1000 $^
|
||||
|
||||
%.o: %.c
|
||||
|
||||
49
cpu/gdt.c
Normal file
49
cpu/gdt.c
Normal file
@ -0,0 +1,49 @@
|
||||
#include "gdt.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct seg_desc_t {
|
||||
uint16_t lim_15_0; // Low bits of segment limit
|
||||
uint16_t base_15_0; // Low bits of segment base address
|
||||
uint8_t base_23_16; // Middle bits of segment base address
|
||||
uint8_t type : 4; // Segment type (see STS_ constants)
|
||||
uint8_t s : 1; // 0 = system, 1 = application
|
||||
uint8_t dpl : 2; // Descriptor Privilege Level
|
||||
uint8_t p : 1; // Present
|
||||
uint8_t lim_19_16 : 4; // High bits of segment limit
|
||||
uint8_t avl : 1; // Unused (available for software use)
|
||||
uint8_t rsv1 : 1; // Reserved
|
||||
uint8_t db : 1; // 0 = 16-bit segment, 1 = 32-bit segment
|
||||
uint8_t g : 1; // Granularity: limit scaled by 4K when set
|
||||
uint8_t base_31_24; // High bits of segment base address
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef unsigned uint;
|
||||
|
||||
#define SEG(type, base, lim, dpl) (struct seg_desc_t) \
|
||||
{ ((lim) >> 12) & 0xffff, (uint)(base) & 0xffff, \
|
||||
((uint)(base) >> 16) & 0xff, type, 1, dpl, 1, \
|
||||
(uint)(lim) >> 28, 0, 0, 1, 1, (uint)(base) >> 24 }
|
||||
|
||||
struct seg_desc_t seg_desc[6];
|
||||
|
||||
void init_seg_desc() {
|
||||
seg_desc[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, 0);
|
||||
seg_desc[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0);
|
||||
seg_desc[SEG_UCODE] = SEG(STA_X|STA_R, USER_BASE, 0xffffffff - USER_BASE, DPL_USER);
|
||||
seg_desc[SEG_UDATA] = SEG(STA_W, USER_BASE, 0xffffffff - USER_BASE, DPL_USER);
|
||||
}
|
||||
|
||||
struct gdt_desc_t {
|
||||
uint16_t size;
|
||||
void* ptr;
|
||||
} __attribute__((packed));
|
||||
|
||||
void load_gdt() {
|
||||
init_seg_desc();
|
||||
|
||||
struct gdt_desc_t gdt_desc;
|
||||
gdt_desc.size = sizeof(seg_desc) - 1;
|
||||
gdt_desc.ptr = seg_desc;
|
||||
asm("lgdt %0": : "m"(gdt_desc));
|
||||
}
|
||||
19
cpu/gdt.h
Normal file
19
cpu/gdt.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#define STA_X 0x8 // Executable segment
|
||||
#define STA_W 0x2 // Writeable (non-executable segments)
|
||||
#define STA_R 0x2 // Readable (executable segments)
|
||||
|
||||
#define DPL_USER 3
|
||||
|
||||
#define SEG_KCODE 1
|
||||
#define SEG_KDATA 2
|
||||
#define SEG_UCODE 3
|
||||
#define SEG_UDATA 4
|
||||
#define SEG_TSS 5
|
||||
|
||||
#define USER_BASE 0x400000 // 4 MB
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
void load_gdt();
|
||||
#endif
|
||||
2
kernel.c
2
kernel.c
@ -2,6 +2,7 @@ asm(".asciz \"kernel start\"");
|
||||
|
||||
#include "console.h"
|
||||
#include "cpu/isr.h"
|
||||
#include "cpu/gdt.h"
|
||||
#include "drivers/keyboard.h"
|
||||
#include "drivers/vga.h"
|
||||
#include "drivers/ata.h"
|
||||
@ -9,6 +10,7 @@ asm(".asciz \"kernel start\"");
|
||||
#include "drivers/uart.h"
|
||||
|
||||
void _start() {
|
||||
load_gdt();
|
||||
init_keyboard();
|
||||
uartinit();
|
||||
load_idt();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user