Merge branch 'master' into shell

This commit is contained in:
Adrien Bourmault 2020-01-10 19:58:53 +01:00
commit 5fba767e64
18 changed files with 647 additions and 276 deletions

View File

@ -22,7 +22,7 @@
# along with OS/K. If not, see <https://www.gnu.org/licenses/>. # # 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 .DELETE_ON_ERROR: $(BINDIR)/kaleid
.DEFAULT_GOAL := all .DEFAULT_GOAL := all
@ -41,7 +41,7 @@ CCNAME=x86_64-elf-gcc
ASMFLAGS=-f elf64 ASMFLAGS=-f elf64
LDFLAGS=-melf_x86_64 LDFLAGS=-melf_x86_64
COPTIM=-O2 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 CINCLUDES=-Iinclude
CFLAGS1=-nostdlib -ffreestanding -mcmodel=large -std=gnu11 -fstack-protector-all -fdump-rtl-expand CFLAGS1=-nostdlib -ffreestanding -mcmodel=large -std=gnu11 -fstack-protector-all -fdump-rtl-expand
CFLAGS2= -c -mno-red-zone -mno-mmx -mno-sse -mno-sse2 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 & cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log &
gdb: all installonimage 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 \ -hda $(installdisk) -no-reboot -no-shutdown -d \
cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log & cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log &
@gdb \ @gdb \
@ -302,9 +302,26 @@ gdb: all installonimage
-ex "break BtStartKern" \ -ex "break BtStartKern" \
ddd: all installonimage ddd: all installonimage
@setsid qemu-system-x86_64 -m $(ram) -hda $(installdisk) -no-reboot -soundhw pcspk \ @setsid qemu-system-x86_64 -m $(ram) -enable-kvm -rtc base=localtime \
-no-shutdown -d cpu_reset,guest_errors,pcall,int -s 2> $(BUILDDIR)/qemu.log & -hda $(installdisk) -no-reboot -no-shutdown -d \
@ddd 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 ---------------------------------------------------------- # ## HD IMAGE RELATED ---------------------------------------------------------- #

View File

@ -42,3 +42,8 @@ To compile and install, simply use at the root of this project, with XXX the ima
make install installdisk=XXX make install installdisk=XXX
``` ```
#### Screenshot
![OS/K Started](https://www.os-k.eu/images/screen3.png)

View File

@ -38,13 +38,16 @@ SECTIONS {
.text ALIGN (0x1000) : .text ALIGN (0x1000) :
{ {
_text = .;
*(.text) *(.text)
_text_end = .;
} }
.data ALIGN (0x1000) : .data ALIGN (0x1000) :
{ {
_data = .; _data = .;
*(.data) *(.data)
_data_end = .;
} }
.eh_frame ALIGN (0x1000) : .eh_frame ALIGN (0x1000) :
@ -55,7 +58,9 @@ SECTIONS {
.rodata ALIGN (0x1000) : .rodata ALIGN (0x1000) :
{ {
_rodata = .;
*(.rodata) *(.rodata)
_rodata_end = .;
} }
.bss ALIGN (0x1000) : .bss ALIGN (0x1000) :
@ -71,4 +76,3 @@ SECTIONS {
kernelEnd = .; kernelEnd = .;
} }

View File

@ -136,6 +136,11 @@ static inline ulong KeReadStsc(void) {
return ((ulong)edx << 32) + eax; return ((ulong)edx << 32) + eax;
} }
static inline void KeFlushTlbSingle(ulong addr)
{
asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
}
//------------------------------------------// //------------------------------------------//
// Misc. I/O // // Misc. I/O //
//------------------------------------------// //------------------------------------------//

View File

@ -44,24 +44,24 @@ struct BootInfo_t
{ {
// The Bootloader infos // The Bootloader infos
struct { struct {
ushort valid;
uint grubFlags; //flags
uint modulesCount; //mods_count
void *modulesAddr; //mods_addr void *modulesAddr; //mods_addr
char *grubName; //boot_loader_name
void *kernelAddr; void *kernelAddr;
void *codeSegment; void *codeSegment;
void *kernelEndAddr; void *kernelEndAddr;
void *stackEndAddr; // stack begins 16B after kernelEndAddr void *stackEndAddr; // stack begins 16B after kernelEndAddr
uint grubFlags; //flags
uint modulesCount; //mods_count
ushort valid;
char *grubName; //boot_loader_name
} btldr; } btldr;
// Informations about drives // Informations about drives
struct { struct {
ushort drvValid; void *bufferAddr; //drives_addr
ushort bufferValid;
uint bootDrv; //boot_device uint bootDrv; //boot_device
uint bufferLength; //drives_length uint bufferLength; //drives_length
void *bufferAddr; //drives_addr ushort drvValid;
ushort bufferValid;
} drives; } drives;
// Informations about memory // Informations about memory
@ -74,36 +74,36 @@ struct BootInfo_t
uint upMemory; //mem_upper uint upMemory; //mem_upper
//GRUB provided memory map //GRUB provided memory map
uint mapLength; //mmap_length
void *mapAddr; //mmap_addr void *mapAddr; //mmap_addr
uint mapLength; //mmap_length
uint ramSize; //The ram (init by map.c) uint ramSize; //The ram (init by map.c)
} memory; } memory;
// Informations about the video drive // Informations about the video drive
struct { struct {
ushort vbeValid;
ushort fbuValid;
void *vbeControl; //vbe_control_info void *vbeControl; //vbe_control_info
void *vbeModeInfo; //vbe_mode_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 void *framebufferAddr; //framebuffer_addr
uint framebufferPitch; //framebuffer_pitch uint framebufferPitch; //framebuffer_pitch
uint framebufferWidth; //framebuffer_width uint framebufferWidth; //framebuffer_width
uint framebufferHeight; //framebuffer_height 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 framebufferBpp; //framebuffer_bpp
uchar framebufferType; //framebuffer_type uchar framebufferType; //framebuffer_type
} video; } video;
// Informations about the microcode firmware (BIOS/EFI) // Informations about the microcode firmware (BIOS/EFI)
struct { struct {
ushort apmValid;
ushort romValid;
uint apmTable; //apm_table uint apmTable; //apm_table
uint romTable; //config_table uint romTable; //config_table
ushort apmValid;
ushort romValid;
} firmware; } firmware;
}; };

View File

@ -31,13 +31,19 @@
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
void IoStartSpeaker(int); void IoStartSpeaker(ulong);
void IoDoBeep(void); void IoDoBeep(void);
void IoDoTone(uint tone, uint time); void IoDoTone(ulong tone, ulong time);
void IoDoBeepNoIdt(void); void IoDoBeepNoIdt(void);
void IoDoStarWars(void); void IoDoStarWars(void);
struct Note
{
ulong tone;
ulong time;
};
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
#endif #endif

View File

@ -59,6 +59,7 @@ extern const char *RtlColorNames[VGA_COLOR_WHITE+1];
#define RtlCharToColor(c) ((c) - 130) #define RtlCharToColor(c) ((c) - 130)
uint IoGetScroll(void); uint IoGetScroll(void);
void IoSetScroll(uint);
void IoScrollUp(void); void IoScrollUp(void);
void IoScrollDown(void); void IoScrollDown(void);

View File

@ -41,7 +41,7 @@
#define BADRAM_ZONE 5 // Invalid zone because material problem... #define BADRAM_ZONE 5 // Invalid zone because material problem...
#define MAX_ENTRIES 2048 // Max number of memory map entries #define MAX_ENTRIES 2048 // Max number of memory map entries
#define KPAGESIZE (4 * KB) #define KPAGESIZE (4 * KB)
#define UPAGESIZE (2 * MB) #define UPAGESIZE (4 * KB)
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
@ -108,7 +108,7 @@ struct Tss_t
ushort iomap_base; ushort iomap_base;
uchar iomap[IOMAP_SIZE]; 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); extern void MmStoreGdt(void);
//
// Paging misc
//
void MmInitPaging(void); void MmInitPaging(void);
void MmReloadPaging(void);
void MmActivatePageHandler(void); void MmActivatePageHandler(void);
// //
@ -170,24 +171,39 @@ void MmActivatePageHandler(void);
void *MmGetStackGuards(char rank); 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 // Page table entry
typedef ulong pte_t; 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 // paging.asm
void MmLoadPML4(void *); void MmLoadPML4(void *);
void MmEnableWriteProtect(void); void MmEnableWriteProtect(void);
void MmDisableWriteProtect(void); void MmDisableWriteProtect(void);
void *MmGetStackGuards(char rank);
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//

View File

@ -62,21 +62,21 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
// Memory // Memory
MmInitMemoryMap(); MmInitMemoryMap();
MmInitPaging(); MmInitGdt();
MmInitHeap();
// Basics for interrupts // Interrupts
KeSetupIDT(); KeSetupIDT();
KeEnableIRQs(); KeEnableIRQs();
// Memory (2)
MmInitHeap();
MmInitPaging();
// Interrupt handlers
MmActivatePageHandler();
KeEnableRTC(); KeEnableRTC();
KeEnablePIT(); KeEnablePIT();
KeGetCpuInfos(); KeGetCpuInfos();
// Memory (2)
MmInitGdt();
MmActivatePageHandler();
// Drivers
IoEnableKeyb(); IoEnableKeyb();
// Command line (kernel mode) // Command line (kernel mode)

View File

@ -28,10 +28,21 @@
extern bool KeIdtIsInitialized; 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; uchar temp;
uint pitf = 1193180 / freq; ulong pitf = 1193180 / freq;
ulong flags = KePauseIRQs(); ulong flags = KePauseIRQs();
IoWriteByteOnPort(0x43, 0xB6); IoWriteByteOnPort(0x43, 0xB6);
@ -52,13 +63,13 @@ static inline void IoQuietSpeaker(void)
KeRestoreIRQs(flags); KeRestoreIRQs(flags);
} }
void IoDoTone(uint tone, uint time) void IoDoTone(ulong tone, ulong time)
{ {
IoStartSpeaker(tone); IoStartSpeaker(tone);
KeSleep(time); KeSleep(time);
} }
static void IoDoToneNoIdt(uint tone, uint time) static void IoDoToneNoIdt(ulong tone, ulong time)
{ {
extern void temporize(void); extern void temporize(void);
IoStartSpeaker(tone); IoStartSpeaker(tone);
@ -81,29 +92,8 @@ void IoDoBeepNoIdt(void)
void IoDoStarWars(void) void IoDoStarWars(void)
{ {
struct Note { for (uint i = 0; i < 40; i++) {
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++) {
IoDoTone(score[i].tone, score[i].time); IoDoTone(score[i].tone, score[i].time);
//bprintf(BStdOut, "%d ", i);
//BStdOut->flusher(BStdOut);
} }
IoQuietSpeaker(); IoQuietSpeaker();

View File

@ -113,6 +113,11 @@ uint IoGetScroll(void)
return bscroll; return bscroll;
} }
void IoSetScroll(uint value)
{
bscroll = 0;
}
void IoScrollDown(void) void IoScrollDown(void)
{ {
BLockBuf(BStdOut); BLockBuf(BStdOut);

View File

@ -26,7 +26,6 @@
#include <init/boot.h> #include <init/boot.h>
#include <ke/idt.h> #include <ke/idt.h>
#include <io/vga.h> #include <io/vga.h>
#include <mm/mm.h>
#include <io/spkr.h> #include <io/spkr.h>
IdtEntry_t idt[256] = { 0 }; IdtEntry_t idt[256] = { 0 };
@ -120,56 +119,56 @@ void KeSetupIDT(void)
_KeIdtPtr.base = &idt; _KeIdtPtr.base = &idt;
// Set IDT Exception Gates // Set IDT Exception Gates
KeSetIDTGate(0x00, (ulong)isr0, codeSeg, 0x8E, 0); KeSetIDTGate(0x00, (ulong)isr0, codeSeg, 0x8E, 2);
KeSetIDTGate(0x01, (ulong)isr1, codeSeg, 0x8E, 0); KeSetIDTGate(0x01, (ulong)isr1, codeSeg, 0x8E, 2);
KeSetIDTGate(0x02, (ulong)isr2, codeSeg, 0x8E, 0); KeSetIDTGate(0x02, (ulong)isr2, codeSeg, 0x8E, 2);
KeSetIDTGate(0x03, (ulong)isr3, codeSeg, 0x8E, 0); KeSetIDTGate(0x03, (ulong)isr3, codeSeg, 0x8E, 2);
KeSetIDTGate(0x04, (ulong)isr4, codeSeg, 0x8E, 0); KeSetIDTGate(0x04, (ulong)isr4, codeSeg, 0x8E, 2);
KeSetIDTGate(0x05, (ulong)isr5, codeSeg, 0x8E, 0); KeSetIDTGate(0x05, (ulong)isr5, codeSeg, 0x8E, 2);
KeSetIDTGate(0x06, (ulong)isr6, codeSeg, 0x8E, 0); KeSetIDTGate(0x06, (ulong)isr6, codeSeg, 0x8E, 2);
KeSetIDTGate(0x07, (ulong)isr7, codeSeg, 0x8E, 0); 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); KeSetIDTGate(0x08, (ulong)isr8, codeSeg, 0x8E, 1); // DOUBLE FAULT
KeSetIDTGate(0x09, (ulong)isr9, codeSeg, 0x8E, 0); KeSetIDTGate(0x09, (ulong)isr9, codeSeg, 0x8E, 2);
KeSetIDTGate(0x0A, (ulong)isr10, codeSeg, 0x8E, 0); KeSetIDTGate(0x0A, (ulong)isr10, codeSeg, 0x8E, 0); // INVALID TSS
KeSetIDTGate(0x0B, (ulong)isr11, codeSeg, 0x8E, 0); KeSetIDTGate(0x0B, (ulong)isr11, codeSeg, 0x8E, 2);
KeSetIDTGate(0x0C, (ulong)isr12, codeSeg, 0x8E, 1); KeSetIDTGate(0x0C, (ulong)isr12, codeSeg, 0x8E, 1); // STACK SEGMENT FAULT
KeSetIDTGate(0x0D, (ulong)isr13, codeSeg, 0x8E, 0); KeSetIDTGate(0x0D, (ulong)isr13, codeSeg, 0x8E, 2);
KeSetIDTGate(0x0E, (ulong)isr14, codeSeg, 0x8E, 0); KeSetIDTGate(0x0E, (ulong)isr14, codeSeg, 0x8E, 2);
KeSetIDTGate(0x0F, (ulong)isr15, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x0F, (ulong)isr15, codeSeg, 0x8E, 2); // INTEL RESERVED
KeSetIDTGate(0x10, (ulong)isr16, codeSeg, 0x8E, 0); KeSetIDTGate(0x10, (ulong)isr16, codeSeg, 0x8E, 2);
KeSetIDTGate(0x11, (ulong)isr17, codeSeg, 0x8E, 0); KeSetIDTGate(0x11, (ulong)isr17, codeSeg, 0x8E, 2);
KeSetIDTGate(0x12, (ulong)isr18, codeSeg, 0x8E, 0); KeSetIDTGate(0x12, (ulong)isr18, codeSeg, 0x8E, 2);
KeSetIDTGate(0x13, (ulong)isr19, codeSeg, 0x8E, 0); KeSetIDTGate(0x13, (ulong)isr19, codeSeg, 0x8E, 2);
KeSetIDTGate(0x14, (ulong)isr20, codeSeg, 0x8E, 0); KeSetIDTGate(0x14, (ulong)isr20, codeSeg, 0x8E, 2);
KeSetIDTGate(0x15, (ulong)isr21, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x15, (ulong)isr21, codeSeg, 0x8E, 2); // INTEL RESERVED
KeSetIDTGate(0x16, (ulong)isr22, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x16, (ulong)isr22, codeSeg, 0x8E, 2); // INTEL RESERVED
KeSetIDTGate(0x17, (ulong)isr23, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x17, (ulong)isr23, codeSeg, 0x8E, 2); // INTEL RESERVED
KeSetIDTGate(0x18, (ulong)isr24, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x18, (ulong)isr24, codeSeg, 0x8E, 2); // INTEL RESERVED
KeSetIDTGate(0x19, (ulong)isr25, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x19, (ulong)isr25, codeSeg, 0x8E, 2); // INTEL RESERVED
KeSetIDTGate(0x1A, (ulong)isr26, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x1A, (ulong)isr26, codeSeg, 0x8E, 2); // INTEL RESERVED
KeSetIDTGate(0x1B, (ulong)isr27, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x1B, (ulong)isr27, codeSeg, 0x8E, 2); // INTEL RESERVED
KeSetIDTGate(0x1C, (ulong)isr28, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x1C, (ulong)isr28, codeSeg, 0x8E, 2); // INTEL RESERVED
KeSetIDTGate(0x1D, (ulong)isr29, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x1D, (ulong)isr29, codeSeg, 0x8E, 2); // INTEL RESERVED
KeSetIDTGate(0x1E, (ulong)isr30, codeSeg, 0x8E, 0); KeSetIDTGate(0x1E, (ulong)isr30, codeSeg, 0x8E, 2);
KeSetIDTGate(0x1F, (ulong)isr31, codeSeg, 0x8E, 0); // INTEL RESERVED KeSetIDTGate(0x1F, (ulong)isr31, codeSeg, 0x8E, 2); // INTEL RESERVED
// Set IDT IRQs Gates // Set IDT IRQs Gates
KeSetIDTGate(0x20, (ulong)isr32, codeSeg, 0x8E, 0); KeSetIDTGate(0x20, (ulong)isr32, codeSeg, 0x8E, 3);
KeSetIDTGate(0x21, (ulong)isr33, codeSeg, 0x8E, 0); KeSetIDTGate(0x21, (ulong)isr33, codeSeg, 0x8E, 3);
KeSetIDTGate(0x22, (ulong)isr34, codeSeg, 0x8E, 0); KeSetIDTGate(0x22, (ulong)isr34, codeSeg, 0x8E, 3);
KeSetIDTGate(0x23, (ulong)isr35, codeSeg, 0x8E, 0); KeSetIDTGate(0x23, (ulong)isr35, codeSeg, 0x8E, 3);
KeSetIDTGate(0x24, (ulong)isr36, codeSeg, 0x8E, 0); KeSetIDTGate(0x24, (ulong)isr36, codeSeg, 0x8E, 3);
KeSetIDTGate(0x25, (ulong)isr37, codeSeg, 0x8E, 0); KeSetIDTGate(0x25, (ulong)isr37, codeSeg, 0x8E, 3);
KeSetIDTGate(0x26, (ulong)isr38, codeSeg, 0x8E, 0); KeSetIDTGate(0x26, (ulong)isr38, codeSeg, 0x8E, 3);
KeSetIDTGate(0x27, (ulong)isr39, codeSeg, 0x8E, 0); KeSetIDTGate(0x27, (ulong)isr39, codeSeg, 0x8E, 3);
KeSetIDTGate(0x28, (ulong)isr40, codeSeg, 0x8E, 0); KeSetIDTGate(0x28, (ulong)isr40, codeSeg, 0x8E, 3);
KeSetIDTGate(0x29, (ulong)isr41, codeSeg, 0x8E, 0); KeSetIDTGate(0x29, (ulong)isr41, codeSeg, 0x8E, 3);
KeSetIDTGate(0x2A, (ulong)isr42, codeSeg, 0x8E, 0); KeSetIDTGate(0x2A, (ulong)isr42, codeSeg, 0x8E, 3);
KeSetIDTGate(0x2B, (ulong)isr43, codeSeg, 0x8E, 0); KeSetIDTGate(0x2B, (ulong)isr43, codeSeg, 0x8E, 3);
KeSetIDTGate(0x2C, (ulong)isr44, codeSeg, 0x8E, 0); KeSetIDTGate(0x2C, (ulong)isr44, codeSeg, 0x8E, 3);
KeSetIDTGate(0x2D, (ulong)isr45, codeSeg, 0x8E, 0); KeSetIDTGate(0x2D, (ulong)isr45, codeSeg, 0x8E, 3);
KeSetIDTGate(0x2E, (ulong)isr46, codeSeg, 0x8E, 0); KeSetIDTGate(0x2E, (ulong)isr46, codeSeg, 0x8E, 3);
KeSetIDTGate(0x2F, (ulong)isr47, codeSeg, 0x8E, 0); KeSetIDTGate(0x2F, (ulong)isr47, codeSeg, 0x8E, 3);
KeIdtIsInitialized++; KeIdtIsInitialized++;
@ -293,8 +292,8 @@ void KeDisableNMI(void)
// //
void _KeHandleISR(ISRFrame_t *regs) void _KeHandleISR(ISRFrame_t *regs)
{ {
if ((!regs) || (!regs->rip)) /* if ((!regs) || (!regs->rip)) */
KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); /* KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); */
if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1D)) if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1D))
return; // INTEL RESERVED return; // INTEL RESERVED
@ -341,20 +340,6 @@ static void EarlyExceptionHandler(ISRFrame_t *regs)
// //
static void DoubleFaultHandler(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" "\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Double Fault Abort\n\n"
" Error code : 0x%x (%b)", " Error code : 0x%x (%b)",
@ -364,8 +349,6 @@ static void DoubleFaultHandler(ISRFrame_t *regs)
regs->ErrorCode regs->ErrorCode
); );
}
KeBrkDumpRegisters(regs); KeBrkDumpRegisters(regs);
BStdOut->flusher(BStdOut); BStdOut->flusher(BStdOut);

View File

@ -95,6 +95,10 @@ isrPreHandler:
iretq iretq
Die:
hlt
jmp Die
;; Divide Error Fault ;; Divide Error Fault
IsrWithoutErrCode 0 IsrWithoutErrCode 0

View File

@ -37,6 +37,9 @@ static char TimeFmtBuf[22] = { 0 };
// //
// ISR handler for the Programmable Interval Timer // ISR handler for the Programmable Interval Timer
// //
#pragma GCC push_options
#pragma GCC optimize ("O0")
static void HandlePIT(ISRFrame_t *regs) static void HandlePIT(ISRFrame_t *regs)
{ {
Ticks++; Ticks++;
@ -52,6 +55,7 @@ static void HandlePIT(ISRFrame_t *regs)
KeSendEOItoPIC(0x28); KeSendEOItoPIC(0x28);
} }
} }
#pragma GCC pop_options
static Timer_t* KeFindTimerBlock(void) static Timer_t* KeFindTimerBlock(void)
{ {
@ -63,6 +67,8 @@ static Timer_t* KeFindTimerBlock(void)
return NULL; return NULL;
} }
#pragma GCC push_options
#pragma GCC optimize ("O0")
void KeSleep(uint delay) void KeSleep(uint delay)
{ {
Timer_t *timerBlock; Timer_t *timerBlock;
@ -77,7 +83,10 @@ void KeSleep(uint delay)
} }
timerBlock->sema = 0; timerBlock->sema = 0;
} }
#pragma GCC pop_options
#pragma GCC push_options
#pragma GCC optimize ("O0")
Timer_t *KeSetTimer(uint delay) Timer_t *KeSetTimer(uint delay)
{ {
Timer_t *timerBlock; Timer_t *timerBlock;
@ -89,6 +98,7 @@ Timer_t *KeSetTimer(uint delay)
return timerBlock; return timerBlock;
} }
#pragma GCC pop_options
int KeGetTimer(Timer_t *timerBlock) int KeGetTimer(Timer_t *timerBlock)
{ {

View File

@ -45,6 +45,10 @@ void MmInitGdt(void)
gdt[1].access = 0x98; gdt[1].access = 0x98;
gdt[1].flags = 0x20; gdt[1].flags = 0x20;
gdt[2].lowLimit = 0xFFFF;
gdt[2].access = 0x98;
gdt[2].flags = 0x20;
tssDesc.access = 0x89; tssDesc.access = 0x89;
tssDesc.flags = 0x40; tssDesc.flags = 0x40;
tssDesc.lowBase = (ulong)&tss & 0xFFFF; tssDesc.lowBase = (ulong)&tss & 0xFFFF;
@ -53,7 +57,9 @@ void MmInitGdt(void)
tssDesc.veryHighBase = ((ulong)&tss >> 32) & 0xFFFFFFFF; tssDesc.veryHighBase = ((ulong)&tss >> 32) & 0xFFFFFFFF;
tssDesc.lowLimit = sizeof(tss); 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); tss.iomap_base = sizeof(tss);
memmove(&gdt[2], &tssDesc, sizeof(TssDescriptor_t)); memmove(&gdt[2], &tssDesc, sizeof(TssDescriptor_t));

View File

@ -1,39 +1,43 @@
#include <kernel.h> #include <kernel.h>
#include <init/boot.h> #include <init/boot.h>
#include <ex/malloc.h> #include <ex/malloc.h>
#include <mm/heap.h>
#include <mm/mm.h> #include <mm/mm.h>
#include <ke/idt.h> #include <ke/idt.h>
#include <lib/buf.h> #include <lib/buf.h>
#include <io/vga.h> #include <io/vga.h>
enum #define USERSPACE 0x80000000
{
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
//----------- //-----------
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))); extern ulong _text;
extern ulong _text_end;
volatile pde_t MmPD[512 * RAM_MAX] __attribute__((__aligned__(KPAGESIZE)));; extern ulong _rodata;
extern ulong _rodata_end;
volatile pte_t MmPT[512 * NB_4K] __attribute__((__aligned__(KPAGESIZE)));; extern ulong _data;
extern ulong _data_end;
ulong MmStackGuards[2] = { 0 }; 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 // Creates our new page table structure and loads it
@ -41,140 +45,294 @@ ulong MmStackGuards[2] = { 0 };
void MmInitPaging(void) void MmInitPaging(void)
{ {
extern MemoryMap_t memoryMap; 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; ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
memzero((void *)&MmPML4[0], sizeof(MmPML4)); // Difference between the end of kernel and the begin of userspace
memzero((void *)&MmPDP[0], sizeof(MmPDP)); ulong lastKernelAddr = (ulong)(_heap_start + _heap_max);
memzero((void *)&MmPD[0], sizeof(MmPD)); ulong diffKernUsr = (ulong)USERSPACE - lastKernelAddr - KPAGESIZE;
memzero((void *)&MmPT[0], sizeof(MmPT));
for (volatile ulong i = 0; i < 512 * NB_4K; i++) { // Maximum VIRTUAL address in memory
// STACK GUARD PAGE MmVirtLastAddress = phRamSize + diffKernUsr;
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.stackEndAddr) {
MmPT[i] = ((ulong)(i*KPAGESIZE)); //DebugLog("\tPaging gap : %u MB (%p)\n\tLast virtual address %p\n", diffKernUsr / MB, diffKernUsr, MmVirtLastAddress);
MmStackGuards[0] = ((ulong)(i*KPAGESIZE));
continue; 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 index = (curAddrPML4 / ((ulong)KPAGESIZE * 0x8000000)) % 512;
if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) {
break; //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 KeFlushTlbSingle(curAddrPT);
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;
} }
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; MmLoadPML4((void *)MmPageMapLevel4);
MmPD[i] = ((ulong)(i* UPAGESIZE)) | MF_PRESENT | MF_READWRITE | MF_HUGE; //MmEnableWriteProtect();
}
for (volatile int i = 0; i < RAM_MAX; i++) { DebugLog("\tPage table size : %u MB\n", (lastDirectoryAddr - firstDirectoryAddr + phDirSize)/MB);
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]);
} }
// //
// Reloads the page tables // Get a page from an address
// //
void MmReloadPaging(void) static pte_t *MmGetPageDescriptorFromVirtual(void *virtualAddr)
{ {
extern MemoryMap_t memoryMap; ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1));
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
if (virtAddrPage > MmVirtLastAddress) {
for (volatile ulong i = 0; i < 512 * NB_4K; i++) { KeStartPanic("MmSetPage() Out of bound of the address space !");
// STACK GUARD PAGE
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.stackEndAddr) {
MmPT[i] = ((ulong)(i*KPAGESIZE));
MmStackGuards[0] = ((ulong)(i*KPAGESIZE));
continue;
} }
// ENOMEM like pdpe_t *pdp = (pdpe_t*)((ulong)MmPageMapLevel4[(virtAddrPage / ((ulong)KPAGESIZE * 0x8000000)) % 512] & ~(KPAGESIZE - 1));
if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) { //DebugLog("pdp\t: %p\n", pdp);
break; 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 pte_t *page = &pt[(virtAddrPage / ((ulong)KPAGESIZE)) % 512];
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) { //DebugLog("page (with flags): %p\n", page);
MmPT[i] = ((ulong)(i*KPAGESIZE));
MmStackGuards[1] = ((ulong)(i*KPAGESIZE));
continue;
}
MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE; return page;
}
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]);
} }
//
// 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 // Returns the rank of the Stack Guards
//
void *MmGetStackGuards(char rank) void *MmGetStackGuards(char rank)
{ {
return (void *)MmStackGuards[(int)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 // Page fault handler
// //
static void PagingHandler(ISRFrame_t *regs) static void PagingHandler(ISRFrame_t *regs)
{ {
ulong StackGuardOne = (ulong)MmGetStackGuards(0); 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, bprintf(BStdOut,
"\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Stack Underflow\n\n" "\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", " Stack Guard bypassed : %#x",
VGA_COLOR_LIGHT_RED, VGA_COLOR_LIGHT_RED,
@ -182,19 +340,68 @@ static void PagingHandler(ISRFrame_t *regs)
regs->ErrorCode, regs->ErrorCode,
StackGuardOne StackGuardOne
); );
} else { } else if ((regs->cr2 >= StackGuardTwo) && (regs->cr2 <= StackGuardTwo + KPAGESIZE) && (regs->rsp >= regs->cr2)) {
//XXX page fault bprintf(BStdOut,
bprintf(BStdOut, "\n\n%CPANIC\n[ISR 0x%x] Irrecoverable Kernel Page Fault at %p\n\n" "\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Stack Overflow\n\n"
" Error code : 0x%x (%b)", " 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, VGA_COLOR_LIGHT_RED,
regs->intNo, 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->cr2,
regs->ErrorCode, regs->ErrorCode,
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); KeBrkDumpRegisters(regs);
BStdOut->flusher(BStdOut); BStdOut->flusher(BStdOut);

View File

@ -126,9 +126,8 @@ void ShStartShell(void)
default: default:
while (IoGetScroll() > 0) { IoSetScroll(1);
IoScrollDown(); IoScrollDown();
}
*bufptr++ = (char)ch; *bufptr++ = (char)ch;

View File

@ -55,6 +55,19 @@ error_t CmdArgs(int argc, char **argv, char *cmdline)
return EOK; 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) error_t CmdDumpATASect(int argc, char **argv, char *cmdline)
{ {
char sector[512] = {0}; char sector[512] = {0};
@ -96,6 +109,42 @@ error_t CmdDumpATASect(int argc, char **argv, char *cmdline)
return EOK; 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) error_t CmdFloatDiv(int argc, char **argv, char *cmdline)
{ {
double a = (double)atoi(argv[1]); double a = (double)atoi(argv[1]);
@ -140,22 +189,79 @@ error_t CmdHelpTest(int argc, char **argv, char *cmdline)
return EOK; 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; 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; return EOK;
} }
@ -199,11 +305,18 @@ error_t CmdTimerTest(int argc, char **argv, char *cmdline)
static Command_t testcmdtable[] = static Command_t testcmdtable[] =
{ {
{ "args", CmdArgs, "Print command line" }, { "args", CmdArgs, "Print command line" },
{ "atoi", CmdAtoi, "Print command line atoised" },
{ "dmpsec", CmdDumpATASect, "Dump an ATA sector on screen" }, { "dmpsec", CmdDumpATASect, "Dump an ATA sector on screen" },
{ "dmp", CmdDumpMem, "Dump 1MB of memory starting from addr"},
{ "help", CmdHelpTest, "Show this message" }, { "help", CmdHelpTest, "Show this message" },
{ "div", CmdFloatDiv, "Float div. Usage : div a b. Returns a/b"}, { "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>"}, { "pf", CmdPF, "Provoke a PF. Usage: pfault <address>"},
{ "rpag", CmdReloadPage, "Reload the pages directory" },
{ "shell", CmdShell, "Start a new shell (nested)", }, { "shell", CmdShell, "Start a new shell (nested)", },
{ "stkov", CmdStackOverflow, "Provoke a stack overflow" }, { "stkov", CmdStackOverflow, "Provoke a stack overflow" },
{ "stkun", CmdStackUnderflow, "Provoke a stack underflow" }, { "stkun", CmdStackUnderflow, "Provoke a stack underflow" },