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/>. #
#=----------------------------------------------------------------------------=#
.PHONY: all test testnokvm testnosnd test32 debug gdb installonimage dust clean OS/K run
.PHONY: all test testnokvm testnosnd test32 debug gdb ddd gdbnokvm dddnokvm installonimage dust clean OS/K run
.DELETE_ON_ERROR: $(BINDIR)/kaleid
.DEFAULT_GOAL := all
@ -41,7 +41,7 @@ CCNAME=x86_64-elf-gcc
ASMFLAGS=-f elf64
LDFLAGS=-melf_x86_64
COPTIM=-O2
CWARNS=-Wall -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough -Werror=implicit-function-declaration -Werror=return-type
CWARNS=-Wall -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough -Werror=implicit-function-declaration -Werror=return-type #-Wpadded
CINCLUDES=-Iinclude
CFLAGS1=-nostdlib -ffreestanding -mcmodel=large -std=gnu11 -fstack-protector-all -fdump-rtl-expand
CFLAGS2= -c -mno-red-zone -mno-mmx -mno-sse -mno-sse2
@ -292,7 +292,7 @@ test32: all installonimage
cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log &
gdb: all installonimage
@setsid qemu-system-x86_64 -m $(ram) -soundhw pcspk -rtc base=localtime \
@setsid qemu-system-x86_64 -m $(ram) -enable-kvm -rtc base=localtime \
-hda $(installdisk) -no-reboot -no-shutdown -d \
cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log &
@gdb \
@ -302,9 +302,26 @@ gdb: all installonimage
-ex "break BtStartKern" \
ddd: all installonimage
@setsid qemu-system-x86_64 -m $(ram) -hda $(installdisk) -no-reboot -soundhw pcspk \
-no-shutdown -d cpu_reset,guest_errors,pcall,int -s 2> $(BUILDDIR)/qemu.log &
@ddd
@setsid qemu-system-x86_64 -m $(ram) -enable-kvm -rtc base=localtime \
-hda $(installdisk) -no-reboot -no-shutdown -d \
cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log &
@ddd -n
gdbnokvm: all installonimage
@setsid qemu-system-x86_64 -m $(ram) -rtc base=localtime \
-hda $(installdisk) -no-reboot -no-shutdown -d \
cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log &
@gdb \
-ex "set arch i386:x86-64:intel" \
-ex "target remote localhost:1234" \
-ex "symbol-file $(BINDIR)/kaleid" \
-ex "break BtStartKern" \
dddnokvm: all installonimage
@setsid qemu-system-x86_64 -m $(ram) -rtc base=localtime \
-hda $(installdisk) -no-reboot -no-shutdown -d \
cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log &
@ddd -n
## HD IMAGE RELATED ---------------------------------------------------------- #

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
```
#### Screenshot
![OS/K Started](https://www.os-k.eu/images/screen3.png)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -41,7 +41,7 @@
#define BADRAM_ZONE 5 // Invalid zone because material problem...
#define MAX_ENTRIES 2048 // Max number of memory map entries
#define KPAGESIZE (4 * KB)
#define UPAGESIZE (2 * MB)
#define UPAGESIZE (4 * KB)
//----------------------------------------------------------------------------//
@ -108,7 +108,7 @@ struct Tss_t
ushort iomap_base;
uchar iomap[IOMAP_SIZE];
} __attribute__ ((packed));
} __attribute__ ((packed)) __attribute__((aligned(8)));
@ -158,10 +158,11 @@ extern void MmLoadGdt(GdtPtr_t *gdtPtr, ushort tssOffset);
//
extern void MmStoreGdt(void);
//
// Paging misc
//
void MmInitPaging(void);
void MmReloadPaging(void);
void MmActivatePageHandler(void);
//
@ -170,24 +171,39 @@ void MmActivatePageHandler(void);
void *MmGetStackGuards(char rank);
//
// Translate a virtual address into physical address
// Translate a virtual address into physical address and the opposite
//
void *MmTranslateKPageToAddr(void *rank);
void *MmTransVirtToPhyAddr(void*);
void *MmTransPhyToVirtAddr(void* virtualAddr);
// Page directory pointer offset
typedef ulong pdpe_t;
//
// Set flags to a page
//
void MmSetPage(void* virtualAddr, ulong flags);
void MmUnSetPage(void* virtualAddr, ulong flags);
// Page directory offset
typedef ulong pde_t;
//
// Map a page
//
void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags);
void MmUnmapPage(void* virtualAddr);
// Page table entry
typedef ulong pte_t;
// Page directory offset
typedef pte_t* pde_t;
// Page directory pointer offset
typedef pde_t* pdpe_t;
// Page directory L4 pointer offset
typedef pdpe_t* pml4_t;
// paging.asm
void MmLoadPML4(void *);
void MmEnableWriteProtect(void);
void MmDisableWriteProtect(void);
void *MmGetStackGuards(char rank);
//----------------------------------------------------------------------------//

View File

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

View File

@ -28,10 +28,21 @@
extern bool KeIdtIsInitialized;
void IoStartSpeaker(int freq)
struct Note score[40] = { {440, 200}, {110, 200}, {440, 200}, {110, 200},
{440, 200}, {110, 200}, {349, 140}, {87, 100},
{523, 60}, {87, 100}, {440, 200}, {110, 200},
{349, 140}, {87, 100}, {523, 60}, {87, 100},
{440, 200}, {110, 200}, {440, 200}, {110, 200},
{659, 200}, {110, 200}, {659, 200}, {110, 200},
{659, 200}, {87, 200}, {698, 140}, {87, 100},
{523, 60}, {87, 100}, {415, 200}, {87, 200},
{349, 140}, {87, 100}, {523, 60}, {87, 100},
{440, 200}, {110, 200}, {110, 200}, {110, 200} };
void IoStartSpeaker(ulong freq)
{
uchar temp;
uint pitf = 1193180 / freq;
ulong pitf = 1193180 / freq;
ulong flags = KePauseIRQs();
IoWriteByteOnPort(0x43, 0xB6);
@ -52,13 +63,13 @@ static inline void IoQuietSpeaker(void)
KeRestoreIRQs(flags);
}
void IoDoTone(uint tone, uint time)
void IoDoTone(ulong tone, ulong time)
{
IoStartSpeaker(tone);
KeSleep(time);
}
static void IoDoToneNoIdt(uint tone, uint time)
static void IoDoToneNoIdt(ulong tone, ulong time)
{
extern void temporize(void);
IoStartSpeaker(tone);
@ -81,29 +92,8 @@ void IoDoBeepNoIdt(void)
void IoDoStarWars(void)
{
struct Note {
uint tone;
uint time;
};
struct Note score[] = { {440, 200}, {110, 200}, {440, 200}, {110, 200},
{440, 200}, {110, 200}, {349, 140}, {87, 100},
{523, 60}, {87, 100}, {440, 200}, {110, 200},
{349, 140}, {87, 100}, {523, 60}, {87, 100},
{440, 200}, {110, 200}, {440, 200}, {110, 200},
{659, 200}, {110, 200}, {659, 200}, {110, 200},
{659, 200}, {87, 200}, {698, 140}, {87, 100},
{523, 60}, {87, 100}, {415, 200}, {87, 200},
{349, 140}, {87, 100}, {523, 60}, {87, 100},
{440, 200}, {110, 200}, {110, 200}, {110, 200}
};
//bprintf(BStdOut, "\n");
for (uint i = 0; i < sizeof(score)/sizeof(struct Note); i++) {
for (uint i = 0; i < 40; i++) {
IoDoTone(score[i].tone, score[i].time);
//bprintf(BStdOut, "%d ", i);
//BStdOut->flusher(BStdOut);
}
IoQuietSpeaker();

View File

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

View File

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

View File

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

View File

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

View File

@ -45,6 +45,10 @@ void MmInitGdt(void)
gdt[1].access = 0x98;
gdt[1].flags = 0x20;
gdt[2].lowLimit = 0xFFFF;
gdt[2].access = 0x98;
gdt[2].flags = 0x20;
tssDesc.access = 0x89;
tssDesc.flags = 0x40;
tssDesc.lowBase = (ulong)&tss & 0xFFFF;
@ -53,7 +57,9 @@ void MmInitGdt(void)
tssDesc.veryHighBase = ((ulong)&tss >> 32) & 0xFFFFFFFF;
tssDesc.lowLimit = sizeof(tss);
tss.ist1 = 0x0007FFFF; // RESCUE STACK, GARANTIED FREE FOR USE BY OSDEV.ORG
tss.ist1 = (ulong)0x0007FFFF; // ISR RESCUE STACK, GARANTIED FREE FOR USE BY OSDEV.ORG
tss.ist2 = (ulong)0x00EFFFFF; // ISR STACK, GARANTIED FREE FOR USE BY OSDEV.ORG
tss.ist3 = (ulong)0x00EF0000; // ISR STACK, GARANTIED FREE FOR USE BY OSDEV.ORG
tss.iomap_base = sizeof(tss);
memmove(&gdt[2], &tssDesc, sizeof(TssDescriptor_t));

View File

@ -1,39 +1,43 @@
#include <kernel.h>
#include <init/boot.h>
#include <ex/malloc.h>
#include <mm/heap.h>
#include <mm/mm.h>
#include <ke/idt.h>
#include <lib/buf.h>
#include <io/vga.h>
enum
{
MF_PRESENT = 1 << 0,
MF_READWRITE = 1 << 1,
MF_USERMODE = 1 << 2,
MF_WRITETHR = 1 << 3,
MF_CACHEDIS = 1 << 4,
MF_ACCESSED = 1 << 5,
MF_DIRTY = 1 << 6,
MF_HUGE = 1 << 7,
MF_NX = 1 << 31
};
#define RAM_MAX 32
#define NB_4K 150
// * 2 MB
#define USERSPACE 0x80000000
//-----------
volatile pdpe_t MmPML4[512] __attribute__((__aligned__(KPAGESIZE)));
pml4_t MmPageMapLevel4[512] __attribute__((__aligned__(KPAGESIZE)));
ulong *MmPhysicalPageTable;
volatile pde_t MmPDP[512] __attribute__((__aligned__(KPAGESIZE)));
volatile pde_t MmPD[512 * RAM_MAX] __attribute__((__aligned__(KPAGESIZE)));;
volatile pte_t MmPT[512 * NB_4K] __attribute__((__aligned__(KPAGESIZE)));;
extern ulong _text;
extern ulong _text_end;
extern ulong _rodata;
extern ulong _rodata_end;
extern ulong _data;
extern ulong _data_end;
ulong MmStackGuards[2] = { 0 };
ulong MmVirtLastAddress = 0;
enum
{
PRESENT = 1 << 0,
READWRITE = 1 << 1,
USERMODE = 1 << 2,
WRITETHR = 1 << 3,
CACHEDIS = 1 << 4,
ACCESSED = 1 << 5,
DIRTY = 1 << 6,
HUGE = 1 << 7,
NX = 1UL << 63
};
//-----------
//
// Creates our new page table structure and loads it
@ -41,140 +45,294 @@ ulong MmStackGuards[2] = { 0 };
void MmInitPaging(void)
{
extern MemoryMap_t memoryMap;
pdpe_t *MmPDP = NULL;
pde_t *MmPD = NULL;
pte_t *MmPT = NULL;
ulong index, xedni;
ulong firstDirectoryAddr = 0;
ulong lastDirectoryAddr = 0;
ulong phDirSize = 0;
// Maximum PHYSICAL address in memory
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
memzero((void *)&MmPML4[0], sizeof(MmPML4));
memzero((void *)&MmPDP[0], sizeof(MmPDP));
memzero((void *)&MmPD[0], sizeof(MmPD));
memzero((void *)&MmPT[0], sizeof(MmPT));
// Difference between the end of kernel and the begin of userspace
ulong lastKernelAddr = (ulong)(_heap_start + _heap_max);
ulong diffKernUsr = (ulong)USERSPACE - lastKernelAddr - KPAGESIZE;
for (volatile ulong i = 0; i < 512 * NB_4K; i++) {
// STACK GUARD PAGE
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.stackEndAddr) {
MmPT[i] = ((ulong)(i*KPAGESIZE));
MmStackGuards[0] = ((ulong)(i*KPAGESIZE));
continue;
}
// Maximum VIRTUAL address in memory
MmVirtLastAddress = phRamSize + diffKernUsr;
// ENOMEM like
if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) {
break;
}
//DebugLog("\tPaging gap : %u MB (%p)\n\tLast virtual address %p\n", diffKernUsr / MB, diffKernUsr, MmVirtLastAddress);
// STACK GARD PAGE
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) {
MmPT[i] = ((ulong)(i*KPAGESIZE));
MmStackGuards[1] = ((ulong)(i*KPAGESIZE));
continue;
}
memzero((void *)&MmPageMapLevel4[0], sizeof(MmPageMapLevel4));
phDirSize = ((phRamSize / KPAGESIZE)*sizeof(ulong) + KPAGESIZE) & ( ~(KPAGESIZE - 1));
MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE;
MmPhysicalPageTable = (ulong*)malloc(phDirSize);
//DebugLog("\t\tRam %u MB, pagesize %u KB, size %u MB\n", phRamSize / MB, KPAGESIZE / KB, phDirSize / MB);
for (ulong curAddrPML4 = 0;
curAddrPML4 < MmVirtLastAddress;
curAddrPML4 += ((ulong)KPAGESIZE * 0x8000000)) {
// Create an entry in PML4 each 512GB
// 0x8000000 = 512 ^ 3
MmPDP = (pdpe_t *)malloc(512*sizeof(pde_t));
if (!firstDirectoryAddr) {
firstDirectoryAddr = (ulong)MmPDP;
}
index = (curAddrPML4 / ((ulong)KPAGESIZE * 0x8000000)) % 512;
//DebugLog("\t\t\t\tPDP %d : %p\n", index, MmPDP);
MmPageMapLevel4[index] = (pdpe_t *)((ulong)MmPDP | PRESENT | READWRITE);
for (ulong curAddrPDP = curAddrPML4;
curAddrPDP < (curAddrPML4 + ((ulong)KPAGESIZE * 0x8000000)) &&
curAddrPDP < MmVirtLastAddress;
curAddrPDP += ((ulong)KPAGESIZE * 0x40000)) {
// Create an intry in PDP each 1GB
// 0x40000 = 512 ^ 2
MmPD = (pde_t *)malloc(512*sizeof(pde_t));
index = (curAddrPDP / ((ulong)KPAGESIZE * 0x40000)) % 512;
//DebugLog("\t\t\t\tPD %d : %p\n", index, MmPD);
MmPDP[index] = (pde_t *)((ulong)MmPD | PRESENT | READWRITE);
for (ulong curAddrPD = curAddrPDP;
curAddrPD < (curAddrPDP + ((ulong)KPAGESIZE * 0x40000)) &&
curAddrPD < MmVirtLastAddress;
curAddrPD += ((ulong)KPAGESIZE * 0x200)) {
// Create an intry in PD each 2MB
// 0x200 = 512
MmPT = (pte_t *)malloc(512*sizeof(pte_t));
index = (curAddrPD / ((ulong)KPAGESIZE * 0x200)) % 512;
//DebugLog("\t\t\t\tPT %d : %p\n", index, MmPT);
MmPD[index] = (pte_t *)((ulong)MmPT | PRESENT | READWRITE);
for (ulong curAddrPT = curAddrPD;
curAddrPT < (curAddrPD + ((ulong)KPAGESIZE * 0x200)) &&
curAddrPT < MmVirtLastAddress;
curAddrPT += (ulong)KPAGESIZE) {
// Create an entry in PT each page of 4KB
index = (curAddrPT / ((ulong)KPAGESIZE)) % 512;
xedni = (curAddrPT / ((ulong)KPAGESIZE));
//DebugLog("\t\t\t\tPage %d : %p\n", index, curAddrPT);
// STACK GUARD PAGE */
if ((ulong)curAddrPT == (ulong)BtLoaderInfo.stackEndAddr) {
MmPT[index] = (ulong)curAddrPT | PRESENT;
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
MmStackGuards[0] = (ulong)curAddrPT;
DebugLog("\tStack Guard at %p\n", curAddrPT);
}
else if ((ulong)curAddrPT == (ulong)BtLoaderInfo.kernelEndAddr) {
MmPT[index] = (ulong)curAddrPT | PRESENT;
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
MmStackGuards[1] = (ulong)curAddrPT;
DebugLog("\tStack Guard at %p\n", curAddrPT);
}
// SECTION .TEXT PROTECTION
else if ((ulong)curAddrPT >= (ulong)&_text && (ulong)curAddrPT <= (ulong)&_text_end) {
MmPT[index] = (ulong)curAddrPT | PRESENT;
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
//DebugLog("\tSection .text at %p\n", curAddrPT);
}
// SECTION .DATA PROTECTION
else if ((ulong)curAddrPT >= (ulong)&_data && (ulong)curAddrPT <= (ulong)&_data_end) {
MmPT[index] = (ulong)curAddrPT | PRESENT | WRITETHR | READWRITE | NX;
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
//DebugLog("\tSection .data at %p\n", curAddrPT);
}
// SECTION .RODATA PROTECTION
else if ((ulong)curAddrPT >= (ulong)&_rodata && (ulong)curAddrPT <= (ulong)&_rodata_end) {
MmPT[index] = (ulong)curAddrPT | PRESENT | WRITETHR | NX;
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
//DebugLog("\tSection .rodata at %p\n", curAddrPT);
}
// While we're inside the kernel pages
else if ((ulong)curAddrPT <= lastKernelAddr) {
MmPT[index] = (ulong)curAddrPT | PRESENT | READWRITE;
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
if ((ulong)curAddrPT == lastKernelAddr) {
//DebugLog("\tLast page of kernel at %p\n", curAddrPT);
}
}
// While we're inside the userspace pages
else if ((ulong)curAddrPT >= USERSPACE) {
MmPT[index] = ((ulong)curAddrPT - diffKernUsr) | PRESENT; // Not present for instance
xedni = (((ulong)curAddrPT - diffKernUsr) / ((ulong)KPAGESIZE));
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
if ((ulong)curAddrPT == USERSPACE) {
DebugLog("\tUserspace at %p:%p\n", curAddrPT, curAddrPT - diffKernUsr);
}
}
else {
MmPT[index] = 0;
}
KeFlushTlbSingle(curAddrPT);
}
}
}
}
lastDirectoryAddr = (ulong)MmPT;
for (volatile ulong i = 0; i < NB_4K; i++) {
MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE;
}
MmLoadPML4((void *)MmPageMapLevel4);
//MmEnableWriteProtect();
for (volatile ulong i = NB_4K; i < 512 * RAM_MAX; i++) {
// ENOMEM like
if ((ulong)(i* UPAGESIZE) > (ulong)phRamSize) {
break;
}
MmPD[i] = 0;
MmPD[i] = ((ulong)(i* UPAGESIZE)) | MF_PRESENT | MF_READWRITE | MF_HUGE;
}
for (volatile int i = 0; i < RAM_MAX; i++) {
MmPDP[i] = (ulong)(&MmPD[i*512])| MF_PRESENT | MF_READWRITE;
}
MmPML4[0] = (ulong)(&MmPDP[0])| MF_PRESENT | MF_READWRITE;
MmLoadPML4((void *)MmPML4);
//DebugLog("\tPaging tables initialized at %p, %p\n", &MmPD, &MmPT);
//DebugLog("\tStack Guards at %p, %p\n", MmStackGuards[0], MmStackGuards[1]);
DebugLog("\tPage table size : %u MB\n", (lastDirectoryAddr - firstDirectoryAddr + phDirSize)/MB);
}
//
// Reloads the page tables
// Get a page from an address
//
void MmReloadPaging(void)
static pte_t *MmGetPageDescriptorFromVirtual(void *virtualAddr)
{
extern MemoryMap_t memoryMap;
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1));
for (volatile ulong i = 0; i < 512 * NB_4K; i++) {
// STACK GUARD PAGE
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.stackEndAddr) {
MmPT[i] = ((ulong)(i*KPAGESIZE));
MmStackGuards[0] = ((ulong)(i*KPAGESIZE));
continue;
}
// ENOMEM like
if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) {
break;
}
// STACK GARD PAGE
if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) {
MmPT[i] = ((ulong)(i*KPAGESIZE));
MmStackGuards[1] = ((ulong)(i*KPAGESIZE));
continue;
}
MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE;
if (virtAddrPage > MmVirtLastAddress) {
KeStartPanic("MmSetPage() Out of bound of the address space !");
}
for (volatile ulong i = 0; i < NB_4K; i++) {
MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE;
}
pdpe_t *pdp = (pdpe_t*)((ulong)MmPageMapLevel4[(virtAddrPage / ((ulong)KPAGESIZE * 0x8000000)) % 512] & ~(KPAGESIZE - 1));
//DebugLog("pdp\t: %p\n", pdp);
pde_t *pd = (pde_t*)( (ulong)pdp[(virtAddrPage / ((ulong)KPAGESIZE * 0x40000)) % 512] & ~(KPAGESIZE - 1));
//DebugLog("pd\t: %p\n", pd);
pte_t *pt = (pte_t*)( (ulong)pd[(virtAddrPage / ((ulong)KPAGESIZE * 0x200)) % 512] & ~(KPAGESIZE - 1));
//DebugLog("pt\t: %p\n", pt);
for (volatile ulong i = NB_4K; i < 512 * RAM_MAX; i++) {
// ENOMEM like
if ((ulong)(i* UPAGESIZE) > (ulong)phRamSize) {
break;
}
pte_t *page = &pt[(virtAddrPage / ((ulong)KPAGESIZE)) % 512];
//DebugLog("page (with flags): %p\n", page);
MmPD[i] = 0;
MmPD[i] = ((ulong)(i* UPAGESIZE)) | MF_PRESENT | MF_READWRITE | MF_HUGE;
}
for (volatile int i = 0; i < RAM_MAX; i++) {
MmPDP[i] = (ulong)(&MmPD[i*512])| MF_PRESENT | MF_READWRITE;
}
MmPML4[0] = (ulong)(&MmPDP[0])| MF_PRESENT | MF_READWRITE;
MmLoadPML4((void *)MmPML4);
DebugLog("\tPaging tables initialized at %p, %p\n", &MmPD, &MmPT);
DebugLog("\tStack Guards at %p, %p\n", MmStackGuards[0], MmStackGuards[1]);
return page;
}
//
// Translates a virtual address to its physical equivalent
//
void *MmTransVirtToPhyAddr(void* virtualAddr)
{
ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1));
pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
if (*page == (*page & ~(KPAGESIZE - 1))) {
return NULL;
}
return (void*)((*page & ~(KPAGESIZE - 1))+ ((ulong)virtualAddr - (ulong)virtAddrPage));
}
void *MmTransPhyToVirtAddr(void* physicalAddr)
{
ulong phyAddrPage = (ulong)physicalAddr & ( ~(KPAGESIZE - 1));
return (void*)( MmPhysicalPageTable[(ulong)physicalAddr
/ ((ulong)KPAGESIZE)
+ ((ulong)physicalAddr - phyAddrPage) ] );
}
//
// Add flags to a page
//
void MmSetPage(void* virtualAddr, ulong flags)
{
pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
*page |= flags;
KeFlushTlbSingle(*page);
}
//
// Remove flags of a page
//
void MmUnsetPage(void* virtualAddr, ulong flags)
{
pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
*page &= (~flags);
KeFlushTlbSingle(*page);
}
//
// Map a page in memory
//
void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags)
{
pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
*page = ((ulong)physicalAddr & ~(KPAGESIZE - 1)) | flags;
KeFlushTlbSingle(*page);
}
//
// Unmap a page in memory
//
void MmUnmapPage(void* virtualAddr)
{
pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
*page = 0;
KeFlushTlbSingle(*page);
}
//
// Kernel Page allocator
//
void *MmKAllocPageBlock(void *start) {
pte_t *startPage = MmGetPageDescriptorFromVirtual(start);
//for (ulong curPage = 0; curPage < )
return NULL;
}
//
// User page allocator
//
void *MmUAllocPageBlock(void *start) {
pte_t *startPage = MmGetPageDescriptorFromVirtual(start);
//for (ulong curPage = 0; curPage < )
return NULL;
}
//-----------
//
// Returns the rank of the Stack Guards
//
void *MmGetStackGuards(char rank)
{
return (void *)MmStackGuards[(int)rank];
}
// Returns an address corresponding to the PT rank
void *MmTranslateKPageToAddr(void *rank)
{
return (void *)MmPT[(ulong)rank];
}
//
// Page fault handler
//
static void PagingHandler(ISRFrame_t *regs)
{
ulong StackGuardOne = (ulong)MmGetStackGuards(0);
if (regs->cr2 >= StackGuardOne && (regs->rsp + 4*KB >= regs->cr2)) {
ulong StackGuardTwo = (ulong)MmGetStackGuards(1);
if ((regs->cr2 >= StackGuardOne) && (regs->cr2 <= StackGuardOne + KPAGESIZE) && (regs->rsp <= regs->cr2)) {
bprintf(BStdOut,
"\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Stack Underflow\n\n"
" Double Fault Error code : %#x (%b)\n"
" Page Fault Error code : %#x (%b)\n"
" Stack Guard bypassed : %#x",
VGA_COLOR_LIGHT_RED,
@ -182,19 +340,68 @@ static void PagingHandler(ISRFrame_t *regs)
regs->ErrorCode,
StackGuardOne
);
} else {
//XXX page fault
bprintf(BStdOut, "\n\n%CPANIC\n[ISR 0x%x] Irrecoverable Kernel Page Fault at %p\n\n"
" Error code : 0x%x (%b)",
} else if ((regs->cr2 >= StackGuardTwo) && (regs->cr2 <= StackGuardTwo + KPAGESIZE) && (regs->rsp >= regs->cr2)) {
bprintf(BStdOut,
"\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Stack Overflow\n\n"
" Page Fault Error code : %#x (%b)\n"
" Stack Guard bypassed : %#x",
VGA_COLOR_LIGHT_RED,
regs->ErrorCode,
regs->ErrorCode,
StackGuardTwo
);
} else if (regs->cr2 == 0) {
bprintf(BStdOut,
"\n\n%CPANIC\n[ISR 0x8] Null vector exception !\n\n"
" Page Fault Error code : %#x (%b)\n",
VGA_COLOR_LIGHT_RED,
regs->intNo,
regs->ErrorCode,
regs->ErrorCode
);
} else if (regs->cr2 >= MmVirtLastAddress || regs->cr2 <= 0) {
bprintf(BStdOut,
"\n\n%CPANIC\n[ISR 0x8] Out of bound of the address space at %p !\n\n"
" End of the address space : %p\n"
" Page Fault Error code : %#x (%b)\n",
VGA_COLOR_LIGHT_RED,
regs->cr2,
MmVirtLastAddress,
regs->ErrorCode,
regs->ErrorCode
);
} else {
//XXX page fault
bprintf(BStdOut, "\n\n%CPANIC\n[ISR 0x8] Irrecoverable Page Fault at %p\n\n"
" Error code : 0x%x (%b)",
VGA_COLOR_LIGHT_RED,
regs->cr2,
regs->ErrorCode,
regs->ErrorCode
);
}
bprintf(BStdOut, "\n Description : ");
if (regs->ErrorCode & PRESENT) {
bprintf(BStdOut, "Page-protection violation ");
} else {
bprintf(BStdOut, "Non present page ");
}
if (regs->ErrorCode & READWRITE) {
bprintf(BStdOut, "during write access ");
} else {
bprintf(BStdOut, "during read access ");
}
if (regs->ErrorCode & (1 << 3))
bprintf(BStdOut, "from userspace ");
if (regs->ErrorCode & (1 << 4))
bprintf(BStdOut, "after instruction fetching ");
KeBrkDumpRegisters(regs);
BStdOut->flusher(BStdOut);

View File

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

View File

@ -55,6 +55,19 @@ error_t CmdArgs(int argc, char **argv, char *cmdline)
return EOK;
}
error_t CmdAtoi(int argc, char **argv, char *cmdline)
{
int i;
KernLog("cmdline: '%s'\nargc: %d\n", cmdline, argc);
for (i = 0; i < argc; i++) {
KernLog("argv[%d]: '%u'\n", i, atoi(argv[i]));
}
return EOK;
}
error_t CmdDumpATASect(int argc, char **argv, char *cmdline)
{
char sector[512] = {0};
@ -96,6 +109,42 @@ error_t CmdDumpATASect(int argc, char **argv, char *cmdline)
return EOK;
}
error_t CmdDumpMem(int argc, char **argv, char *cmdline)
{
char sector[1024] = {0};
char *address = (char*)strtoul(argv[1], NULL, 16);
int nb = 1; //atoi(argv[2]);
int x = 0;
int step = 16;
KernLog("Address begin: %p\n", address);
for (int i = 0; i < 1024*nb; i++) {
sector[i] = *address++;
}
while(x < 1024*nb) {
KernLog("%C", shcol);
for (int i = 0; i < step; i++) {
KernLog("%02x ", (uchar)sector[i+x]);
}
KernLog(" %C ", VGA_COLOR_LIGHT_BLUE);
for (int i = 0; i < step; i++) {
if (isprint(sector[i+x]))
KernLog("%c",
sector[i+x]
);
else
KernLog("%c", 0);
}
KernLog("\n");
x += step;
}
KernLog("\n\n");
return EOK;
}
error_t CmdFloatDiv(int argc, char **argv, char *cmdline)
{
double a = (double)atoi(argv[1]);
@ -140,22 +189,79 @@ error_t CmdHelpTest(int argc, char **argv, char *cmdline)
return EOK;
}
error_t CmdPF(int argc, char **argv, char *cmdline)
error_t CmdPageTranslateVirtToPhy(int argc, char **argv, char *cmdline)
{
char *address = (void*)(ulong)atoi(argv[1]);
void *address = (void*)atoul(argv[1]);
KernLog("Provoking Page Fault at %#x\n", address);
if (!(void*)strtoul(argv[1], NULL, 16)) {
KernLog("No argument : translating the userspace address\n");
address = (void *)0x80000000;
}
*address = 1;
void *translation = MmTransVirtToPhyAddr(address);
KernLog("No page fault : address was valid/present\n");
KernLog("Translation of %p is %p\n", address, translation);
return EOK;
}
enum
{
PRESENT = 1 << 0,
READWRITE = 1 << 1,
USERMODE = 1 << 2,
WRITETHR = 1 << 3,
CACHEDIS = 1 << 4,
ACCESSED = 1 << 5,
DIRTY = 1 << 6,
HUGE = 1 << 7,
NX = 1UL << 63
};
error_t CmdPageMap(int argc, char **argv, char *cmdline)
{
void *virtual = (void*)strtoul(argv[1], NULL, 16);
void *physical = (void*)strtoul(argv[2], NULL, 16);
MmMapPage(virtual, physical, PRESENT | READWRITE);
return EOK;
}
error_t CmdReloadPage(int argc, char **argv, char *cmdline)
error_t CmdPageUnmap(int argc, char **argv, char *cmdline)
{
MmReloadPaging();
void *virtual = (void*)strtoul(argv[1], NULL, 16);
MmUnmapPage(virtual);
return EOK;
}
error_t CmdPageTranslatePhyToVirt(int argc, char **argv, char *cmdline)
{
void *address = (void*)strtoul(argv[1], NULL, 16);
/* if (!(void*)atoul(argv[1])) { */
/* address = (ulong *)0x80000000; */
/* } */
void *translation = MmTransPhyToVirtAddr(address);
KernLog("Translation of %p is %p\n", address, translation);
return EOK;
}
error_t CmdPF(int argc, char **argv, char *cmdline)
{
ulong *address = (ulong*)(ulong)strtoul(argv[1], NULL, 16);
KernLog("Provoking Page Fault at %#x\n", address);
KernLog("It contained %#x\n", *address);
*address = 1;
KernLog("Now it contains %#x\n", *address);
KernLog("No page fault : address was valid/present\n");
return EOK;
}
@ -199,11 +305,18 @@ error_t CmdTimerTest(int argc, char **argv, char *cmdline)
static Command_t testcmdtable[] =
{
{ "args", CmdArgs, "Print command line" },
{ "atoi", CmdAtoi, "Print command line atoised" },
{ "dmpsec", CmdDumpATASect, "Dump an ATA sector on screen" },
{ "dmp", CmdDumpMem, "Dump 1MB of memory starting from addr"},
{ "help", CmdHelpTest, "Show this message" },
{ "div", CmdFloatDiv, "Float div. Usage : div a b. Returns a/b"},
{ "transvtp", CmdPageTranslateVirtToPhy, "Translate a virtual to"
" physical address (paging)"},
{ "transptv", CmdPageTranslatePhyToVirt, "Translate a physical to"
" virtual address (paging)"},
{ "pmap", CmdPageMap, "Map a page to given physical addr" },
{ "punmap", CmdPageUnmap, "Unmap a page" },
{ "pf", CmdPF, "Provoke a PF. Usage: pfault <address>"},
{ "rpag", CmdReloadPage, "Reload the pages directory" },
{ "shell", CmdShell, "Start a new shell (nested)", },
{ "stkov", CmdStackOverflow, "Provoke a stack overflow" },
{ "stkun", CmdStackUnderflow, "Provoke a stack underflow" },