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/>. #
|
# 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 ---------------------------------------------------------- #
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 = .;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 //
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,21 +340,7 @@ static void EarlyExceptionHandler(ISRFrame_t *regs)
|
||||||
//
|
//
|
||||||
static void DoubleFaultHandler(ISRFrame_t *regs)
|
static void DoubleFaultHandler(ISRFrame_t *regs)
|
||||||
{
|
{
|
||||||
ulong StackGuardTwo = (ulong)MmGetStackGuards(1);
|
bprintf(BStdOut,
|
||||||
|
|
||||||
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"
|
"\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);
|
||||||
|
|
|
@ -95,6 +95,10 @@ isrPreHandler:
|
||||||
|
|
||||||
iretq
|
iretq
|
||||||
|
|
||||||
|
Die:
|
||||||
|
hlt
|
||||||
|
jmp Die
|
||||||
|
|
||||||
;; Divide Error Fault
|
;; Divide Error Fault
|
||||||
IsrWithoutErrCode 0
|
IsrWithoutErrCode 0
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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));
|
|
||||||
MmStackGuards[0] = ((ulong)(i*KPAGESIZE));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ENOMEM like
|
//DebugLog("\tPaging gap : %u MB (%p)\n\tLast virtual address %p\n", diffKernUsr / MB, diffKernUsr, MmVirtLastAddress);
|
||||||
if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// STACK GARD PAGE
|
memzero((void *)&MmPageMapLevel4[0], sizeof(MmPageMapLevel4));
|
||||||
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) {
|
phDirSize = ((phRamSize / KPAGESIZE)*sizeof(ulong) + KPAGESIZE) & ( ~(KPAGESIZE - 1));
|
||||||
MmPT[i] = ((ulong)(i*KPAGESIZE));
|
|
||||||
MmStackGuards[1] = ((ulong)(i*KPAGESIZE));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
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++) {
|
MmLoadPML4((void *)MmPageMapLevel4);
|
||||||
MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE;
|
//MmEnableWriteProtect();
|
||||||
}
|
|
||||||
|
|
||||||
for (volatile ulong i = NB_4K; i < 512 * RAM_MAX; i++) {
|
DebugLog("\tPage table size : %u MB\n", (lastDirectoryAddr - firstDirectoryAddr + phDirSize)/MB);
|
||||||
// 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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// 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
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (volatile ulong i = 0; i < NB_4K; i++) {
|
pdpe_t *pdp = (pdpe_t*)((ulong)MmPageMapLevel4[(virtAddrPage / ((ulong)KPAGESIZE * 0x8000000)) % 512] & ~(KPAGESIZE - 1));
|
||||||
MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE;
|
//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++) {
|
pte_t *page = &pt[(virtAddrPage / ((ulong)KPAGESIZE)) % 512];
|
||||||
// ENOMEM like
|
//DebugLog("page (with flags): %p\n", page);
|
||||||
if ((ulong)(i* UPAGESIZE) > (ulong)phRamSize) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
MmPD[i] = 0;
|
return page;
|
||||||
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);
|
||||||
|
|
|
@ -126,9 +126,8 @@ void ShStartShell(void)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
while (IoGetScroll() > 0) {
|
IoSetScroll(1);
|
||||||
IoScrollDown();
|
IoScrollDown();
|
||||||
}
|
|
||||||
|
|
||||||
*bufptr++ = (char)ch;
|
*bufptr++ = (char)ch;
|
||||||
|
|
||||||
|
|
|
@ -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" },
|
||||||
|
|
Loading…
Reference in New Issue