Merge branch 'khorben/gdt'
This commit is contained in:
commit
084bdd18a2
|
@ -9,20 +9,36 @@
|
||||||
.section .text
|
.section .text
|
||||||
/* arch_setgdt */
|
/* arch_setgdt */
|
||||||
.global __arch_setgdt
|
.global __arch_setgdt
|
||||||
|
#ifndef __clang__
|
||||||
.type __arch_setgdt, @function
|
.type __arch_setgdt, @function
|
||||||
__arch_setgdt:
|
|
||||||
#if 0
|
|
||||||
lea gdt_descriptor, %rcx
|
|
||||||
#else
|
|
||||||
mov (gdt_descriptor), %rcx
|
|
||||||
#endif
|
#endif
|
||||||
|
__arch_setgdt:
|
||||||
|
lea gdt_descriptor, %rcx
|
||||||
|
|
||||||
/* set the offset of the GDT */
|
/* set the offset of the GDT */
|
||||||
mov %rsi, 0x2(%rcx)
|
mov %rsi, 0x2(%rcx)
|
||||||
|
|
||||||
/* set the size of the GDT */
|
/* set the size of the GDT */
|
||||||
|
shl $0x3, %rdi
|
||||||
dec %rdi
|
dec %rdi
|
||||||
mov %di, (%rcx)
|
mov %di, (%rcx)
|
||||||
|
|
||||||
/* load the GDT */
|
/* load the GDT */
|
||||||
lgdt (%rcx)
|
lgdt (%rcx)
|
||||||
|
|
||||||
|
push $0x8
|
||||||
|
lea gdt_flush, %rax
|
||||||
|
push %rax
|
||||||
|
retf
|
||||||
|
|
||||||
|
gdt_flush:
|
||||||
|
mov $0x10, %ax
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
|
mov %ax, %ss
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,4 +47,4 @@ __arch_setgdt:
|
||||||
.align 16
|
.align 16
|
||||||
gdt_descriptor:
|
gdt_descriptor:
|
||||||
.skip 2 /* size */
|
.skip 2 /* size */
|
||||||
.skip 4 /* offset */
|
.skip 8 /* offset */
|
||||||
|
|
|
@ -14,15 +14,29 @@
|
||||||
#endif
|
#endif
|
||||||
__arch_setgdt:
|
__arch_setgdt:
|
||||||
lea gdt_descriptor, %ecx
|
lea gdt_descriptor, %ecx
|
||||||
|
|
||||||
/* set the offset of the GDT */
|
/* set the offset of the GDT */
|
||||||
mov 0x4(%esp), %eax
|
mov 0x4(%esp), %eax
|
||||||
mov %eax, 0x2(%ecx)
|
mov %eax, 0x2(%ecx)
|
||||||
|
|
||||||
/* set the size of the GDT */
|
/* set the size of the GDT */
|
||||||
mov 0x8(%esp), %eax
|
mov 0x8(%esp), %eax
|
||||||
|
shl $0x3, %eax
|
||||||
dec %eax
|
dec %eax
|
||||||
mov %ax, (%ecx)
|
mov %ax, (%ecx)
|
||||||
/* load the GDT */
|
/* load the GDT */
|
||||||
lgdt (%ecx)
|
lgdt (gdt_descriptor)
|
||||||
|
|
||||||
|
/* apply the GDT */
|
||||||
|
mov $0x10, %ax
|
||||||
|
mov %ax, %ds
|
||||||
|
mov %ax, %es
|
||||||
|
mov %ax, %fs
|
||||||
|
mov %ax, %gs
|
||||||
|
mov %ax, %ss
|
||||||
|
ljmp $0x08, $gdt_flush
|
||||||
|
gdt_flush:
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/* Copyright (c) 2018 Pierre Pronchery <khorben@defora.org> */
|
/* Copyright (c) 2018-2025 Pierre Pronchery <khorben@defora.org> */
|
||||||
/* This file is part of DeforaOS uKernel */
|
/* This file is part of DeforaOS uKernel */
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,21 +7,31 @@
|
||||||
#ifndef UKERNEL_ARCH_I386_GDT_H
|
#ifndef UKERNEL_ARCH_I386_GDT_H
|
||||||
# define UKERNEL_ARCH_I386_GDT_H
|
# define UKERNEL_ARCH_I386_GDT_H
|
||||||
|
|
||||||
|
# include <sys/mman.h>
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
/* public */
|
/* public */
|
||||||
/* types */
|
/* types */
|
||||||
typedef struct _GDT
|
typedef struct _GDT GDT;
|
||||||
|
|
||||||
|
typedef struct _GDTTable
|
||||||
{
|
{
|
||||||
vaddr_t base;
|
vaddr_t base;
|
||||||
vaddr_t limit;
|
size_t size;
|
||||||
uint8_t type;
|
unsigned int prot;
|
||||||
} GDT;
|
} GDTTable;
|
||||||
|
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
int _arch_setgdt(GDT const * gdt, size_t count);
|
GDT * gdt_init(void);
|
||||||
|
int gdt_init_table(GDTTable const * table, size_t count);
|
||||||
|
|
||||||
|
|
||||||
|
/* useful */
|
||||||
|
int gdt_append(GDT * gdt, vaddr_t base, size_t size, unsigned int prot);
|
||||||
|
|
||||||
|
void gdt_apply(GDT * gdt);
|
||||||
|
|
||||||
#endif /* !UKERNEL_ARCH_I386_GDT_H */
|
#endif /* !UKERNEL_ARCH_I386_GDT_H */
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <elf.h>
|
# include <elf.h>
|
||||||
# include "arch/amd64/gdt.h"
|
|
||||||
# include "arch/i386/gdt.h"
|
|
||||||
# include "drivers/boot/multiboot.h"
|
# include "drivers/boot/multiboot.h"
|
||||||
|
|
||||||
# ifndef MAX
|
# ifndef MAX
|
||||||
|
|
|
@ -27,12 +27,10 @@
|
||||||
/* private */
|
/* private */
|
||||||
/* constants */
|
/* constants */
|
||||||
/* GDT: 4GB flat memory setup */
|
/* GDT: 4GB flat memory setup */
|
||||||
static const GDT _gdt_4gb[4] =
|
static const GDTTable _gdt_4gb[2] =
|
||||||
{
|
{
|
||||||
{ 0x00000000, 0x00000000, 0x00 },
|
{ 0x00000000, 0xffffffff, PROT_READ | PROT_EXEC },
|
||||||
{ 0x00000000, 0xffffffff, 0x9a },
|
{ 0x00000000, 0xffffffff, PROT_READ | PROT_WRITE }
|
||||||
{ 0x00000000, 0xffffffff, 0x92 },
|
|
||||||
{ 0x00000000, 0x00000000, 0x89 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const IDT _idt[] =
|
static const IDT _idt[] =
|
||||||
|
@ -93,7 +91,8 @@ int multiboot(const ukMultibootInfo * mi)
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
if(_arch_setgdt64(_gdt_4gb, sizeof(_gdt_4gb) / sizeof(*_gdt_4gb)) != 0)
|
if(_arch_setgdt64(_gdt_4gb, sizeof(_gdt_4gb) / sizeof(*_gdt_4gb)) != 0)
|
||||||
#else
|
#else
|
||||||
if(_arch_setgdt(_gdt_4gb, sizeof(_gdt_4gb) / sizeof(*_gdt_4gb)) != 0)
|
if(gdt_init_table((const GDTTable *)&_gdt_4gb,
|
||||||
|
sizeof(_gdt_4gb) / sizeof(*_gdt_4gb)) != 0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
puts("Could not setup the GDT");
|
puts("Could not setup the GDT");
|
||||||
|
|
200
src/loader/gdt.c
200
src/loader/gdt.c
|
@ -1,10 +1,11 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
/* Copyright (c) 2018 Pierre Pronchery <khorben@defora.org> */
|
/* Copyright (c) 2018-2025 Pierre Pronchery <khorben@defora.org> */
|
||||||
/* This file is part of DeforaOS uKernel */
|
/* This file is part of DeforaOS uKernel */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
|
# include <limits.h>
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
# include <string.h>
|
# include <string.h>
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
|
@ -12,101 +13,154 @@
|
||||||
# include "arch/i386/gdt.h"
|
# include "arch/i386/gdt.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* constants */
|
||||||
|
# define GDT_ENTRIES_MAX 8192
|
||||||
|
# define GDT_LIMIT_MAX 0x000fffff
|
||||||
|
|
||||||
|
/* access */
|
||||||
|
# define GDT_ACCESS_SET 0x01
|
||||||
|
# define GDT_ACCESS_RW 0x02
|
||||||
|
# define GDT_ACCESS_X 0x08
|
||||||
|
# define GDT_ACCESS_SEGMENT 0x10
|
||||||
|
# define GDT_ACCESS_RING(level) ((level) << 5)
|
||||||
|
# define GDT_ACCESS_PRESENT 0x80
|
||||||
|
|
||||||
|
/* flags */
|
||||||
|
# define GDT_FLAG_LONG_MODE 0x2 /* 64-bit code segment */
|
||||||
|
# define GDT_FLAG_PROTECTED_MODE 0x4 /* 32-bit protected mode
|
||||||
|
code segment */
|
||||||
|
# define GDT_FLAG_PAGE_GRANULARITY 0x8 /* 4 KB page size */
|
||||||
|
|
||||||
|
|
||||||
|
/* types */
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct _GDTEntry
|
||||||
|
{
|
||||||
|
uint8_t limit0;
|
||||||
|
uint8_t limit1;
|
||||||
|
uint8_t base0;
|
||||||
|
uint8_t base1;
|
||||||
|
uint8_t base2;
|
||||||
|
uint8_t access;
|
||||||
|
unsigned int limit2:4;
|
||||||
|
unsigned int flags:4;
|
||||||
|
uint8_t base3;
|
||||||
|
} GDTEntry;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
struct _GDT
|
||||||
|
{
|
||||||
|
GDTEntry entries[GDT_ENTRIES_MAX];
|
||||||
|
size_t entries_cnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
extern void __arch_setgdt(uint8_t * buf, size_t count);
|
extern void __arch_setgdt(GDTEntry const * entries, size_t count);
|
||||||
|
|
||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
static uint8_t _buf[65536];
|
static GDT _gdt;
|
||||||
|
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
/* arch_setgdt */
|
/* gdt_init */
|
||||||
int _arch_setgdt(GDT const * gdt, size_t count)
|
GDT * gdt_init(void)
|
||||||
{
|
{
|
||||||
uint8_t * buf = _buf;
|
memset(&_gdt.entries[0], 0, sizeof(_gdt.entries[0]));
|
||||||
size_t i;
|
_gdt.entries_cnt = 1;
|
||||||
GDT g;
|
return &_gdt;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&_buf, 0, sizeof(_buf));
|
|
||||||
/* check for errors */
|
/* gdt_init_table */
|
||||||
if(count == 0 || count > sizeof(_buf) / sizeof(*gdt))
|
int gdt_init_table(GDTTable const * table, size_t count)
|
||||||
{
|
{
|
||||||
errno = ERANGE;
|
int ret = 0;
|
||||||
return -1;
|
GDT * gdt;
|
||||||
}
|
size_t i;
|
||||||
|
|
||||||
|
gdt = gdt_init();
|
||||||
for(i = 0; i < count; i++)
|
for(i = 0; i < count; i++)
|
||||||
{
|
if((ret = gdt_append(gdt, table[i].base, table[i].size,
|
||||||
g = gdt[i];
|
table[i].prot)) != 0)
|
||||||
buf = &_buf[sizeof(g) * i];
|
return ret;
|
||||||
if(g.limit > 65536)
|
gdt_apply(gdt);
|
||||||
{
|
|
||||||
/* make sure the limit can be encoded */
|
|
||||||
if((g.limit & 0xfff) != 0xfff)
|
|
||||||
return -1;
|
|
||||||
g.limit = g.limit >> 12;
|
|
||||||
buf[6] = 0xc0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
buf[6] = 0x40;
|
|
||||||
//encode the limit
|
|
||||||
buf[0] = g.limit & 0xff;
|
|
||||||
buf[1] = (g.limit >> 8) & 0xff;
|
|
||||||
buf[6] |= (g.limit >> 16) & 0xf;
|
|
||||||
//encode the base
|
|
||||||
buf[2] = g.base & 0xff;
|
|
||||||
buf[3] = (g.base >> 8) & 0xff;
|
|
||||||
buf[4] = (g.base >> 16) & 0xff;
|
|
||||||
buf[7] = (g.base >> 24) & 0xff;
|
|
||||||
//encode the type
|
|
||||||
buf[5] = g.type;
|
|
||||||
}
|
|
||||||
__arch_setgdt(_buf, count);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* arch_setgdt64 */
|
/* useful */
|
||||||
int _arch_setgdt64(GDT const * gdt, size_t count)
|
/* gdt_append */
|
||||||
|
int gdt_append(GDT * gdt, vaddr_t base, size_t size, unsigned int prot)
|
||||||
{
|
{
|
||||||
uint8_t * buf;
|
GDTEntry * entry;
|
||||||
size_t i;
|
uint32_t limit;
|
||||||
GDT g;
|
uint8_t access = GDT_ACCESS_PRESENT
|
||||||
|
| GDT_ACCESS_SEGMENT | GDT_ACCESS_RING(0);
|
||||||
|
uint8_t flags = GDT_FLAG_PROTECTED_MODE;
|
||||||
|
|
||||||
memset(&_buf, 0, sizeof(_buf));
|
|
||||||
/* check for errors */
|
/* check for errors */
|
||||||
if(count == 0 || count > sizeof(_buf) / sizeof(*gdt))
|
if(size == 0)
|
||||||
{
|
{
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for(i = 0; i < count; i++)
|
if(gdt->entries_cnt >= sizeof(gdt->entries) / sizeof(*gdt->entries)
|
||||||
|
|| size > ULONG_MAX
|
||||||
|
|| ULONG_MAX - size < base)
|
||||||
{
|
{
|
||||||
g = gdt[i];
|
errno = ENOMEM;
|
||||||
buf = &_buf[sizeof(g) * i];
|
return -1;
|
||||||
if(g.limit > 65536)
|
|
||||||
{
|
|
||||||
/* make sure the limit can be encoded */
|
|
||||||
if((g.limit & 0xfff) != 0xfff)
|
|
||||||
return -1;
|
|
||||||
g.limit = g.limit >> 12;
|
|
||||||
buf[6] = 0xa0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
buf[6] = 0x20;
|
|
||||||
//encode the limit
|
|
||||||
buf[0] = g.limit & 0xff;
|
|
||||||
buf[1] = (g.limit >> 8) & 0xff;
|
|
||||||
buf[6] |= (g.limit >> 16) & 0xf;
|
|
||||||
//encode the base
|
|
||||||
buf[2] = g.base & 0xff;
|
|
||||||
buf[3] = (g.base >> 8) & 0xff;
|
|
||||||
buf[4] = (g.base >> 16) & 0xff;
|
|
||||||
buf[7] = (g.base >> 24) & 0xff;
|
|
||||||
//encode the type
|
|
||||||
buf[5] = g.type;
|
|
||||||
}
|
}
|
||||||
__arch_setgdt(_buf, count);
|
if(prot != PROT_READ
|
||||||
|
&& prot != (PROT_READ | PROT_WRITE)
|
||||||
|
&& prot != (PROT_READ | PROT_EXEC))
|
||||||
|
{
|
||||||
|
errno = EPERM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
entry = &gdt->entries[gdt->entries_cnt];
|
||||||
|
/* base */
|
||||||
|
entry->base0 = base & 0xff;
|
||||||
|
entry->base1 = (base & 0xff00) >> 8;
|
||||||
|
entry->base2 = (base & 0xff0000) >> 16;
|
||||||
|
entry->base3 = (base & 0xff000000) >> 24;
|
||||||
|
/* limit */
|
||||||
|
if(size - 1 > GDT_LIMIT_MAX)
|
||||||
|
{
|
||||||
|
limit = (size & 0xfff) == 0
|
||||||
|
? (size >> 12)
|
||||||
|
: (((size | 0xfff) + 1) >> 12);
|
||||||
|
limit--;
|
||||||
|
flags |= GDT_FLAG_PAGE_GRANULARITY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
limit = size - 1;
|
||||||
|
entry->limit0 = limit & 0xff;
|
||||||
|
entry->limit1 = (limit & 0xff00) >> 8;
|
||||||
|
entry->limit2 = (limit & 0xf0000) >> 16;
|
||||||
|
/* access */
|
||||||
|
if(prot == (PROT_READ | PROT_EXEC))
|
||||||
|
/* code segment */
|
||||||
|
access |= GDT_ACCESS_RW | GDT_ACCESS_X;
|
||||||
|
else if(prot == (PROT_READ | PROT_WRITE))
|
||||||
|
/* data segment (read/write) */
|
||||||
|
access |= GDT_ACCESS_RW;
|
||||||
|
else if(prot == PROT_READ)
|
||||||
|
/* data segment (read-only) */
|
||||||
|
access |= GDT_ACCESS_SET;
|
||||||
|
entry->access = access;
|
||||||
|
/* flags */
|
||||||
|
entry->flags = flags;
|
||||||
|
gdt->entries_cnt++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* gdt_apply */
|
||||||
|
void gdt_apply(GDT * gdt)
|
||||||
|
{
|
||||||
|
__arch_setgdt(gdt->entries, gdt->entries_cnt);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,12 +29,10 @@
|
||||||
/* private */
|
/* private */
|
||||||
/* constants */
|
/* constants */
|
||||||
/* GDT: 4GB flat memory setup */
|
/* GDT: 4GB flat memory setup */
|
||||||
static const GDT _gdt_4gb[4] =
|
static const GDTTable _gdt_4gb[2] =
|
||||||
{
|
{
|
||||||
{ 0x00000000, 0x00000000, 0x00 },
|
{ 0x00000000, 0xffffffff, PROT_READ | PROT_EXEC },
|
||||||
{ 0x00000000, 0xffffffff, 0x9a },
|
{ 0x00000000, 0xffffffff, PROT_READ | PROT_WRITE }
|
||||||
{ 0x00000000, 0xffffffff, 0x92 },
|
|
||||||
{ 0x00000000, 0x00000000, 0x89 }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,7 +86,8 @@ int multiboot(const ukMultibootInfo * mi)
|
||||||
printf("Booted from %#x\n", mi->boot_device_drive);
|
printf("Booted from %#x\n", mi->boot_device_drive);
|
||||||
|
|
||||||
/* setup the GDT */
|
/* setup the GDT */
|
||||||
if(_arch_setgdt(_gdt_4gb, sizeof(_gdt_4gb) / sizeof(*_gdt_4gb)) != 0)
|
if(gdt_init_table((const GDTTable *)&_gdt_4gb,
|
||||||
|
sizeof(_gdt_4gb) / sizeof(*_gdt_4gb)) != 0)
|
||||||
{
|
{
|
||||||
puts("Could not setup the GDT");
|
puts("Could not setup the GDT");
|
||||||
return 4;
|
return 4;
|
||||||
|
|
|
@ -85,7 +85,7 @@ depends=$(OBJDIR)../lib/libk.a
|
||||||
depends=../drivers/boot/multiboot.h,../../include/kernel/drivers/bus.h,../../include/kernel/drivers/console.h
|
depends=../drivers/boot/multiboot.h,../../include/kernel/drivers/bus.h,../../include/kernel/drivers/console.h
|
||||||
|
|
||||||
[start.S]
|
[start.S]
|
||||||
depends=../arch/i386/intr.S,../arch/i386/loader.S,../arch/i386/multiboot.S
|
depends=../arch/i386/gdt.S,../arch/i386/intr.S,../arch/i386/loader.S,../arch/i386/multiboot.S
|
||||||
|
|
||||||
[syscalls.S]
|
[syscalls.S]
|
||||||
depends=$(OBJDIR)../lib/libc/src/syscalls.o
|
depends=$(OBJDIR)../lib/libc/src/syscalls.o
|
||||||
|
|
69
tests/gdt.c
Normal file
69
tests/gdt.c
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/* $Id$ */
|
||||||
|
/* Copyright (c) 2025 Pierre Pronchery <khorben@defora.org> */
|
||||||
|
/* This file is part of DeforaOS uKernel */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#ifndef vaddr_t
|
||||||
|
# define vaddr_t unsigned long
|
||||||
|
#endif
|
||||||
|
#include "../src/loader/gdt.c"
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
|
/* __arch_setgdt */
|
||||||
|
void __arch_setgdt(GDTEntry const * entries, size_t count)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
GDTEntry const * entry;
|
||||||
|
|
||||||
|
printf("sizeof(*entries) => %zu\n", sizeof(*entries));
|
||||||
|
for(i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
entry = &entries[i];
|
||||||
|
printf("base=0x%02x%02x%02x%02x ",
|
||||||
|
entry->base3, entry->base2,
|
||||||
|
entry->base1, entry->base0);
|
||||||
|
printf("limit=0x%x%02x%02x ",
|
||||||
|
entry->limit2, entry->limit1, entry->limit0);
|
||||||
|
printf("access=0x%02x ", entry->access);
|
||||||
|
printf("flags=0x%0x\n", entry->flags);
|
||||||
|
}
|
||||||
|
printf("count=0x%zx => size=0x%zx\n", count, (count << 3) - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* main */
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
|
GDT * gdt;
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
|
||||||
|
printf("sizeof(GDTEntry) = %zu (expected: %u)\n\n",
|
||||||
|
sizeof(GDTEntry), 8);
|
||||||
|
|
||||||
|
/* flat 4 GB */
|
||||||
|
printf("Flat 4 GB:\n");
|
||||||
|
gdt = gdt_init();
|
||||||
|
gdt_append(gdt, 0x00000000, 0xffffffff, PROT_READ | PROT_EXEC);
|
||||||
|
gdt_append(gdt, 0x00000000, 0xffffffff, PROT_READ | PROT_WRITE);
|
||||||
|
gdt_apply(gdt);
|
||||||
|
|
||||||
|
/* 4 MB code + 4 MB data (read-write) + 4 MB data (read-only) */
|
||||||
|
printf("\n4 MB (rx) + 4 MB (rw) + 4 MB (ro):\n");
|
||||||
|
gdt = gdt_init();
|
||||||
|
gdt_append(gdt, 0x00400000, 0x00400000, PROT_READ | PROT_EXEC);
|
||||||
|
gdt_append(gdt, 0x00800000, 0x00400000, PROT_READ | PROT_WRITE);
|
||||||
|
gdt_append(gdt, 0x00c00000, 0x00400000, PROT_READ);
|
||||||
|
gdt_apply(gdt);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
targets=clint.log,distcheck.log,fixme.log,grub.log
|
targets=clint.log,distcheck.log,fixme.log,gdt,grub.log
|
||||||
|
cppflags_force=-I../src
|
||||||
|
cflags_force=-W -Wall -g -O2
|
||||||
dist=Makefile,clint.sh,distcheck.sh,fixme.sh,grub.sh
|
dist=Makefile,clint.sh,distcheck.sh,fixme.sh,grub.sh
|
||||||
|
|
||||||
#targets
|
#targets
|
||||||
|
@ -20,8 +22,16 @@ script=./fixme.sh
|
||||||
depends=fixme.sh
|
depends=fixme.sh
|
||||||
enabled=0
|
enabled=0
|
||||||
|
|
||||||
|
[gdt]
|
||||||
|
type=binary
|
||||||
|
sources=gdt.c
|
||||||
|
|
||||||
[grub.log]
|
[grub.log]
|
||||||
type=script
|
type=script
|
||||||
script=./grub.sh
|
script=./grub.sh
|
||||||
depends=$(OBJDIR)../src/kernel/uKernel.bin,grub.sh
|
depends=$(OBJDIR)../src/kernel/uKernel.bin,grub.sh
|
||||||
enabled=0
|
enabled=0
|
||||||
|
|
||||||
|
#sources
|
||||||
|
[gdt.c]
|
||||||
|
depends=../src/loader/gdt.c,../src/arch/amd64/gdt.h,../src/arch/i386/gdt.h
|
||||||
|
|
Loading…
Reference in New Issue
Block a user