some test things
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
OBJS = bin/boot.o bin/kernel.o bin/idt.o bin/isr.o bin/screen.o \
|
OBJS = bin/boot.o bin/kernel.o bin/idt.o bin/isr.o bin/screen.o \
|
||||||
bin/utils.o bin/string.o bin/stdio.o bin/disk.o bin/pic.o bin/pit.o \
|
bin/utils.o bin/string.o bin/stdio.o bin/disk.o bin/pic.o bin/pit.o \
|
||||||
bin/keyboard.o bin/paging.o bin/heap.o bin/page_alloc.o bin/page_tables.o \
|
bin/keyboard.o bin/paging.o bin/heap.o bin/page_alloc.o bin/page_tables.o \
|
||||||
bin/fat.o bin/task.o bin/switch.o bin/sys_exit.o
|
bin/fat.o bin/task.o bin/switch.o bin/sys_exit.o bin/gdt.o
|
||||||
|
|
||||||
# Define the compiler and assembler
|
# Define the compiler and assembler
|
||||||
CC = gcc -D__is_katauos
|
CC = gcc -D__is_katauos
|
||||||
@@ -48,7 +48,7 @@ image:
|
|||||||
sudo losetup -D
|
sudo losetup -D
|
||||||
|
|
||||||
test:
|
test:
|
||||||
qemu-system-i386 -drive file=boot.iso,media=disk,format=raw -m 512M -d int
|
qemu-system-i386 -drive file=boot.iso,media=disk,format=raw -m 4096M -d int
|
||||||
#qemu-system-i386 -s -S -kernel myos.bin
|
#qemu-system-i386 -s -S -kernel myos.bin
|
||||||
|
|
||||||
debug:
|
debug:
|
||||||
@@ -120,6 +120,9 @@ bin/task.o: src/tasking/task.c
|
|||||||
bin/sys_exit.o: src/tasking/sys_exit.asm
|
bin/sys_exit.o: src/tasking/sys_exit.asm
|
||||||
$(AS) $(ASFLAGS) $< -o $@
|
$(AS) $(ASFLAGS) $< -o $@
|
||||||
|
|
||||||
|
bin/gdt.o: src/kernel/gdt.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf bin/
|
rm -rf bin/
|
||||||
rm -f $(OUTPUT)
|
rm -f $(OUTPUT)
|
||||||
|
|||||||
@@ -1,17 +1,45 @@
|
|||||||
OUTPUT_FORMAT(elf32-i386)
|
OUTPUT_FORMAT(elf32-i386)
|
||||||
ENTRY(start)
|
ENTRY(start)
|
||||||
|
|
||||||
|
vaddr = 0xC0000000; /* virtual start address */
|
||||||
|
paddr = 0x100000; /* physical address at 1MB */
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x100000;
|
. = 0x100000;
|
||||||
|
|
||||||
|
.setup ALIGN(4096) :
|
||||||
|
{
|
||||||
|
*(.setup)
|
||||||
|
}
|
||||||
|
|
||||||
|
. += vaddr;
|
||||||
|
|
||||||
.text BLOCK(4K) : ALIGN(4K) {
|
.text BLOCK(4K) : ALIGN(4K) {
|
||||||
*(.multiboot)
|
|
||||||
*(.text)
|
*(.text)
|
||||||
}
|
}
|
||||||
.rodata BLOCK(4K) : ALIGN(4K) { *(.rodata) }
|
_etext = .;
|
||||||
.data BLOCK(4K) : ALIGN(4K) { *(.data) }
|
|
||||||
.bss BLOCK(4K) : ALIGN(4K) {
|
.data ALIGN(4096) : AT(ADDR(.data) - vaddr)
|
||||||
*(.COMMON)
|
{
|
||||||
*(.bss)
|
*(.data)
|
||||||
|
*(.rodata*)
|
||||||
}
|
}
|
||||||
kernel_end = .;
|
_edata = .;
|
||||||
|
|
||||||
|
/* uninitialized data */
|
||||||
|
.bss ALIGN(4096) : AT(ADDR(.bss) - vaddr)
|
||||||
|
{
|
||||||
|
*(COMMON*)
|
||||||
|
*(.bss*)
|
||||||
|
}
|
||||||
|
_end = .;
|
||||||
|
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
*(.comment)
|
||||||
|
*(.eh_frame)
|
||||||
|
*(.note*)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+101
-75
@@ -1,96 +1,122 @@
|
|||||||
bits 32
|
bits 32
|
||||||
|
|
||||||
section .multiboot
|
%define CR0_MP 0x00000002 /* bit 01 -> enable monitor coprocessor */
|
||||||
align 4
|
%define CR0_NE 0x00000020 /* bit 05 -> enable native x87 FPU mode */
|
||||||
dd 0x1BADB002
|
%define CR0_WP 0x00010000 /* bit 16 -> enable write protect (for CoW) */
|
||||||
dd 0x00
|
%define CR0_AM 0x00040000 /* bit 18 -> enable alignment checking */
|
||||||
dd - (0x1BADB002+0x00)
|
%define CR0_PG 0x80000000 /* bit 31 -> enable paging */
|
||||||
|
|
||||||
section .data
|
%define PAGE_OFFSET 0xC0000000
|
||||||
|
%define GDT_BASE (0xFFFFFFFF - (PAGE_OFFSET - 1))
|
||||||
|
|
||||||
|
section .setup
|
||||||
align 4
|
align 4
|
||||||
multiboot_info:
|
tmp_gdtr:
|
||||||
dd 0
|
dw ((3 * 8) - 1)
|
||||||
dd 0
|
tmp_gdta:
|
||||||
dd 0
|
dd tmp_gdt
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
dd 0
|
|
||||||
|
|
||||||
global tss
|
|
||||||
global tss_end
|
|
||||||
align 4
|
align 4
|
||||||
tss:
|
tmp_gdt:
|
||||||
dd 0 ; 0-3
|
; null entry
|
||||||
dd stack_top ; 4-7
|
dw 0x0000
|
||||||
dd DATA_SEG ; 8-11
|
dw 0x0000
|
||||||
dd 0 ; 12-15
|
dw 0x0000
|
||||||
dd 0 ; 16-19
|
dw 0x0000
|
||||||
dd 0 ; 20-23
|
|
||||||
dd 0 ; 24-27
|
|
||||||
dd 0 ; 28-31
|
|
||||||
dd 0 ; 32-35
|
|
||||||
dd 0 ; 36-39
|
|
||||||
dd 0 ; 40-43
|
|
||||||
dd 0 ; 44-47
|
|
||||||
dd 0 ; 48-51
|
|
||||||
dd 0 ; 52-55
|
|
||||||
dd 0 ; 56-59
|
|
||||||
dd 0 ; 60-63
|
|
||||||
dd 0 ; 64-67
|
|
||||||
dd 0 ; 68-71
|
|
||||||
dd DATA_SEG ; 72-75
|
|
||||||
dd CODE_SEG ; 76-79
|
|
||||||
dd DATA_SEG ; 80-83
|
|
||||||
dd DATA_SEG ; 84-87
|
|
||||||
dd DATA_SEG ; 88-91
|
|
||||||
dd DATA_SEG ; 92-95
|
|
||||||
dd 0 ; 96-99
|
|
||||||
dw 0 ; 100-101
|
|
||||||
dw 104 ; 102-103
|
|
||||||
tss_end:
|
|
||||||
|
|
||||||
section .bss
|
; /* KERNEL CODE */
|
||||||
stack_bottom:
|
dw 0xFFFF ; /* segment limit 15-00 */
|
||||||
resb 16384
|
dw 0x0000 ; /* base address 15-00 */
|
||||||
stack_top:
|
db 0x00 ; /* base address 23-16 */
|
||||||
|
db 0x9A ; /* P=1 DPL=00 S=1 TYPE=1010 (exec/read) */
|
||||||
|
db 0xCF ; /* G=1 DB=1 0=0 AVL=0 SEGLIM=1111 */
|
||||||
|
db GDT_BASE >> 24 ; /* base address 31-24 */
|
||||||
|
|
||||||
|
; /* KERNEL DATA */
|
||||||
|
dw 0xFFFF ; /* segment limit 15-00 */
|
||||||
|
dw 0x0000 ; /* base address 15-00 */
|
||||||
|
db 0x00 ; /* base address 23-16 */
|
||||||
|
db 0x92 ; /* P=1 DPL=00 S=1 TYPE=0010 (read/write) */
|
||||||
|
db 0xCF ; /* G=1 DB=1 0=0 AVL=0 SEGLIM=1111 */
|
||||||
|
db GDT_BASE >> 24 ; /* base address 31-24 */
|
||||||
|
|
||||||
section .gdt
|
align 4
|
||||||
%include "src/gdt.asm"
|
multiboot_header:
|
||||||
|
dd 0x1BADB002
|
||||||
|
dd 0x00
|
||||||
|
dd - (0x1BADB002 + 0x00)
|
||||||
|
|
||||||
section .text
|
dd 0
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
|
||||||
|
; section .text
|
||||||
global start:function (start.end - start)
|
global start:function (start.end - start)
|
||||||
extern kmain ; this function is gonna be located in our c code(kernel.c)
|
extern kmain ; this function is gonna be located in our c code(kernel.c)
|
||||||
|
extern get_last_boot_addr
|
||||||
|
extern gdt_init
|
||||||
|
extern bss_init
|
||||||
|
extern setup_tmp_pgdir
|
||||||
|
|
||||||
|
align 4
|
||||||
start:
|
start:
|
||||||
mov esp, stack_top
|
; mov esp, stack_top
|
||||||
cli
|
cli
|
||||||
push ebx ; Сохраняем оригинальный ebx (указатель Multiboot)
|
; push ebx ; Сохраняем оригинальный ebx (указатель Multiboot)
|
||||||
|
|
||||||
lgdt [gdt]
|
;lgdt [gdt]
|
||||||
|
lgdt [tmp_gdtr]
|
||||||
|
|
||||||
; Заполняем адрес TSS в дескрипторе GDT
|
mov cx, 0x10 ; data segment
|
||||||
mov eax, tss ; Получаем 32-битный адрес tss
|
mov ds, cx
|
||||||
mov ebx, gdt_tss ; Адрес дескриптора TSS в GDT
|
mov es, cx
|
||||||
mov [ebx + 2], ax ; Нижние 16 бит адреса TSS
|
mov fs, cx
|
||||||
shr eax, 16 ; Сдвигаем для доступа к старшим битам
|
mov gs, cx
|
||||||
mov [ebx + 4], al ; Средние 8 бит адреса TSS
|
mov ss, cx
|
||||||
mov [ebx + 7], ah ; Верхние 8 бит адреса TSS
|
jmp 0x8:.huita ; 0x8 - code segment
|
||||||
|
|
||||||
mov ax, DATA_SEG
|
.text
|
||||||
mov ds, ax
|
|
||||||
mov es, ax
|
|
||||||
mov fs, ax
|
|
||||||
mov gs, ax
|
|
||||||
mov ss, ax
|
|
||||||
jmp CODE_SEG:.huita
|
|
||||||
|
|
||||||
|
align 4
|
||||||
.huita:
|
.huita:
|
||||||
mov ax, TSS_SEG
|
mov esp, PAGE_OFFSET + 0x10000 ; default stack address
|
||||||
ltr ax
|
push 0
|
||||||
pop ebx ; Восстанавливаем оригинальный ebx
|
popf ; reset EFLAGS
|
||||||
push ebx ; Передаем его в kmain
|
|
||||||
call kmain
|
push ebx ; save Multiboot info structure
|
||||||
hlt
|
push eax ; save Multiboot magic value
|
||||||
|
|
||||||
|
call setup_tmp_pgdir
|
||||||
|
mov cr3, eax
|
||||||
|
|
||||||
|
mov eax, cr0
|
||||||
|
and eax, 0x00000011 ; disable all, preserve ET & PE (GRUB)
|
||||||
|
or eax, 0x80000000 ; CR0_PG ; enable PG
|
||||||
|
or eax, 0x40000 ; CR0_AM ; enable AM
|
||||||
|
or eax, 0x10000 ; CR0_WP ; enable WP
|
||||||
|
or eax, 0x20 ; CR0_NE ; enable NE
|
||||||
|
or eax, 0x2 ; CR0_MP ; enable MP
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
|
call bss_init ; initialize BSS segment
|
||||||
|
call gdt_init ; setup and load definitive GDT
|
||||||
|
call get_last_boot_addr
|
||||||
|
|
||||||
|
pop ecx ; restore Multiboot magic value
|
||||||
|
pop ebx ; restore Multiboot info structure
|
||||||
|
|
||||||
|
push eax ; save last boot address
|
||||||
|
push ebx ; save Multiboot info structure
|
||||||
|
push ecx ; save Multiboot magic value
|
||||||
|
|
||||||
|
pop ebx ; Восстанавливаем оригинальный ebx
|
||||||
|
push ebx ; Передаем его в kmain
|
||||||
|
call kmain
|
||||||
|
hlt
|
||||||
.end:
|
.end:
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
//#include "../include/gdt.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "../include/string.h"
|
||||||
|
|
||||||
|
struct desc_r {
|
||||||
|
uint16_t limit;
|
||||||
|
uint32_t base_addr;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct seg_desc {
|
||||||
|
unsigned sd_lolimit : 16; /* segment limit 0-15 bits */
|
||||||
|
unsigned sd_lobase : 24; /* base address 0-23 bits */
|
||||||
|
unsigned sd_loflags : 8; /* flags (P, DPL, S and TYPE) */
|
||||||
|
unsigned sd_hilimit : 4; /* segment limit 16-19 bits */
|
||||||
|
unsigned sd_hiflags : 4; /* flags (G, DB, 0 and AVL) */
|
||||||
|
unsigned sd_hibase : 8; /* base address 24-31 bits */
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct gate_desc {
|
||||||
|
unsigned gd_looffset: 16; /* offset 0-15 bits */
|
||||||
|
unsigned gd_selector: 16; /* segment selector */
|
||||||
|
unsigned gd_flags : 16; /* flags (P, DPL, TYPE, 0 and NULL) */
|
||||||
|
unsigned gd_hioffset: 16; /* offset 16-31 bits */
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
extern char _end[], _edata[];
|
||||||
|
|
||||||
|
#define KERNEL_CS 0x08 /* kernel code segment */
|
||||||
|
#define KERNEL_DS 0x10 /* kernel data segment */
|
||||||
|
#define USER_CS 0x18 /* user code segment */
|
||||||
|
#define USER_DS 0x20 /* user data segment */
|
||||||
|
#define TSS 0x28 /* TSS segment */
|
||||||
|
|
||||||
|
|
||||||
|
void load_gdt(uint32_t gdt_ptr) {
|
||||||
|
asm volatile (
|
||||||
|
"lgdt (%0)\n\t"
|
||||||
|
"movw %1, %%ax\n\t"
|
||||||
|
"movw %%ax, %%ds\n\t"
|
||||||
|
"movw %%ax, %%es\n\t"
|
||||||
|
"movw %%ax, %%fs\n\t"
|
||||||
|
"movw %%ax, %%gs\n\t"
|
||||||
|
"movw %%ax, %%ss\n\t"
|
||||||
|
"ljmp %2, $1f\n\t"
|
||||||
|
"1:\n\t"
|
||||||
|
:
|
||||||
|
: "r" (gdt_ptr), "i" (KERNEL_DS), "i" (KERNEL_CS)
|
||||||
|
: "eax"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
#define PAGE_SHIFT 0x0C
|
||||||
|
|
||||||
|
#define PAGE_MASK ~(PAGE_SIZE - 1) /* 0xFFFFF000 */
|
||||||
|
#define PAGE_ALIGN(addr) (((addr) + (PAGE_SIZE - 1)) & PAGE_MASK)
|
||||||
|
|
||||||
|
#define KERNEL_BSS_SIZE ((int)_end - (int)_edata)
|
||||||
|
|
||||||
|
#define NR_GDT_ENTRIES 6 /* entries in GDT descriptor */
|
||||||
|
#define NR_IDT_ENTRIES 256 /* entries in IDT descriptor */
|
||||||
|
|
||||||
|
/* low flags of Segment Descriptors */
|
||||||
|
#define SD_CODE 0x0A /* CODE Exec/Read */
|
||||||
|
#define SD_DATA 0x02 /* DATA Read/Write */
|
||||||
|
|
||||||
|
#define SD_32INTRGATE 0x0E /* 32-bit Interrupt Gate (0D110) */
|
||||||
|
#define SD_32TRAPGATE 0x0F /* 32-bit Trap Gate (0D111) */
|
||||||
|
|
||||||
|
#define SD_CD 0x10 /* 0 = system / 1 = code/data */
|
||||||
|
#define SD_DPL0 0x00 /* priority level 0 (kernel) */
|
||||||
|
#define SD_DPL3 0x60 /* priority level 3 (user) */
|
||||||
|
#define SD_PRESENT 0x80 /* segment present or valid */
|
||||||
|
|
||||||
|
/* high flags Segment Descriptors */
|
||||||
|
#define SD_OPSIZE32 0x04 /* 32-bit code and data segments */
|
||||||
|
#define SD_PAGE4KB 0x08 /* page granularity (4KB) */
|
||||||
|
|
||||||
|
/* low flags of the TSS Descriptors */
|
||||||
|
#define SD_TSSPRESENT 0x89 /* TSS present and not busy flag */
|
||||||
|
|
||||||
|
/* EFLAGS */
|
||||||
|
#define EF_IOPL 12 /* IOPL bit */
|
||||||
|
|
||||||
|
#define KERNEL_CS 0x08 /* kernel code segment */
|
||||||
|
#define KERNEL_DS 0x10 /* kernel data segment */
|
||||||
|
#define USER_CS 0x18 /* user code segment */
|
||||||
|
#define USER_DS 0x20 /* user data segment */
|
||||||
|
#define TSS 0x28 /* TSS segment */
|
||||||
|
|
||||||
|
|
||||||
|
struct tss_entry_struct {
|
||||||
|
uint32_t prev_tss; // The previous TSS - with hardware task switching these form a kind of backward linked list.
|
||||||
|
uint32_t esp0; // The stack pointer to load when changing to kernel mode.
|
||||||
|
uint32_t ss0; // The stack segment to load when changing to kernel mode.
|
||||||
|
// Everything below here is unused.
|
||||||
|
uint32_t esp1; // esp and ss 1 and 2 would be used when switching to rings 1 or 2.
|
||||||
|
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 ldt;
|
||||||
|
uint16_t trap;
|
||||||
|
uint16_t iomap_base;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
void bss_init()
|
||||||
|
{
|
||||||
|
memset((void *)((int)_edata), 0, KERNEL_BSS_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_last_boot_addr()
|
||||||
|
{
|
||||||
|
return ((unsigned int)_end & PAGE_MASK) + PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct seg_desc gdt[NR_GDT_ENTRIES];
|
||||||
|
|
||||||
|
struct desc_r gdtr = {
|
||||||
|
sizeof(gdt) - 1,
|
||||||
|
(unsigned int)&gdt
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gdt_set_entry(int num, unsigned int base_addr, unsigned int limit, char loflags, char hiflags)
|
||||||
|
{
|
||||||
|
num /= sizeof(struct seg_desc);
|
||||||
|
gdt[num].sd_lolimit = limit & 0xFFFF;
|
||||||
|
gdt[num].sd_lobase = base_addr & 0xFFFFFF;
|
||||||
|
gdt[num].sd_loflags = loflags;
|
||||||
|
gdt[num].sd_hilimit = (limit >> 16) & 0x0F;
|
||||||
|
gdt[num].sd_hiflags = hiflags;
|
||||||
|
gdt[num].sd_hibase = (base_addr >> 24) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gdt_init(void)
|
||||||
|
{
|
||||||
|
unsigned char loflags;
|
||||||
|
|
||||||
|
gdt_set_entry(0, 0, 0, 0, 0); /* null descriptor */
|
||||||
|
|
||||||
|
loflags = SD_CODE | SD_CD | SD_DPL0 | SD_PRESENT;
|
||||||
|
gdt_set_entry(KERNEL_CS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB);
|
||||||
|
loflags = SD_DATA | SD_CD | SD_DPL0 | SD_PRESENT;
|
||||||
|
gdt_set_entry(KERNEL_DS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB);
|
||||||
|
|
||||||
|
loflags = SD_CODE | SD_CD | SD_DPL3 | SD_PRESENT;
|
||||||
|
gdt_set_entry(USER_CS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB);
|
||||||
|
loflags = SD_DATA | SD_CD | SD_DPL3 | SD_PRESENT;
|
||||||
|
gdt_set_entry(USER_DS, 0, 0xFFFFFFFF, loflags, SD_OPSIZE32 | SD_PAGE4KB);
|
||||||
|
|
||||||
|
loflags = SD_TSSPRESENT;
|
||||||
|
gdt_set_entry(TSS, 0, sizeof(struct tss_entry_struct), loflags, SD_OPSIZE32);
|
||||||
|
|
||||||
|
load_gdt((unsigned int)&gdtr);
|
||||||
|
}
|
||||||
@@ -1,10 +1,77 @@
|
|||||||
#include "../include/paging.h"
|
#include "../include/paging.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "../include/multiboot.h"
|
||||||
|
#include "../include/string.h"
|
||||||
|
|
||||||
uint32_t kernel_page_directory[1024] __attribute__((aligned(4096)));
|
uint32_t kernel_page_directory[1024] __attribute__((aligned(4096)));
|
||||||
uint32_t kernel_page_table[1024] __attribute__((aligned(4096)));
|
uint32_t kernel_page_table[1024] __attribute__((aligned(4096)));
|
||||||
uint32_t user_page_table[1024] __attribute__((aligned(4096)));
|
uint32_t user_page_table[1024] __attribute__((aligned(4096)));
|
||||||
|
|
||||||
|
#define PAGE_OFFSET 0xC0000000
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
|
||||||
|
#define PAGE_PRESENT 0x1
|
||||||
|
#define PAGE_RW 0x002 /* Read/Write */
|
||||||
|
#define PAGE_USER 0x004 /* User */
|
||||||
|
#define PAGE_NOALLOC 0x200 /* No Page Allocated (OS managed) */
|
||||||
|
|
||||||
|
#define PAGE_SHIFT 0x0C
|
||||||
|
#define PAGE_MASK ~(PAGE_SIZE - 1) /* 0xFFFFF000 */
|
||||||
|
|
||||||
|
#define GDT_BASE (0xFFFFFFFF - (PAGE_OFFSET - 1))
|
||||||
|
|
||||||
|
#define GET_PGDIR(address) ((unsigned int)((address) >> 22) & 0x3FF)
|
||||||
|
#define GET_PGTBL(address) ((unsigned int)((address) >> 12) & 0x3FF)
|
||||||
|
|
||||||
|
#define PAGE_ALIGN(addr) (((addr) + (PAGE_SIZE - 1)) & PAGE_MASK)
|
||||||
|
|
||||||
|
unsigned int *kpage_dir;
|
||||||
|
|
||||||
|
unsigned int setup_tmp_pgdir(unsigned int magic, unsigned int info)
|
||||||
|
{
|
||||||
|
int n, pd;
|
||||||
|
unsigned int addr, memksize;
|
||||||
|
unsigned int *pgtbl;
|
||||||
|
struct multiboot_info *mbi;
|
||||||
|
|
||||||
|
if(magic != MULTIBOOT_BOOTLOADER_MAGIC) {
|
||||||
|
/* 4MB of memory assumed */
|
||||||
|
memksize = 4096;
|
||||||
|
} else {
|
||||||
|
mbi = (struct multiboot_info *)(PAGE_OFFSET + info);
|
||||||
|
if(!(mbi->flags & MULTIBOOT_INFO_MEMORY)) {
|
||||||
|
/* 4MB of memory assumed */
|
||||||
|
memksize = 4096;
|
||||||
|
} else {
|
||||||
|
/* we need to add the first 1MB to memksize */
|
||||||
|
memksize = (unsigned int)mbi->mem_upper + 1024;
|
||||||
|
/* CONFIG_VM_SPLIT22 marks the maximum physical memory supported */
|
||||||
|
if(memksize > ((0xFFFFFFFF - PAGE_OFFSET) / 1024)) {
|
||||||
|
memksize = (0xFFFFFFFF - PAGE_OFFSET) / 1024;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = PAGE_OFFSET + (memksize * 1024) - memksize;
|
||||||
|
addr = PAGE_ALIGN(addr);
|
||||||
|
|
||||||
|
kpage_dir = (unsigned int *)addr;
|
||||||
|
memset(kpage_dir, 0, PAGE_SIZE);
|
||||||
|
|
||||||
|
addr += PAGE_SIZE;
|
||||||
|
pgtbl = (unsigned int *)addr;
|
||||||
|
memset(pgtbl, 0, memksize);
|
||||||
|
|
||||||
|
for(n = 0; n < memksize / sizeof(unsigned int); n++) {
|
||||||
|
pgtbl[n] = (n << PAGE_SHIFT) | PAGE_PRESENT | PAGE_RW;
|
||||||
|
if(!(n % 1024)) {
|
||||||
|
pd = n / 1024;
|
||||||
|
kpage_dir[pd] = (unsigned int)(addr + (PAGE_SIZE * pd) + GDT_BASE) | PAGE_PRESENT | PAGE_RW;
|
||||||
|
kpage_dir[GET_PGDIR(PAGE_OFFSET) + pd] = (unsigned int)(addr + (PAGE_SIZE * pd) + GDT_BASE) | PAGE_PRESENT | PAGE_RW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (unsigned int)kpage_dir - PAGE_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
void enablePaging() {
|
void enablePaging() {
|
||||||
asm volatile (
|
asm volatile (
|
||||||
|
|||||||
Reference in New Issue
Block a user