diff --git a/Makefile b/Makefile
index 0d11f9b..05c091e 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@
# along with OS/K. If not, see . #
#=----------------------------------------------------------------------------=#
-.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 ---------------------------------------------------------- #
diff --git a/README.md b/README.md
index 7d3b06a..93be98b 100644
--- a/README.md
+++ b/README.md
@@ -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)
+
+
+
diff --git a/build/kernel.ld b/build/kernel.ld
index 0840bf2..7604bd8 100644
--- a/build/kernel.ld
+++ b/build/kernel.ld
@@ -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 = .;
}
-
diff --git a/include/asm.h b/include/asm.h
index 4694222..936ae50 100644
--- a/include/asm.h
+++ b/include/asm.h
@@ -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 //
//------------------------------------------//
diff --git a/include/init/boot.h b/include/init/boot.h
index 61cfa19..5594870 100644
--- a/include/init/boot.h
+++ b/include/init/boot.h
@@ -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;
};
diff --git a/include/io/spkr.h b/include/io/spkr.h
index 760928a..be9eea5 100644
--- a/include/io/spkr.h
+++ b/include/io/spkr.h
@@ -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
diff --git a/include/io/vga.h b/include/io/vga.h
index 319c790..11d7c50 100644
--- a/include/io/vga.h
+++ b/include/io/vga.h
@@ -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);
diff --git a/include/mm/mm.h b/include/mm/mm.h
index 8bd9238..50657f1 100644
--- a/include/mm/mm.h
+++ b/include/mm/mm.h
@@ -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);
//----------------------------------------------------------------------------//
diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c
index ceda825..12d3792 100644
--- a/kaleid/kernel/init/init.c
+++ b/kaleid/kernel/init/init.c
@@ -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)
diff --git a/kaleid/kernel/io/spkr.c b/kaleid/kernel/io/spkr.c
index dff5d21..66a7f5c 100644
--- a/kaleid/kernel/io/spkr.c
+++ b/kaleid/kernel/io/spkr.c
@@ -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();
diff --git a/kaleid/kernel/io/vga.c b/kaleid/kernel/io/vga.c
index e02041d..80d6842 100644
--- a/kaleid/kernel/io/vga.c
+++ b/kaleid/kernel/io/vga.c
@@ -113,6 +113,11 @@ uint IoGetScroll(void)
return bscroll;
}
+void IoSetScroll(uint value)
+{
+ bscroll = 0;
+}
+
void IoScrollDown(void)
{
BLockBuf(BStdOut);
diff --git a/kaleid/kernel/ke/idt.c b/kaleid/kernel/ke/idt.c
index d5dc7e2..d6fc0fc 100644
--- a/kaleid/kernel/ke/idt.c
+++ b/kaleid/kernel/ke/idt.c
@@ -26,7 +26,6 @@
#include
#include
#include
-#include
#include
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,21 +340,7 @@ 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,
+ 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);
diff --git a/kaleid/kernel/ke/isr.asm b/kaleid/kernel/ke/isr.asm
index 8a92419..7c07e6f 100644
--- a/kaleid/kernel/ke/isr.asm
+++ b/kaleid/kernel/ke/isr.asm
@@ -95,6 +95,10 @@ isrPreHandler:
iretq
+Die:
+ hlt
+ jmp Die
+
;; Divide Error Fault
IsrWithoutErrCode 0
diff --git a/kaleid/kernel/ke/pit.c b/kaleid/kernel/ke/pit.c
index db3bfda..a9d961c 100644
--- a/kaleid/kernel/ke/pit.c
+++ b/kaleid/kernel/ke/pit.c
@@ -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)
{
diff --git a/kaleid/kernel/mm/gdt.c b/kaleid/kernel/mm/gdt.c
index eb3c4e3..8bd426a 100644
--- a/kaleid/kernel/mm/gdt.c
+++ b/kaleid/kernel/mm/gdt.c
@@ -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));
diff --git a/kaleid/kernel/mm/paging.c b/kaleid/kernel/mm/paging.c
index 7b9a93c..5a7e77e 100644
--- a/kaleid/kernel/mm/paging.c
+++ b/kaleid/kernel/mm/paging.c
@@ -1,39 +1,43 @@
#include
#include
#include
+#include
#include
#include
#include
#include
-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;
- // ENOMEM like
- if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) {
- break;
- }
+ //DebugLog("\tPaging gap : %u MB (%p)\n\tLast virtual address %p\n", diffKernUsr / MB, diffKernUsr, MmVirtLastAddress);
- // STACK GARD PAGE
- if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) {
- MmPT[i] = ((ulong)(i*KPAGESIZE));
- MmStackGuards[1] = ((ulong)(i*KPAGESIZE));
- continue;
- }
+ memzero((void *)&MmPageMapLevel4[0], sizeof(MmPageMapLevel4));
+ phDirSize = ((phRamSize / KPAGESIZE)*sizeof(ulong) + KPAGESIZE) & ( ~(KPAGESIZE - 1));
- MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE;
+ 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;
+ }
+
+ 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;
+ }
+
+ KeFlushTlbSingle(curAddrPT);
+ }
+ }
+ }
}
+ lastDirectoryAddr = (ulong)MmPT;
- for (volatile ulong i = 0; i < NB_4K; i++) {
- MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE;
- }
+ MmLoadPML4((void *)MmPageMapLevel4);
+ //MmEnableWriteProtect();
- 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]);
+ 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;
- }
-
- // ENOMEM like
- if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) {
- break;
- }
-
- // STACK GARD PAGE
- if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) {
- MmPT[i] = ((ulong)(i*KPAGESIZE));
- MmStackGuards[1] = ((ulong)(i*KPAGESIZE));
- continue;
- }
-
- MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE;
+ if (virtAddrPage > MmVirtLastAddress) {
+ KeStartPanic("MmSetPage() Out of bound of the address space !");
}
- for (volatile ulong i = 0; i < NB_4K; i++) {
- MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE;
- }
+ 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);
- for (volatile ulong i = NB_4K; i < 512 * RAM_MAX; i++) {
- // ENOMEM like
- if ((ulong)(i* UPAGESIZE) > (ulong)phRamSize) {
- break;
- }
+ pte_t *page = &pt[(virtAddrPage / ((ulong)KPAGESIZE)) % 512];
+ //DebugLog("page (with flags): %p\n", page);
- 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);
diff --git a/kaleid/kernel/sh/shell.c b/kaleid/kernel/sh/shell.c
index 99fde03..c9d16ce 100644
--- a/kaleid/kernel/sh/shell.c
+++ b/kaleid/kernel/sh/shell.c
@@ -126,9 +126,8 @@ void ShStartShell(void)
default:
- while (IoGetScroll() > 0) {
- IoScrollDown();
- }
+ IoSetScroll(1);
+ IoScrollDown();
*bufptr++ = (char)ch;
diff --git a/kaleid/kernel/sh/testcmds.c b/kaleid/kernel/sh/testcmds.c
index 50661fc..f528b71 100644
--- a/kaleid/kernel/sh/testcmds.c
+++ b/kaleid/kernel/sh/testcmds.c
@@ -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 "},
- { "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" },