Merge branch 'master' into shell
This commit is contained in:
commit
5fba767e64
29
Makefile
29
Makefile
|
@ -22,7 +22,7 @@
|
|||
# along with OS/K. If not, see <https://www.gnu.org/licenses/>. #
|
||||
#=----------------------------------------------------------------------------=#
|
||||
|
||||
.PHONY: all test testnokvm testnosnd test32 debug gdb installonimage dust clean OS/K run
|
||||
.PHONY: all test testnokvm testnosnd test32 debug gdb ddd gdbnokvm dddnokvm installonimage dust clean OS/K run
|
||||
.DELETE_ON_ERROR: $(BINDIR)/kaleid
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
|
@ -41,7 +41,7 @@ CCNAME=x86_64-elf-gcc
|
|||
ASMFLAGS=-f elf64
|
||||
LDFLAGS=-melf_x86_64
|
||||
COPTIM=-O2
|
||||
CWARNS=-Wall -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough -Werror=implicit-function-declaration -Werror=return-type
|
||||
CWARNS=-Wall -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough -Werror=implicit-function-declaration -Werror=return-type #-Wpadded
|
||||
CINCLUDES=-Iinclude
|
||||
CFLAGS1=-nostdlib -ffreestanding -mcmodel=large -std=gnu11 -fstack-protector-all -fdump-rtl-expand
|
||||
CFLAGS2= -c -mno-red-zone -mno-mmx -mno-sse -mno-sse2
|
||||
|
@ -292,7 +292,7 @@ test32: all installonimage
|
|||
cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log &
|
||||
|
||||
gdb: all installonimage
|
||||
@setsid qemu-system-x86_64 -m $(ram) -soundhw pcspk -rtc base=localtime \
|
||||
@setsid qemu-system-x86_64 -m $(ram) -enable-kvm -rtc base=localtime \
|
||||
-hda $(installdisk) -no-reboot -no-shutdown -d \
|
||||
cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log &
|
||||
@gdb \
|
||||
|
@ -302,9 +302,26 @@ gdb: all installonimage
|
|||
-ex "break BtStartKern" \
|
||||
|
||||
ddd: all installonimage
|
||||
@setsid qemu-system-x86_64 -m $(ram) -hda $(installdisk) -no-reboot -soundhw pcspk \
|
||||
-no-shutdown -d cpu_reset,guest_errors,pcall,int -s 2> $(BUILDDIR)/qemu.log &
|
||||
@ddd
|
||||
@setsid qemu-system-x86_64 -m $(ram) -enable-kvm -rtc base=localtime \
|
||||
-hda $(installdisk) -no-reboot -no-shutdown -d \
|
||||
cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log &
|
||||
@ddd -n
|
||||
|
||||
gdbnokvm: all installonimage
|
||||
@setsid qemu-system-x86_64 -m $(ram) -rtc base=localtime \
|
||||
-hda $(installdisk) -no-reboot -no-shutdown -d \
|
||||
cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log &
|
||||
@gdb \
|
||||
-ex "set arch i386:x86-64:intel" \
|
||||
-ex "target remote localhost:1234" \
|
||||
-ex "symbol-file $(BINDIR)/kaleid" \
|
||||
-ex "break BtStartKern" \
|
||||
|
||||
dddnokvm: all installonimage
|
||||
@setsid qemu-system-x86_64 -m $(ram) -rtc base=localtime \
|
||||
-hda $(installdisk) -no-reboot -no-shutdown -d \
|
||||
cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log &
|
||||
@ddd -n
|
||||
|
||||
|
||||
## HD IMAGE RELATED ---------------------------------------------------------- #
|
||||
|
|
|
@ -42,3 +42,8 @@ To compile and install, simply use at the root of this project, with XXX the ima
|
|||
make install installdisk=XXX
|
||||
```
|
||||
|
||||
#### Screenshot
|
||||
![OS/K Started](https://www.os-k.eu/images/screen3.png)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -38,13 +38,16 @@ SECTIONS {
|
|||
|
||||
.text ALIGN (0x1000) :
|
||||
{
|
||||
_text = .;
|
||||
*(.text)
|
||||
_text_end = .;
|
||||
}
|
||||
|
||||
.data ALIGN (0x1000) :
|
||||
{
|
||||
_data = .;
|
||||
*(.data)
|
||||
_data_end = .;
|
||||
}
|
||||
|
||||
.eh_frame ALIGN (0x1000) :
|
||||
|
@ -55,7 +58,9 @@ SECTIONS {
|
|||
|
||||
.rodata ALIGN (0x1000) :
|
||||
{
|
||||
_rodata = .;
|
||||
*(.rodata)
|
||||
_rodata_end = .;
|
||||
}
|
||||
|
||||
.bss ALIGN (0x1000) :
|
||||
|
@ -71,4 +76,3 @@ SECTIONS {
|
|||
kernelEnd = .;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -136,6 +136,11 @@ static inline ulong KeReadStsc(void) {
|
|||
return ((ulong)edx << 32) + eax;
|
||||
}
|
||||
|
||||
static inline void KeFlushTlbSingle(ulong addr)
|
||||
{
|
||||
asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
|
||||
}
|
||||
|
||||
//------------------------------------------//
|
||||
// Misc. I/O //
|
||||
//------------------------------------------//
|
||||
|
|
|
@ -44,24 +44,24 @@ struct BootInfo_t
|
|||
{
|
||||
// The Bootloader infos
|
||||
struct {
|
||||
ushort valid;
|
||||
uint grubFlags; //flags
|
||||
uint modulesCount; //mods_count
|
||||
void *modulesAddr; //mods_addr
|
||||
char *grubName; //boot_loader_name
|
||||
void *kernelAddr;
|
||||
void *codeSegment;
|
||||
void *kernelEndAddr;
|
||||
void *stackEndAddr; // stack begins 16B after kernelEndAddr
|
||||
uint grubFlags; //flags
|
||||
uint modulesCount; //mods_count
|
||||
ushort valid;
|
||||
char *grubName; //boot_loader_name
|
||||
} btldr;
|
||||
|
||||
// Informations about drives
|
||||
struct {
|
||||
ushort drvValid;
|
||||
ushort bufferValid;
|
||||
void *bufferAddr; //drives_addr
|
||||
uint bootDrv; //boot_device
|
||||
uint bufferLength; //drives_length
|
||||
void *bufferAddr; //drives_addr
|
||||
ushort drvValid;
|
||||
ushort bufferValid;
|
||||
} drives;
|
||||
|
||||
// Informations about memory
|
||||
|
@ -74,36 +74,36 @@ struct BootInfo_t
|
|||
uint upMemory; //mem_upper
|
||||
|
||||
//GRUB provided memory map
|
||||
uint mapLength; //mmap_length
|
||||
void *mapAddr; //mmap_addr
|
||||
uint mapLength; //mmap_length
|
||||
|
||||
uint ramSize; //The ram (init by map.c)
|
||||
} memory;
|
||||
|
||||
// Informations about the video drive
|
||||
struct {
|
||||
ushort vbeValid;
|
||||
ushort fbuValid;
|
||||
void *vbeControl; //vbe_control_info
|
||||
void *vbeModeInfo; //vbe_mode_info
|
||||
ushort vbeMode; //vbe_mode
|
||||
ushort vbeInterfaceSeg; //vbe_interface_seg
|
||||
ushort vbeInterfaceOff; //vbe_interface_off
|
||||
ushort vbeInterfaceLen; //vbe_interface_len
|
||||
void *framebufferAddr; //framebuffer_addr
|
||||
uint framebufferPitch; //framebuffer_pitch
|
||||
uint framebufferWidth; //framebuffer_width
|
||||
uint framebufferHeight; //framebuffer_height
|
||||
ushort vbeValid;
|
||||
ushort fbuValid;
|
||||
ushort vbeMode; //vbe_mode
|
||||
ushort vbeInterfaceSeg; //vbe_interface_seg
|
||||
ushort vbeInterfaceOff; //vbe_interface_off
|
||||
ushort vbeInterfaceLen; //vbe_interface_len
|
||||
uchar framebufferBpp; //framebuffer_bpp
|
||||
uchar framebufferType; //framebuffer_type
|
||||
} video;
|
||||
|
||||
// Informations about the microcode firmware (BIOS/EFI)
|
||||
struct {
|
||||
ushort apmValid;
|
||||
ushort romValid;
|
||||
uint apmTable; //apm_table
|
||||
uint romTable; //config_table
|
||||
ushort apmValid;
|
||||
ushort romValid;
|
||||
} firmware;
|
||||
};
|
||||
|
||||
|
|
|
@ -31,13 +31,19 @@
|
|||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
void IoStartSpeaker(int);
|
||||
void IoStartSpeaker(ulong);
|
||||
void IoDoBeep(void);
|
||||
void IoDoTone(uint tone, uint time);
|
||||
void IoDoTone(ulong tone, ulong time);
|
||||
void IoDoBeepNoIdt(void);
|
||||
|
||||
void IoDoStarWars(void);
|
||||
|
||||
struct Note
|
||||
{
|
||||
ulong tone;
|
||||
ulong time;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#endif
|
||||
|
|
|
@ -59,6 +59,7 @@ extern const char *RtlColorNames[VGA_COLOR_WHITE+1];
|
|||
#define RtlCharToColor(c) ((c) - 130)
|
||||
|
||||
uint IoGetScroll(void);
|
||||
void IoSetScroll(uint);
|
||||
void IoScrollUp(void);
|
||||
void IoScrollDown(void);
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#define BADRAM_ZONE 5 // Invalid zone because material problem...
|
||||
#define MAX_ENTRIES 2048 // Max number of memory map entries
|
||||
#define KPAGESIZE (4 * KB)
|
||||
#define UPAGESIZE (2 * MB)
|
||||
#define UPAGESIZE (4 * KB)
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
@ -108,7 +108,7 @@ struct Tss_t
|
|||
ushort iomap_base;
|
||||
uchar iomap[IOMAP_SIZE];
|
||||
|
||||
} __attribute__ ((packed));
|
||||
} __attribute__ ((packed)) __attribute__((aligned(8)));
|
||||
|
||||
|
||||
|
||||
|
@ -158,10 +158,11 @@ extern void MmLoadGdt(GdtPtr_t *gdtPtr, ushort tssOffset);
|
|||
//
|
||||
extern void MmStoreGdt(void);
|
||||
|
||||
//
|
||||
// Paging misc
|
||||
//
|
||||
void MmInitPaging(void);
|
||||
|
||||
void MmReloadPaging(void);
|
||||
|
||||
void MmActivatePageHandler(void);
|
||||
|
||||
//
|
||||
|
@ -170,24 +171,39 @@ void MmActivatePageHandler(void);
|
|||
void *MmGetStackGuards(char rank);
|
||||
|
||||
//
|
||||
// Translate a virtual address into physical address
|
||||
// Translate a virtual address into physical address and the opposite
|
||||
//
|
||||
void *MmTranslateKPageToAddr(void *rank);
|
||||
void *MmTransVirtToPhyAddr(void*);
|
||||
void *MmTransPhyToVirtAddr(void* virtualAddr);
|
||||
|
||||
// Page directory pointer offset
|
||||
typedef ulong pdpe_t;
|
||||
//
|
||||
// Set flags to a page
|
||||
//
|
||||
void MmSetPage(void* virtualAddr, ulong flags);
|
||||
void MmUnSetPage(void* virtualAddr, ulong flags);
|
||||
|
||||
// Page directory offset
|
||||
typedef ulong pde_t;
|
||||
//
|
||||
// Map a page
|
||||
//
|
||||
void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags);
|
||||
void MmUnmapPage(void* virtualAddr);
|
||||
|
||||
// Page table entry
|
||||
typedef ulong pte_t;
|
||||
|
||||
// Page directory offset
|
||||
typedef pte_t* pde_t;
|
||||
|
||||
// Page directory pointer offset
|
||||
typedef pde_t* pdpe_t;
|
||||
|
||||
// Page directory L4 pointer offset
|
||||
typedef pdpe_t* pml4_t;
|
||||
|
||||
// paging.asm
|
||||
void MmLoadPML4(void *);
|
||||
void MmEnableWriteProtect(void);
|
||||
void MmDisableWriteProtect(void);
|
||||
void *MmGetStackGuards(char rank);
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
|
|
@ -62,21 +62,21 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
|
|||
|
||||
// Memory
|
||||
MmInitMemoryMap();
|
||||
MmInitPaging();
|
||||
MmInitHeap();
|
||||
MmInitGdt();
|
||||
|
||||
// Basics for interrupts
|
||||
// Interrupts
|
||||
KeSetupIDT();
|
||||
KeEnableIRQs();
|
||||
|
||||
// Memory (2)
|
||||
MmInitHeap();
|
||||
MmInitPaging();
|
||||
|
||||
// Interrupt handlers
|
||||
MmActivatePageHandler();
|
||||
KeEnableRTC();
|
||||
KeEnablePIT();
|
||||
KeGetCpuInfos();
|
||||
|
||||
// Memory (2)
|
||||
MmInitGdt();
|
||||
MmActivatePageHandler();
|
||||
|
||||
// Drivers
|
||||
IoEnableKeyb();
|
||||
|
||||
// Command line (kernel mode)
|
||||
|
|
|
@ -28,10 +28,21 @@
|
|||
|
||||
extern bool KeIdtIsInitialized;
|
||||
|
||||
void IoStartSpeaker(int freq)
|
||||
struct Note score[40] = { {440, 200}, {110, 200}, {440, 200}, {110, 200},
|
||||
{440, 200}, {110, 200}, {349, 140}, {87, 100},
|
||||
{523, 60}, {87, 100}, {440, 200}, {110, 200},
|
||||
{349, 140}, {87, 100}, {523, 60}, {87, 100},
|
||||
{440, 200}, {110, 200}, {440, 200}, {110, 200},
|
||||
{659, 200}, {110, 200}, {659, 200}, {110, 200},
|
||||
{659, 200}, {87, 200}, {698, 140}, {87, 100},
|
||||
{523, 60}, {87, 100}, {415, 200}, {87, 200},
|
||||
{349, 140}, {87, 100}, {523, 60}, {87, 100},
|
||||
{440, 200}, {110, 200}, {110, 200}, {110, 200} };
|
||||
|
||||
void IoStartSpeaker(ulong freq)
|
||||
{
|
||||
uchar temp;
|
||||
uint pitf = 1193180 / freq;
|
||||
ulong pitf = 1193180 / freq;
|
||||
|
||||
ulong flags = KePauseIRQs();
|
||||
IoWriteByteOnPort(0x43, 0xB6);
|
||||
|
@ -52,13 +63,13 @@ static inline void IoQuietSpeaker(void)
|
|||
KeRestoreIRQs(flags);
|
||||
}
|
||||
|
||||
void IoDoTone(uint tone, uint time)
|
||||
void IoDoTone(ulong tone, ulong time)
|
||||
{
|
||||
IoStartSpeaker(tone);
|
||||
KeSleep(time);
|
||||
}
|
||||
|
||||
static void IoDoToneNoIdt(uint tone, uint time)
|
||||
static void IoDoToneNoIdt(ulong tone, ulong time)
|
||||
{
|
||||
extern void temporize(void);
|
||||
IoStartSpeaker(tone);
|
||||
|
@ -81,29 +92,8 @@ void IoDoBeepNoIdt(void)
|
|||
|
||||
void IoDoStarWars(void)
|
||||
{
|
||||
struct Note {
|
||||
uint tone;
|
||||
uint time;
|
||||
};
|
||||
|
||||
struct Note score[] = { {440, 200}, {110, 200}, {440, 200}, {110, 200},
|
||||
{440, 200}, {110, 200}, {349, 140}, {87, 100},
|
||||
{523, 60}, {87, 100}, {440, 200}, {110, 200},
|
||||
{349, 140}, {87, 100}, {523, 60}, {87, 100},
|
||||
{440, 200}, {110, 200}, {440, 200}, {110, 200},
|
||||
{659, 200}, {110, 200}, {659, 200}, {110, 200},
|
||||
{659, 200}, {87, 200}, {698, 140}, {87, 100},
|
||||
{523, 60}, {87, 100}, {415, 200}, {87, 200},
|
||||
{349, 140}, {87, 100}, {523, 60}, {87, 100},
|
||||
{440, 200}, {110, 200}, {110, 200}, {110, 200}
|
||||
};
|
||||
|
||||
//bprintf(BStdOut, "\n");
|
||||
|
||||
for (uint i = 0; i < sizeof(score)/sizeof(struct Note); i++) {
|
||||
for (uint i = 0; i < 40; i++) {
|
||||
IoDoTone(score[i].tone, score[i].time);
|
||||
//bprintf(BStdOut, "%d ", i);
|
||||
//BStdOut->flusher(BStdOut);
|
||||
}
|
||||
IoQuietSpeaker();
|
||||
|
||||
|
|
|
@ -113,6 +113,11 @@ uint IoGetScroll(void)
|
|||
return bscroll;
|
||||
}
|
||||
|
||||
void IoSetScroll(uint value)
|
||||
{
|
||||
bscroll = 0;
|
||||
}
|
||||
|
||||
void IoScrollDown(void)
|
||||
{
|
||||
BLockBuf(BStdOut);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <init/boot.h>
|
||||
#include <ke/idt.h>
|
||||
#include <io/vga.h>
|
||||
#include <mm/mm.h>
|
||||
#include <io/spkr.h>
|
||||
|
||||
IdtEntry_t idt[256] = { 0 };
|
||||
|
@ -120,56 +119,56 @@ void KeSetupIDT(void)
|
|||
_KeIdtPtr.base = &idt;
|
||||
|
||||
// Set IDT Exception Gates
|
||||
KeSetIDTGate(0x00, (ulong)isr0, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x01, (ulong)isr1, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x02, (ulong)isr2, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x03, (ulong)isr3, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x04, (ulong)isr4, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x05, (ulong)isr5, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x06, (ulong)isr6, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x07, (ulong)isr7, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x08, (ulong)isr8, codeSeg, 0x8E, 1);
|
||||
KeSetIDTGate(0x09, (ulong)isr9, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x0A, (ulong)isr10, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x0B, (ulong)isr11, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x0C, (ulong)isr12, codeSeg, 0x8E, 1);
|
||||
KeSetIDTGate(0x0D, (ulong)isr13, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x0E, (ulong)isr14, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x0F, (ulong)isr15, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x10, (ulong)isr16, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x11, (ulong)isr17, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x12, (ulong)isr18, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x13, (ulong)isr19, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x14, (ulong)isr20, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x15, (ulong)isr21, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x16, (ulong)isr22, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x17, (ulong)isr23, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x18, (ulong)isr24, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x19, (ulong)isr25, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x1A, (ulong)isr26, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x1B, (ulong)isr27, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x1C, (ulong)isr28, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x1D, (ulong)isr29, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x1E, (ulong)isr30, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x1F, (ulong)isr31, codeSeg, 0x8E, 0); // INTEL RESERVED
|
||||
KeSetIDTGate(0x00, (ulong)isr0, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x01, (ulong)isr1, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x02, (ulong)isr2, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x03, (ulong)isr3, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x04, (ulong)isr4, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x05, (ulong)isr5, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x06, (ulong)isr6, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x07, (ulong)isr7, codeSeg, 0x8E, 2); // XXX device not available, useful for FPU save/restore when multitasking
|
||||
KeSetIDTGate(0x08, (ulong)isr8, codeSeg, 0x8E, 1); // DOUBLE FAULT
|
||||
KeSetIDTGate(0x09, (ulong)isr9, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x0A, (ulong)isr10, codeSeg, 0x8E, 0); // INVALID TSS
|
||||
KeSetIDTGate(0x0B, (ulong)isr11, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x0C, (ulong)isr12, codeSeg, 0x8E, 1); // STACK SEGMENT FAULT
|
||||
KeSetIDTGate(0x0D, (ulong)isr13, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x0E, (ulong)isr14, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x0F, (ulong)isr15, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
KeSetIDTGate(0x10, (ulong)isr16, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x11, (ulong)isr17, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x12, (ulong)isr18, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x13, (ulong)isr19, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x14, (ulong)isr20, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x15, (ulong)isr21, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
KeSetIDTGate(0x16, (ulong)isr22, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
KeSetIDTGate(0x17, (ulong)isr23, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
KeSetIDTGate(0x18, (ulong)isr24, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
KeSetIDTGate(0x19, (ulong)isr25, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
KeSetIDTGate(0x1A, (ulong)isr26, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
KeSetIDTGate(0x1B, (ulong)isr27, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
KeSetIDTGate(0x1C, (ulong)isr28, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
KeSetIDTGate(0x1D, (ulong)isr29, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
KeSetIDTGate(0x1E, (ulong)isr30, codeSeg, 0x8E, 2);
|
||||
KeSetIDTGate(0x1F, (ulong)isr31, codeSeg, 0x8E, 2); // INTEL RESERVED
|
||||
|
||||
// Set IDT IRQs Gates
|
||||
KeSetIDTGate(0x20, (ulong)isr32, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x21, (ulong)isr33, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x22, (ulong)isr34, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x23, (ulong)isr35, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x24, (ulong)isr36, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x25, (ulong)isr37, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x26, (ulong)isr38, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x27, (ulong)isr39, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x28, (ulong)isr40, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x29, (ulong)isr41, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x2A, (ulong)isr42, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x2B, (ulong)isr43, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x2C, (ulong)isr44, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x2D, (ulong)isr45, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x2E, (ulong)isr46, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x2F, (ulong)isr47, codeSeg, 0x8E, 0);
|
||||
KeSetIDTGate(0x20, (ulong)isr32, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x21, (ulong)isr33, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x22, (ulong)isr34, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x23, (ulong)isr35, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x24, (ulong)isr36, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x25, (ulong)isr37, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x26, (ulong)isr38, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x27, (ulong)isr39, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x28, (ulong)isr40, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x29, (ulong)isr41, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x2A, (ulong)isr42, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x2B, (ulong)isr43, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x2C, (ulong)isr44, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x2D, (ulong)isr45, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x2E, (ulong)isr46, codeSeg, 0x8E, 3);
|
||||
KeSetIDTGate(0x2F, (ulong)isr47, codeSeg, 0x8E, 3);
|
||||
|
||||
KeIdtIsInitialized++;
|
||||
|
||||
|
@ -293,8 +292,8 @@ void KeDisableNMI(void)
|
|||
//
|
||||
void _KeHandleISR(ISRFrame_t *regs)
|
||||
{
|
||||
if ((!regs) || (!regs->rip))
|
||||
KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n");
|
||||
/* if ((!regs) || (!regs->rip)) */
|
||||
/* KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); */
|
||||
|
||||
if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1D))
|
||||
return; // INTEL RESERVED
|
||||
|
@ -341,20 +340,6 @@ static void EarlyExceptionHandler(ISRFrame_t *regs)
|
|||
//
|
||||
static void DoubleFaultHandler(ISRFrame_t *regs)
|
||||
{
|
||||
ulong StackGuardTwo = (ulong)MmGetStackGuards(1);
|
||||
|
||||
if (regs->rsp <= StackGuardTwo + 4*KB && (regs->rsp - 4*KB <= regs->cr2)) {
|
||||
bprintf(BStdOut,
|
||||
"\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Stack Overflow\n\n"
|
||||
" Double Fault Error code : %#x (%b)\n"
|
||||
" Stack Guard bypassed : %#x",
|
||||
|
||||
VGA_COLOR_LIGHT_RED,
|
||||
regs->ErrorCode,
|
||||
regs->ErrorCode,
|
||||
StackGuardTwo
|
||||
);
|
||||
} else {
|
||||
bprintf(BStdOut,
|
||||
"\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Double Fault Abort\n\n"
|
||||
" Error code : 0x%x (%b)",
|
||||
|
@ -364,8 +349,6 @@ static void DoubleFaultHandler(ISRFrame_t *regs)
|
|||
regs->ErrorCode
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
KeBrkDumpRegisters(regs);
|
||||
|
||||
BStdOut->flusher(BStdOut);
|
||||
|
|
|
@ -95,6 +95,10 @@ isrPreHandler:
|
|||
|
||||
iretq
|
||||
|
||||
Die:
|
||||
hlt
|
||||
jmp Die
|
||||
|
||||
;; Divide Error Fault
|
||||
IsrWithoutErrCode 0
|
||||
|
||||
|
|
|
@ -37,6 +37,9 @@ static char TimeFmtBuf[22] = { 0 };
|
|||
//
|
||||
// ISR handler for the Programmable Interval Timer
|
||||
//
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("O0")
|
||||
static void HandlePIT(ISRFrame_t *regs)
|
||||
{
|
||||
Ticks++;
|
||||
|
@ -52,6 +55,7 @@ static void HandlePIT(ISRFrame_t *regs)
|
|||
KeSendEOItoPIC(0x28);
|
||||
}
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
static Timer_t* KeFindTimerBlock(void)
|
||||
{
|
||||
|
@ -63,6 +67,8 @@ static Timer_t* KeFindTimerBlock(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("O0")
|
||||
void KeSleep(uint delay)
|
||||
{
|
||||
Timer_t *timerBlock;
|
||||
|
@ -77,7 +83,10 @@ void KeSleep(uint delay)
|
|||
}
|
||||
timerBlock->sema = 0;
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize ("O0")
|
||||
Timer_t *KeSetTimer(uint delay)
|
||||
{
|
||||
Timer_t *timerBlock;
|
||||
|
@ -89,6 +98,7 @@ Timer_t *KeSetTimer(uint delay)
|
|||
|
||||
return timerBlock;
|
||||
}
|
||||
#pragma GCC pop_options
|
||||
|
||||
int KeGetTimer(Timer_t *timerBlock)
|
||||
{
|
||||
|
|
|
@ -45,6 +45,10 @@ void MmInitGdt(void)
|
|||
gdt[1].access = 0x98;
|
||||
gdt[1].flags = 0x20;
|
||||
|
||||
gdt[2].lowLimit = 0xFFFF;
|
||||
gdt[2].access = 0x98;
|
||||
gdt[2].flags = 0x20;
|
||||
|
||||
tssDesc.access = 0x89;
|
||||
tssDesc.flags = 0x40;
|
||||
tssDesc.lowBase = (ulong)&tss & 0xFFFF;
|
||||
|
@ -53,7 +57,9 @@ void MmInitGdt(void)
|
|||
tssDesc.veryHighBase = ((ulong)&tss >> 32) & 0xFFFFFFFF;
|
||||
tssDesc.lowLimit = sizeof(tss);
|
||||
|
||||
tss.ist1 = 0x0007FFFF; // RESCUE STACK, GARANTIED FREE FOR USE BY OSDEV.ORG
|
||||
tss.ist1 = (ulong)0x0007FFFF; // ISR RESCUE STACK, GARANTIED FREE FOR USE BY OSDEV.ORG
|
||||
tss.ist2 = (ulong)0x00EFFFFF; // ISR STACK, GARANTIED FREE FOR USE BY OSDEV.ORG
|
||||
tss.ist3 = (ulong)0x00EF0000; // ISR STACK, GARANTIED FREE FOR USE BY OSDEV.ORG
|
||||
tss.iomap_base = sizeof(tss);
|
||||
|
||||
memmove(&gdt[2], &tssDesc, sizeof(TssDescriptor_t));
|
||||
|
|
|
@ -1,39 +1,43 @@
|
|||
#include <kernel.h>
|
||||
#include <init/boot.h>
|
||||
#include <ex/malloc.h>
|
||||
#include <mm/heap.h>
|
||||
#include <mm/mm.h>
|
||||
#include <ke/idt.h>
|
||||
#include <lib/buf.h>
|
||||
#include <io/vga.h>
|
||||
|
||||
enum
|
||||
{
|
||||
MF_PRESENT = 1 << 0,
|
||||
MF_READWRITE = 1 << 1,
|
||||
MF_USERMODE = 1 << 2,
|
||||
MF_WRITETHR = 1 << 3,
|
||||
MF_CACHEDIS = 1 << 4,
|
||||
MF_ACCESSED = 1 << 5,
|
||||
MF_DIRTY = 1 << 6,
|
||||
MF_HUGE = 1 << 7,
|
||||
MF_NX = 1 << 31
|
||||
};
|
||||
|
||||
#define RAM_MAX 32
|
||||
#define NB_4K 150
|
||||
// * 2 MB
|
||||
#define USERSPACE 0x80000000
|
||||
|
||||
//-----------
|
||||
|
||||
volatile pdpe_t MmPML4[512] __attribute__((__aligned__(KPAGESIZE)));
|
||||
pml4_t MmPageMapLevel4[512] __attribute__((__aligned__(KPAGESIZE)));
|
||||
ulong *MmPhysicalPageTable;
|
||||
|
||||
volatile pde_t MmPDP[512] __attribute__((__aligned__(KPAGESIZE)));
|
||||
|
||||
volatile pde_t MmPD[512 * RAM_MAX] __attribute__((__aligned__(KPAGESIZE)));;
|
||||
|
||||
volatile pte_t MmPT[512 * NB_4K] __attribute__((__aligned__(KPAGESIZE)));;
|
||||
extern ulong _text;
|
||||
extern ulong _text_end;
|
||||
extern ulong _rodata;
|
||||
extern ulong _rodata_end;
|
||||
extern ulong _data;
|
||||
extern ulong _data_end;
|
||||
|
||||
ulong MmStackGuards[2] = { 0 };
|
||||
ulong MmVirtLastAddress = 0;
|
||||
|
||||
enum
|
||||
{
|
||||
PRESENT = 1 << 0,
|
||||
READWRITE = 1 << 1,
|
||||
USERMODE = 1 << 2,
|
||||
WRITETHR = 1 << 3,
|
||||
CACHEDIS = 1 << 4,
|
||||
ACCESSED = 1 << 5,
|
||||
DIRTY = 1 << 6,
|
||||
HUGE = 1 << 7,
|
||||
NX = 1UL << 63
|
||||
};
|
||||
|
||||
//-----------
|
||||
|
||||
//
|
||||
// Creates our new page table structure and loads it
|
||||
|
@ -41,140 +45,294 @@ ulong MmStackGuards[2] = { 0 };
|
|||
void MmInitPaging(void)
|
||||
{
|
||||
extern MemoryMap_t memoryMap;
|
||||
pdpe_t *MmPDP = NULL;
|
||||
pde_t *MmPD = NULL;
|
||||
pte_t *MmPT = NULL;
|
||||
ulong index, xedni;
|
||||
ulong firstDirectoryAddr = 0;
|
||||
ulong lastDirectoryAddr = 0;
|
||||
ulong phDirSize = 0;
|
||||
|
||||
// Maximum PHYSICAL address in memory
|
||||
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
|
||||
|
||||
memzero((void *)&MmPML4[0], sizeof(MmPML4));
|
||||
memzero((void *)&MmPDP[0], sizeof(MmPDP));
|
||||
memzero((void *)&MmPD[0], sizeof(MmPD));
|
||||
memzero((void *)&MmPT[0], sizeof(MmPT));
|
||||
// Difference between the end of kernel and the begin of userspace
|
||||
ulong lastKernelAddr = (ulong)(_heap_start + _heap_max);
|
||||
ulong diffKernUsr = (ulong)USERSPACE - lastKernelAddr - KPAGESIZE;
|
||||
|
||||
for (volatile ulong i = 0; i < 512 * NB_4K; i++) {
|
||||
// STACK GUARD PAGE
|
||||
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.stackEndAddr) {
|
||||
MmPT[i] = ((ulong)(i*KPAGESIZE));
|
||||
MmStackGuards[0] = ((ulong)(i*KPAGESIZE));
|
||||
continue;
|
||||
// Maximum VIRTUAL address in memory
|
||||
MmVirtLastAddress = phRamSize + diffKernUsr;
|
||||
|
||||
//DebugLog("\tPaging gap : %u MB (%p)\n\tLast virtual address %p\n", diffKernUsr / MB, diffKernUsr, MmVirtLastAddress);
|
||||
|
||||
memzero((void *)&MmPageMapLevel4[0], sizeof(MmPageMapLevel4));
|
||||
phDirSize = ((phRamSize / KPAGESIZE)*sizeof(ulong) + KPAGESIZE) & ( ~(KPAGESIZE - 1));
|
||||
|
||||
MmPhysicalPageTable = (ulong*)malloc(phDirSize);
|
||||
//DebugLog("\t\tRam %u MB, pagesize %u KB, size %u MB\n", phRamSize / MB, KPAGESIZE / KB, phDirSize / MB);
|
||||
|
||||
for (ulong curAddrPML4 = 0;
|
||||
curAddrPML4 < MmVirtLastAddress;
|
||||
curAddrPML4 += ((ulong)KPAGESIZE * 0x8000000)) {
|
||||
// Create an entry in PML4 each 512GB
|
||||
// 0x8000000 = 512 ^ 3
|
||||
|
||||
MmPDP = (pdpe_t *)malloc(512*sizeof(pde_t));
|
||||
|
||||
if (!firstDirectoryAddr) {
|
||||
firstDirectoryAddr = (ulong)MmPDP;
|
||||
}
|
||||
|
||||
// ENOMEM like
|
||||
if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) {
|
||||
break;
|
||||
index = (curAddrPML4 / ((ulong)KPAGESIZE * 0x8000000)) % 512;
|
||||
|
||||
//DebugLog("\t\t\t\tPDP %d : %p\n", index, MmPDP);
|
||||
MmPageMapLevel4[index] = (pdpe_t *)((ulong)MmPDP | PRESENT | READWRITE);
|
||||
|
||||
for (ulong curAddrPDP = curAddrPML4;
|
||||
curAddrPDP < (curAddrPML4 + ((ulong)KPAGESIZE * 0x8000000)) &&
|
||||
curAddrPDP < MmVirtLastAddress;
|
||||
curAddrPDP += ((ulong)KPAGESIZE * 0x40000)) {
|
||||
// Create an intry in PDP each 1GB
|
||||
// 0x40000 = 512 ^ 2
|
||||
|
||||
MmPD = (pde_t *)malloc(512*sizeof(pde_t));
|
||||
|
||||
index = (curAddrPDP / ((ulong)KPAGESIZE * 0x40000)) % 512;
|
||||
|
||||
//DebugLog("\t\t\t\tPD %d : %p\n", index, MmPD);
|
||||
MmPDP[index] = (pde_t *)((ulong)MmPD | PRESENT | READWRITE);
|
||||
|
||||
for (ulong curAddrPD = curAddrPDP;
|
||||
curAddrPD < (curAddrPDP + ((ulong)KPAGESIZE * 0x40000)) &&
|
||||
curAddrPD < MmVirtLastAddress;
|
||||
curAddrPD += ((ulong)KPAGESIZE * 0x200)) {
|
||||
// Create an intry in PD each 2MB
|
||||
// 0x200 = 512
|
||||
|
||||
MmPT = (pte_t *)malloc(512*sizeof(pte_t));
|
||||
|
||||
index = (curAddrPD / ((ulong)KPAGESIZE * 0x200)) % 512;
|
||||
|
||||
//DebugLog("\t\t\t\tPT %d : %p\n", index, MmPT);
|
||||
MmPD[index] = (pte_t *)((ulong)MmPT | PRESENT | READWRITE);
|
||||
|
||||
for (ulong curAddrPT = curAddrPD;
|
||||
curAddrPT < (curAddrPD + ((ulong)KPAGESIZE * 0x200)) &&
|
||||
curAddrPT < MmVirtLastAddress;
|
||||
curAddrPT += (ulong)KPAGESIZE) {
|
||||
// Create an entry in PT each page of 4KB
|
||||
|
||||
index = (curAddrPT / ((ulong)KPAGESIZE)) % 512;
|
||||
xedni = (curAddrPT / ((ulong)KPAGESIZE));
|
||||
|
||||
//DebugLog("\t\t\t\tPage %d : %p\n", index, curAddrPT);
|
||||
|
||||
// STACK GUARD PAGE */
|
||||
if ((ulong)curAddrPT == (ulong)BtLoaderInfo.stackEndAddr) {
|
||||
MmPT[index] = (ulong)curAddrPT | PRESENT;
|
||||
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
|
||||
MmStackGuards[0] = (ulong)curAddrPT;
|
||||
DebugLog("\tStack Guard at %p\n", curAddrPT);
|
||||
}
|
||||
else if ((ulong)curAddrPT == (ulong)BtLoaderInfo.kernelEndAddr) {
|
||||
MmPT[index] = (ulong)curAddrPT | PRESENT;
|
||||
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
|
||||
MmStackGuards[1] = (ulong)curAddrPT;
|
||||
DebugLog("\tStack Guard at %p\n", curAddrPT);
|
||||
}
|
||||
// SECTION .TEXT PROTECTION
|
||||
else if ((ulong)curAddrPT >= (ulong)&_text && (ulong)curAddrPT <= (ulong)&_text_end) {
|
||||
MmPT[index] = (ulong)curAddrPT | PRESENT;
|
||||
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
|
||||
//DebugLog("\tSection .text at %p\n", curAddrPT);
|
||||
}
|
||||
// SECTION .DATA PROTECTION
|
||||
else if ((ulong)curAddrPT >= (ulong)&_data && (ulong)curAddrPT <= (ulong)&_data_end) {
|
||||
MmPT[index] = (ulong)curAddrPT | PRESENT | WRITETHR | READWRITE | NX;
|
||||
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
|
||||
//DebugLog("\tSection .data at %p\n", curAddrPT);
|
||||
}
|
||||
// SECTION .RODATA PROTECTION
|
||||
else if ((ulong)curAddrPT >= (ulong)&_rodata && (ulong)curAddrPT <= (ulong)&_rodata_end) {
|
||||
MmPT[index] = (ulong)curAddrPT | PRESENT | WRITETHR | NX;
|
||||
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
|
||||
//DebugLog("\tSection .rodata at %p\n", curAddrPT);
|
||||
}
|
||||
// While we're inside the kernel pages
|
||||
else if ((ulong)curAddrPT <= lastKernelAddr) {
|
||||
MmPT[index] = (ulong)curAddrPT | PRESENT | READWRITE;
|
||||
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
|
||||
|
||||
if ((ulong)curAddrPT == lastKernelAddr) {
|
||||
//DebugLog("\tLast page of kernel at %p\n", curAddrPT);
|
||||
}
|
||||
}
|
||||
// While we're inside the userspace pages
|
||||
else if ((ulong)curAddrPT >= USERSPACE) {
|
||||
MmPT[index] = ((ulong)curAddrPT - diffKernUsr) | PRESENT; // Not present for instance
|
||||
xedni = (((ulong)curAddrPT - diffKernUsr) / ((ulong)KPAGESIZE));
|
||||
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
|
||||
|
||||
if ((ulong)curAddrPT == USERSPACE) {
|
||||
DebugLog("\tUserspace at %p:%p\n", curAddrPT, curAddrPT - diffKernUsr);
|
||||
}
|
||||
}
|
||||
else {
|
||||
MmPT[index] = 0;
|
||||
}
|
||||
|
||||
// STACK GARD PAGE
|
||||
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) {
|
||||
MmPT[i] = ((ulong)(i*KPAGESIZE));
|
||||
MmStackGuards[1] = ((ulong)(i*KPAGESIZE));
|
||||
continue;
|
||||
KeFlushTlbSingle(curAddrPT);
|
||||
}
|
||||
|
||||
MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE;
|
||||
}
|
||||
|
||||
for (volatile ulong i = 0; i < NB_4K; i++) {
|
||||
MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE;
|
||||
}
|
||||
|
||||
for (volatile ulong i = NB_4K; i < 512 * RAM_MAX; i++) {
|
||||
// ENOMEM like
|
||||
if ((ulong)(i* UPAGESIZE) > (ulong)phRamSize) {
|
||||
break;
|
||||
}
|
||||
lastDirectoryAddr = (ulong)MmPT;
|
||||
|
||||
MmPD[i] = 0;
|
||||
MmPD[i] = ((ulong)(i* UPAGESIZE)) | MF_PRESENT | MF_READWRITE | MF_HUGE;
|
||||
}
|
||||
MmLoadPML4((void *)MmPageMapLevel4);
|
||||
//MmEnableWriteProtect();
|
||||
|
||||
for (volatile int i = 0; i < RAM_MAX; i++) {
|
||||
MmPDP[i] = (ulong)(&MmPD[i*512])| MF_PRESENT | MF_READWRITE;
|
||||
}
|
||||
|
||||
MmPML4[0] = (ulong)(&MmPDP[0])| MF_PRESENT | MF_READWRITE;
|
||||
|
||||
MmLoadPML4((void *)MmPML4);
|
||||
//DebugLog("\tPaging tables initialized at %p, %p\n", &MmPD, &MmPT);
|
||||
//DebugLog("\tStack Guards at %p, %p\n", MmStackGuards[0], MmStackGuards[1]);
|
||||
DebugLog("\tPage table size : %u MB\n", (lastDirectoryAddr - firstDirectoryAddr + phDirSize)/MB);
|
||||
}
|
||||
|
||||
//
|
||||
// Reloads the page tables
|
||||
// Get a page from an address
|
||||
//
|
||||
void MmReloadPaging(void)
|
||||
static pte_t *MmGetPageDescriptorFromVirtual(void *virtualAddr)
|
||||
{
|
||||
extern MemoryMap_t memoryMap;
|
||||
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
|
||||
ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1));
|
||||
|
||||
|
||||
for (volatile ulong i = 0; i < 512 * NB_4K; i++) {
|
||||
// STACK GUARD PAGE
|
||||
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.stackEndAddr) {
|
||||
MmPT[i] = ((ulong)(i*KPAGESIZE));
|
||||
MmStackGuards[0] = ((ulong)(i*KPAGESIZE));
|
||||
continue;
|
||||
if (virtAddrPage > MmVirtLastAddress) {
|
||||
KeStartPanic("MmSetPage() Out of bound of the address space !");
|
||||
}
|
||||
|
||||
// ENOMEM like
|
||||
if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) {
|
||||
break;
|
||||
}
|
||||
pdpe_t *pdp = (pdpe_t*)((ulong)MmPageMapLevel4[(virtAddrPage / ((ulong)KPAGESIZE * 0x8000000)) % 512] & ~(KPAGESIZE - 1));
|
||||
//DebugLog("pdp\t: %p\n", pdp);
|
||||
pde_t *pd = (pde_t*)( (ulong)pdp[(virtAddrPage / ((ulong)KPAGESIZE * 0x40000)) % 512] & ~(KPAGESIZE - 1));
|
||||
//DebugLog("pd\t: %p\n", pd);
|
||||
pte_t *pt = (pte_t*)( (ulong)pd[(virtAddrPage / ((ulong)KPAGESIZE * 0x200)) % 512] & ~(KPAGESIZE - 1));
|
||||
//DebugLog("pt\t: %p\n", pt);
|
||||
|
||||
// STACK GARD PAGE
|
||||
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) {
|
||||
MmPT[i] = ((ulong)(i*KPAGESIZE));
|
||||
MmStackGuards[1] = ((ulong)(i*KPAGESIZE));
|
||||
continue;
|
||||
}
|
||||
pte_t *page = &pt[(virtAddrPage / ((ulong)KPAGESIZE)) % 512];
|
||||
//DebugLog("page (with flags): %p\n", page);
|
||||
|
||||
MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE;
|
||||
}
|
||||
|
||||
for (volatile ulong i = 0; i < NB_4K; i++) {
|
||||
MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE;
|
||||
}
|
||||
|
||||
for (volatile ulong i = NB_4K; i < 512 * RAM_MAX; i++) {
|
||||
// ENOMEM like
|
||||
if ((ulong)(i* UPAGESIZE) > (ulong)phRamSize) {
|
||||
break;
|
||||
}
|
||||
|
||||
MmPD[i] = 0;
|
||||
MmPD[i] = ((ulong)(i* UPAGESIZE)) | MF_PRESENT | MF_READWRITE | MF_HUGE;
|
||||
}
|
||||
|
||||
for (volatile int i = 0; i < RAM_MAX; i++) {
|
||||
MmPDP[i] = (ulong)(&MmPD[i*512])| MF_PRESENT | MF_READWRITE;
|
||||
}
|
||||
|
||||
MmPML4[0] = (ulong)(&MmPDP[0])| MF_PRESENT | MF_READWRITE;
|
||||
|
||||
MmLoadPML4((void *)MmPML4);
|
||||
DebugLog("\tPaging tables initialized at %p, %p\n", &MmPD, &MmPT);
|
||||
DebugLog("\tStack Guards at %p, %p\n", MmStackGuards[0], MmStackGuards[1]);
|
||||
return page;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Translates a virtual address to its physical equivalent
|
||||
//
|
||||
void *MmTransVirtToPhyAddr(void* virtualAddr)
|
||||
{
|
||||
ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1));
|
||||
pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
|
||||
|
||||
if (*page == (*page & ~(KPAGESIZE - 1))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void*)((*page & ~(KPAGESIZE - 1))+ ((ulong)virtualAddr - (ulong)virtAddrPage));
|
||||
}
|
||||
|
||||
void *MmTransPhyToVirtAddr(void* physicalAddr)
|
||||
{
|
||||
ulong phyAddrPage = (ulong)physicalAddr & ( ~(KPAGESIZE - 1));
|
||||
return (void*)( MmPhysicalPageTable[(ulong)physicalAddr
|
||||
/ ((ulong)KPAGESIZE)
|
||||
+ ((ulong)physicalAddr - phyAddrPage) ] );
|
||||
}
|
||||
|
||||
//
|
||||
// Add flags to a page
|
||||
//
|
||||
void MmSetPage(void* virtualAddr, ulong flags)
|
||||
{
|
||||
pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
|
||||
|
||||
*page |= flags;
|
||||
|
||||
KeFlushTlbSingle(*page);
|
||||
}
|
||||
|
||||
//
|
||||
// Remove flags of a page
|
||||
//
|
||||
void MmUnsetPage(void* virtualAddr, ulong flags)
|
||||
{
|
||||
pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
|
||||
|
||||
*page &= (~flags);
|
||||
|
||||
KeFlushTlbSingle(*page);
|
||||
}
|
||||
|
||||
//
|
||||
// Map a page in memory
|
||||
//
|
||||
void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags)
|
||||
{
|
||||
pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
|
||||
|
||||
*page = ((ulong)physicalAddr & ~(KPAGESIZE - 1)) | flags;
|
||||
|
||||
KeFlushTlbSingle(*page);
|
||||
}
|
||||
|
||||
//
|
||||
// Unmap a page in memory
|
||||
//
|
||||
void MmUnmapPage(void* virtualAddr)
|
||||
{
|
||||
pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
|
||||
|
||||
*page = 0;
|
||||
|
||||
KeFlushTlbSingle(*page);
|
||||
}
|
||||
|
||||
//
|
||||
// Kernel Page allocator
|
||||
//
|
||||
void *MmKAllocPageBlock(void *start) {
|
||||
pte_t *startPage = MmGetPageDescriptorFromVirtual(start);
|
||||
|
||||
//for (ulong curPage = 0; curPage < )
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// User page allocator
|
||||
//
|
||||
void *MmUAllocPageBlock(void *start) {
|
||||
pte_t *startPage = MmGetPageDescriptorFromVirtual(start);
|
||||
|
||||
//for (ulong curPage = 0; curPage < )
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------
|
||||
|
||||
//
|
||||
// Returns the rank of the Stack Guards
|
||||
//
|
||||
void *MmGetStackGuards(char rank)
|
||||
{
|
||||
return (void *)MmStackGuards[(int)rank];
|
||||
}
|
||||
|
||||
// Returns an address corresponding to the PT rank
|
||||
void *MmTranslateKPageToAddr(void *rank)
|
||||
{
|
||||
return (void *)MmPT[(ulong)rank];
|
||||
}
|
||||
|
||||
//
|
||||
// Page fault handler
|
||||
//
|
||||
static void PagingHandler(ISRFrame_t *regs)
|
||||
{
|
||||
ulong StackGuardOne = (ulong)MmGetStackGuards(0);
|
||||
if (regs->cr2 >= StackGuardOne && (regs->rsp + 4*KB >= regs->cr2)) {
|
||||
ulong StackGuardTwo = (ulong)MmGetStackGuards(1);
|
||||
if ((regs->cr2 >= StackGuardOne) && (regs->cr2 <= StackGuardOne + KPAGESIZE) && (regs->rsp <= regs->cr2)) {
|
||||
bprintf(BStdOut,
|
||||
"\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Stack Underflow\n\n"
|
||||
" Double Fault Error code : %#x (%b)\n"
|
||||
" Page Fault Error code : %#x (%b)\n"
|
||||
" Stack Guard bypassed : %#x",
|
||||
|
||||
VGA_COLOR_LIGHT_RED,
|
||||
|
@ -182,19 +340,68 @@ static void PagingHandler(ISRFrame_t *regs)
|
|||
regs->ErrorCode,
|
||||
StackGuardOne
|
||||
);
|
||||
} else {
|
||||
//XXX page fault
|
||||
bprintf(BStdOut, "\n\n%CPANIC\n[ISR 0x%x] Irrecoverable Kernel Page Fault at %p\n\n"
|
||||
" Error code : 0x%x (%b)",
|
||||
} else if ((regs->cr2 >= StackGuardTwo) && (regs->cr2 <= StackGuardTwo + KPAGESIZE) && (regs->rsp >= regs->cr2)) {
|
||||
bprintf(BStdOut,
|
||||
"\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Stack Overflow\n\n"
|
||||
" Page Fault Error code : %#x (%b)\n"
|
||||
" Stack Guard bypassed : %#x",
|
||||
|
||||
VGA_COLOR_LIGHT_RED,
|
||||
regs->ErrorCode,
|
||||
regs->ErrorCode,
|
||||
StackGuardTwo
|
||||
);
|
||||
} else if (regs->cr2 == 0) {
|
||||
bprintf(BStdOut,
|
||||
"\n\n%CPANIC\n[ISR 0x8] Null vector exception !\n\n"
|
||||
" Page Fault Error code : %#x (%b)\n",
|
||||
|
||||
VGA_COLOR_LIGHT_RED,
|
||||
regs->intNo,
|
||||
regs->ErrorCode,
|
||||
regs->ErrorCode
|
||||
);
|
||||
} else if (regs->cr2 >= MmVirtLastAddress || regs->cr2 <= 0) {
|
||||
bprintf(BStdOut,
|
||||
"\n\n%CPANIC\n[ISR 0x8] Out of bound of the address space at %p !\n\n"
|
||||
" End of the address space : %p\n"
|
||||
" Page Fault Error code : %#x (%b)\n",
|
||||
|
||||
VGA_COLOR_LIGHT_RED,
|
||||
regs->cr2,
|
||||
MmVirtLastAddress,
|
||||
regs->ErrorCode,
|
||||
regs->ErrorCode
|
||||
);
|
||||
} else {
|
||||
//XXX page fault
|
||||
bprintf(BStdOut, "\n\n%CPANIC\n[ISR 0x8] Irrecoverable Page Fault at %p\n\n"
|
||||
" Error code : 0x%x (%b)",
|
||||
|
||||
VGA_COLOR_LIGHT_RED,
|
||||
regs->cr2,
|
||||
regs->ErrorCode,
|
||||
regs->ErrorCode
|
||||
);
|
||||
}
|
||||
|
||||
bprintf(BStdOut, "\n Description : ");
|
||||
|
||||
if (regs->ErrorCode & PRESENT) {
|
||||
bprintf(BStdOut, "Page-protection violation ");
|
||||
} else {
|
||||
bprintf(BStdOut, "Non present page ");
|
||||
}
|
||||
if (regs->ErrorCode & READWRITE) {
|
||||
bprintf(BStdOut, "during write access ");
|
||||
} else {
|
||||
bprintf(BStdOut, "during read access ");
|
||||
}
|
||||
if (regs->ErrorCode & (1 << 3))
|
||||
bprintf(BStdOut, "from userspace ");
|
||||
if (regs->ErrorCode & (1 << 4))
|
||||
bprintf(BStdOut, "after instruction fetching ");
|
||||
|
||||
KeBrkDumpRegisters(regs);
|
||||
|
||||
BStdOut->flusher(BStdOut);
|
||||
|
|
|
@ -126,9 +126,8 @@ void ShStartShell(void)
|
|||
|
||||
default:
|
||||
|
||||
while (IoGetScroll() > 0) {
|
||||
IoSetScroll(1);
|
||||
IoScrollDown();
|
||||
}
|
||||
|
||||
*bufptr++ = (char)ch;
|
||||
|
||||
|
|
|
@ -55,6 +55,19 @@ error_t CmdArgs(int argc, char **argv, char *cmdline)
|
|||
return EOK;
|
||||
}
|
||||
|
||||
error_t CmdAtoi(int argc, char **argv, char *cmdline)
|
||||
{
|
||||
int i;
|
||||
|
||||
KernLog("cmdline: '%s'\nargc: %d\n", cmdline, argc);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
KernLog("argv[%d]: '%u'\n", i, atoi(argv[i]));
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
error_t CmdDumpATASect(int argc, char **argv, char *cmdline)
|
||||
{
|
||||
char sector[512] = {0};
|
||||
|
@ -96,6 +109,42 @@ error_t CmdDumpATASect(int argc, char **argv, char *cmdline)
|
|||
return EOK;
|
||||
}
|
||||
|
||||
error_t CmdDumpMem(int argc, char **argv, char *cmdline)
|
||||
{
|
||||
char sector[1024] = {0};
|
||||
char *address = (char*)strtoul(argv[1], NULL, 16);
|
||||
int nb = 1; //atoi(argv[2]);
|
||||
int x = 0;
|
||||
int step = 16;
|
||||
|
||||
KernLog("Address begin: %p\n", address);
|
||||
|
||||
for (int i = 0; i < 1024*nb; i++) {
|
||||
sector[i] = *address++;
|
||||
}
|
||||
|
||||
while(x < 1024*nb) {
|
||||
KernLog("%C", shcol);
|
||||
for (int i = 0; i < step; i++) {
|
||||
KernLog("%02x ", (uchar)sector[i+x]);
|
||||
}
|
||||
KernLog(" %C ", VGA_COLOR_LIGHT_BLUE);
|
||||
for (int i = 0; i < step; i++) {
|
||||
if (isprint(sector[i+x]))
|
||||
KernLog("%c",
|
||||
sector[i+x]
|
||||
);
|
||||
else
|
||||
KernLog("%c", 0);
|
||||
}
|
||||
KernLog("\n");
|
||||
x += step;
|
||||
}
|
||||
|
||||
KernLog("\n\n");
|
||||
return EOK;
|
||||
}
|
||||
|
||||
error_t CmdFloatDiv(int argc, char **argv, char *cmdline)
|
||||
{
|
||||
double a = (double)atoi(argv[1]);
|
||||
|
@ -140,22 +189,79 @@ error_t CmdHelpTest(int argc, char **argv, char *cmdline)
|
|||
return EOK;
|
||||
}
|
||||
|
||||
error_t CmdPF(int argc, char **argv, char *cmdline)
|
||||
error_t CmdPageTranslateVirtToPhy(int argc, char **argv, char *cmdline)
|
||||
{
|
||||
char *address = (void*)(ulong)atoi(argv[1]);
|
||||
void *address = (void*)atoul(argv[1]);
|
||||
|
||||
KernLog("Provoking Page Fault at %#x\n", address);
|
||||
if (!(void*)strtoul(argv[1], NULL, 16)) {
|
||||
KernLog("No argument : translating the userspace address\n");
|
||||
address = (void *)0x80000000;
|
||||
}
|
||||
|
||||
*address = 1;
|
||||
void *translation = MmTransVirtToPhyAddr(address);
|
||||
|
||||
KernLog("No page fault : address was valid/present\n");
|
||||
KernLog("Translation of %p is %p\n", address, translation);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
PRESENT = 1 << 0,
|
||||
READWRITE = 1 << 1,
|
||||
USERMODE = 1 << 2,
|
||||
WRITETHR = 1 << 3,
|
||||
CACHEDIS = 1 << 4,
|
||||
ACCESSED = 1 << 5,
|
||||
DIRTY = 1 << 6,
|
||||
HUGE = 1 << 7,
|
||||
NX = 1UL << 63
|
||||
};
|
||||
|
||||
error_t CmdPageMap(int argc, char **argv, char *cmdline)
|
||||
{
|
||||
void *virtual = (void*)strtoul(argv[1], NULL, 16);
|
||||
void *physical = (void*)strtoul(argv[2], NULL, 16);
|
||||
|
||||
MmMapPage(virtual, physical, PRESENT | READWRITE);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
error_t CmdReloadPage(int argc, char **argv, char *cmdline)
|
||||
error_t CmdPageUnmap(int argc, char **argv, char *cmdline)
|
||||
{
|
||||
MmReloadPaging();
|
||||
void *virtual = (void*)strtoul(argv[1], NULL, 16);
|
||||
|
||||
MmUnmapPage(virtual);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
error_t CmdPageTranslatePhyToVirt(int argc, char **argv, char *cmdline)
|
||||
{
|
||||
void *address = (void*)strtoul(argv[1], NULL, 16);
|
||||
|
||||
/* if (!(void*)atoul(argv[1])) { */
|
||||
/* address = (ulong *)0x80000000; */
|
||||
/* } */
|
||||
|
||||
void *translation = MmTransPhyToVirtAddr(address);
|
||||
|
||||
KernLog("Translation of %p is %p\n", address, translation);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
error_t CmdPF(int argc, char **argv, char *cmdline)
|
||||
{
|
||||
ulong *address = (ulong*)(ulong)strtoul(argv[1], NULL, 16);
|
||||
|
||||
KernLog("Provoking Page Fault at %#x\n", address);
|
||||
|
||||
KernLog("It contained %#x\n", *address);
|
||||
*address = 1;
|
||||
KernLog("Now it contains %#x\n", *address);
|
||||
|
||||
KernLog("No page fault : address was valid/present\n");
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
@ -199,11 +305,18 @@ error_t CmdTimerTest(int argc, char **argv, char *cmdline)
|
|||
static Command_t testcmdtable[] =
|
||||
{
|
||||
{ "args", CmdArgs, "Print command line" },
|
||||
{ "atoi", CmdAtoi, "Print command line atoised" },
|
||||
{ "dmpsec", CmdDumpATASect, "Dump an ATA sector on screen" },
|
||||
{ "dmp", CmdDumpMem, "Dump 1MB of memory starting from addr"},
|
||||
{ "help", CmdHelpTest, "Show this message" },
|
||||
{ "div", CmdFloatDiv, "Float div. Usage : div a b. Returns a/b"},
|
||||
{ "transvtp", CmdPageTranslateVirtToPhy, "Translate a virtual to"
|
||||
" physical address (paging)"},
|
||||
{ "transptv", CmdPageTranslatePhyToVirt, "Translate a physical to"
|
||||
" virtual address (paging)"},
|
||||
{ "pmap", CmdPageMap, "Map a page to given physical addr" },
|
||||
{ "punmap", CmdPageUnmap, "Unmap a page" },
|
||||
{ "pf", CmdPF, "Provoke a PF. Usage: pfault <address>"},
|
||||
{ "rpag", CmdReloadPage, "Reload the pages directory" },
|
||||
{ "shell", CmdShell, "Start a new shell (nested)", },
|
||||
{ "stkov", CmdStackOverflow, "Provoke a stack overflow" },
|
||||
{ "stkun", CmdStackUnderflow, "Provoke a stack underflow" },
|
||||
|
|
Loading…
Reference in New Issue