Merge pull request #1 from Azomasiel/gdt
Memory management: Global Descriptor Table
This commit is contained in:
commit
439394c667
1
.bochsrc
1
.bochsrc
@ -11,6 +11,7 @@ clock: sync=realtime
|
|||||||
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
|
||||||
ata0-master: type=cdrom, path="k.iso", status=inserted
|
ata0-master: type=cdrom, path="k.iso", status=inserted
|
||||||
boot: cdrom
|
boot: cdrom
|
||||||
|
magic_break: enabled=1
|
||||||
|
|
||||||
# write serial logs to stdout
|
# write serial logs to stdout
|
||||||
com1: enabled=1, mode=file, dev=/dev/stdout
|
com1: enabled=1, mode=file, dev=/dev/stdout
|
||||||
|
@ -30,7 +30,8 @@ OBJS = \
|
|||||||
libvga.o \
|
libvga.o \
|
||||||
list.o \
|
list.o \
|
||||||
memory.o \
|
memory.o \
|
||||||
serial.o
|
serial.o \
|
||||||
|
gdt.o
|
||||||
|
|
||||||
|
|
||||||
DEPS = $(OBJS:.o=.d)
|
DEPS = $(OBJS:.o=.d)
|
||||||
|
122
k/gdt.c
Normal file
122
k/gdt.c
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "gdt.h"
|
||||||
|
|
||||||
|
static struct gdt gdt = { 0 };
|
||||||
|
|
||||||
|
static void create_kernel_ds()
|
||||||
|
{
|
||||||
|
struct gdt_entry *entry = gdt.entries + KERNEL_DS_INDEX;
|
||||||
|
|
||||||
|
uint32_t limit = 0xfffff;
|
||||||
|
uint32_t base = 0x0;
|
||||||
|
|
||||||
|
entry->granularity = 1;
|
||||||
|
entry->db = 1;
|
||||||
|
entry->l = 0;
|
||||||
|
entry->available = 0;
|
||||||
|
|
||||||
|
entry->present = 1;
|
||||||
|
entry->desc_priv = 0;
|
||||||
|
entry->desc_type = 1;
|
||||||
|
entry->ex = 0;
|
||||||
|
entry->dc = 0;
|
||||||
|
entry->rw = 1;
|
||||||
|
entry->accessed = 0;
|
||||||
|
|
||||||
|
entry->limit_1 = limit & 0xffff;
|
||||||
|
entry->limit_2 = (limit >> 16) & 0xf;
|
||||||
|
|
||||||
|
entry->base_1 = base & 0xffff;
|
||||||
|
entry->base_2 = (base >> 16) & 0xff;
|
||||||
|
entry->base_3 = (base >> 24) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_kernel_cs()
|
||||||
|
{
|
||||||
|
struct gdt_entry *entry = gdt.entries + KERNEL_CS_INDEX;
|
||||||
|
|
||||||
|
uint32_t limit = 0xfffff;
|
||||||
|
uint32_t base = 0x0;
|
||||||
|
|
||||||
|
entry->granularity = 1;
|
||||||
|
entry->db = 1;
|
||||||
|
entry->l = 0;
|
||||||
|
entry->available = 0;
|
||||||
|
|
||||||
|
entry->present = 1;
|
||||||
|
entry->desc_priv = 0;
|
||||||
|
entry->desc_type = 1;
|
||||||
|
entry->ex = 1;
|
||||||
|
entry->dc = 0;
|
||||||
|
entry->rw = 1;
|
||||||
|
entry->accessed = 0;
|
||||||
|
|
||||||
|
entry->limit_1 = limit & 0xffff;
|
||||||
|
entry->limit_2 = (limit >> 16) & 0xf;
|
||||||
|
|
||||||
|
entry->base_1 = base & 0xffff;
|
||||||
|
entry->base_2 = (base >> 16) & 0xff;
|
||||||
|
entry->base_3 = (base >> 24) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_gdt()
|
||||||
|
{
|
||||||
|
create_kernel_ds();
|
||||||
|
create_kernel_cs();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_gdt()
|
||||||
|
{
|
||||||
|
struct gdt_r gdtr;
|
||||||
|
gdtr.addr = (uint32_t)&gdt;
|
||||||
|
gdtr.limit = GDT_SIZE - 1;
|
||||||
|
|
||||||
|
asm volatile("lgdt %0\n"
|
||||||
|
:
|
||||||
|
: "m" (gdtr)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_ds()
|
||||||
|
{
|
||||||
|
struct segment_selector selector;
|
||||||
|
selector.index = KERNEL_DS_INDEX;
|
||||||
|
selector.table_indicator = 0;
|
||||||
|
selector.rpl = 0;
|
||||||
|
|
||||||
|
asm volatile("movw %0, %%ax\n"
|
||||||
|
"movw %%ax, %%ds\n"
|
||||||
|
"movw %%ax, %%fs\n"
|
||||||
|
"movw %%ax, %%gs\n"
|
||||||
|
"movw %%ax, %%ss\n"
|
||||||
|
:
|
||||||
|
: "m" (selector)
|
||||||
|
: "ax");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_cs()
|
||||||
|
{
|
||||||
|
struct segment_selector selector;
|
||||||
|
selector.index = KERNEL_CS_INDEX;
|
||||||
|
selector.table_indicator = 0;
|
||||||
|
selector.rpl = 0;
|
||||||
|
|
||||||
|
asm volatile("pushl %0\n"
|
||||||
|
"pushl $1f\n"
|
||||||
|
"lret\n"
|
||||||
|
"1:\n"
|
||||||
|
:
|
||||||
|
: "m" (selector));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reload_segment_selectors()
|
||||||
|
{
|
||||||
|
load_ds();
|
||||||
|
load_cs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_gdt()
|
||||||
|
{
|
||||||
|
create_gdt();
|
||||||
|
load_gdt();
|
||||||
|
reload_segment_selectors();
|
||||||
|
}
|
52
k/gdt.h
Normal file
52
k/gdt.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef GDT_H
|
||||||
|
#define GDT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define GDT_NB_ENTRIES 3
|
||||||
|
#define GDT_SIZE (GDT_NB_ENTRIES * sizeof(struct gdt_entry))
|
||||||
|
|
||||||
|
#define KERNEL_CS_INDEX 1
|
||||||
|
#define KERNEL_DS_INDEX 2
|
||||||
|
|
||||||
|
struct gdt_entry
|
||||||
|
{
|
||||||
|
uint16_t limit_1 : 16;
|
||||||
|
uint16_t base_1 : 16;
|
||||||
|
uint8_t base_2 : 8;
|
||||||
|
uint8_t accessed : 1;
|
||||||
|
uint8_t rw : 1;
|
||||||
|
uint8_t dc : 1;
|
||||||
|
uint8_t ex : 1;
|
||||||
|
uint8_t desc_type : 1;
|
||||||
|
uint8_t desc_priv : 2;
|
||||||
|
uint8_t present : 1;
|
||||||
|
uint8_t limit_2 : 4;
|
||||||
|
uint8_t available : 1;
|
||||||
|
uint8_t l : 1;
|
||||||
|
uint8_t db : 1;
|
||||||
|
uint8_t granularity : 1;
|
||||||
|
uint8_t base_3 : 8;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct gdt
|
||||||
|
{
|
||||||
|
struct gdt_entry entries[GDT_NB_ENTRIES];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gdt_r
|
||||||
|
{
|
||||||
|
uint16_t limit;
|
||||||
|
uint32_t addr;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct segment_selector
|
||||||
|
{
|
||||||
|
uint8_t rpl : 2;
|
||||||
|
uint8_t table_indicator : 1;
|
||||||
|
uint16_t index : 13;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
void init_gdt();
|
||||||
|
|
||||||
|
#endif /* !GDT_H */
|
1
k/k.c
1
k/k.c
@ -30,6 +30,7 @@
|
|||||||
static void k_init(void)
|
static void k_init(void)
|
||||||
{
|
{
|
||||||
init_serial();
|
init_serial();
|
||||||
|
init_gdt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void k_main(unsigned long magic, multiboot_info_t *info)
|
void k_main(unsigned long magic, multiboot_info_t *info)
|
||||||
|
@ -24,12 +24,12 @@ void init_serial(void)
|
|||||||
|
|
||||||
int write(const char *buf, size_t count)
|
int write(const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
int sent;
|
size_t sent;
|
||||||
|
|
||||||
for(sent = 0; sent < count; ++sent)
|
for(sent = 0; sent < count; ++sent)
|
||||||
{
|
{
|
||||||
u8 line_status = inb(COM1 + 5);
|
u8 line_status = inb(COM1 + 5);
|
||||||
if (!line_status & EMPTY_TRANSMITTER)
|
if (!(line_status & EMPTY_TRANSMITTER))
|
||||||
break;
|
break;
|
||||||
outb(COM1, buf[sent]);
|
outb(COM1, buf[sent]);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user