diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index dc00a9d..0c50e6d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -110,6 +110,21 @@ db 10010010b db 11001111b db 0 + +.userCode: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +.userData: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 .end: dw .end - gdt32 - 1 dd gdt32 diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index dc00a9d..0c50e6d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -110,6 +110,21 @@ db 10010010b db 11001111b db 0 + +.userCode: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +.userData: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 .end: dw .end - gdt32 - 1 dd gdt32 diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5731bda..9f875fa 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -37,5 +37,9 @@ void *destinationAddress); extern void *getPhysicalAddressKernel(void *address); +extern void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, + void *address); +extern uint32_t findPage(PagingInfo *info); +extern void *mapTemporary(void *address); #endif diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index dc00a9d..0c50e6d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -110,6 +110,21 @@ db 10010010b db 11001111b db 0 + +.userCode: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +.userData: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 .end: dw .end - gdt32 - 1 dd gdt32 diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5731bda..9f875fa 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -37,5 +37,9 @@ void *destinationAddress); extern void *getPhysicalAddressKernel(void *address); +extern void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, + void *address); +extern uint32_t findPage(PagingInfo *info); +extern void *mapTemporary(void *address); #endif diff --git a/src/kernel/include/syscall.h b/src/kernel/include/syscall.h new file mode 100644 index 0000000..3df25fa --- /dev/null +++ b/src/kernel/include/syscall.h @@ -0,0 +1,6 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +extern void setupSyscalls(); + +#endif diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index dc00a9d..0c50e6d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -110,6 +110,21 @@ db 10010010b db 11001111b db 0 + +.userCode: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +.userData: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 .end: dw .end - gdt32 - 1 dd gdt32 diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5731bda..9f875fa 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -37,5 +37,9 @@ void *destinationAddress); extern void *getPhysicalAddressKernel(void *address); +extern void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, + void *address); +extern uint32_t findPage(PagingInfo *info); +extern void *mapTemporary(void *address); #endif diff --git a/src/kernel/include/syscall.h b/src/kernel/include/syscall.h new file mode 100644 index 0000000..3df25fa --- /dev/null +++ b/src/kernel/include/syscall.h @@ -0,0 +1,6 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +extern void setupSyscalls(); + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index f5879d0..fd079cd 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -2,12 +2,14 @@ #include #include #include +#include void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapMultiplePhysicalPages(multibootInfo, 4); uint32_t tarSize = 0; void *initrd = findInitrd(address, &tarSize); + setupSyscalls(); void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); loadElf(loaderProgram); asm("mov %%eax, %0" ::"r"(0xB105F00D)); diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index dc00a9d..0c50e6d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -110,6 +110,21 @@ db 10010010b db 11001111b db 0 + +.userCode: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +.userData: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 .end: dw .end - gdt32 - 1 dd gdt32 diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5731bda..9f875fa 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -37,5 +37,9 @@ void *destinationAddress); extern void *getPhysicalAddressKernel(void *address); +extern void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, + void *address); +extern uint32_t findPage(PagingInfo *info); +extern void *mapTemporary(void *address); #endif diff --git a/src/kernel/include/syscall.h b/src/kernel/include/syscall.h new file mode 100644 index 0000000..3df25fa --- /dev/null +++ b/src/kernel/include/syscall.h @@ -0,0 +1,6 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +extern void setupSyscalls(); + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index f5879d0..fd079cd 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -2,12 +2,14 @@ #include #include #include +#include void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapMultiplePhysicalPages(multibootInfo, 4); uint32_t tarSize = 0; void *initrd = findInitrd(address, &tarSize); + setupSyscalls(); void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); loadElf(loaderProgram); asm("mov %%eax, %0" ::"r"(0xB105F00D)); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 3bd35e9..cc9c13d 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -36,22 +36,20 @@ return temporaryPage; } -void *getPhysicalAddress(void *address, PageDirectoryEntry *pageDirectory) { +void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, void *address) { VirtualAddress *virtual = (void *)&address; - uint32_t pageTableLocation = + uint32_t pageTableId = pageDirectory[virtual->pageDirectoryIndex].pageTableID; - PageTableEntry *pageTable = PTR(pageTableLocation << 12); - pageTable = mapTemporary(pageTable); + PageTableEntry *pageTable = mapTemporary(PTR(pageTableId << 12)); uint32_t pageBase = pageTable[virtual->pageTableIndex].targetAddress; return PTR(pageBase << 12 | virtual->pageOffset); } void *getPhysicalAddressKernel(void *address) { - return getPhysicalAddress(address, kernelVirtualPages->pageDirectory); + return getPhysicalAddress(kernelVirtualPages->pageDirectory, address); } -uint32_t findPage(PagingInfo *info); -void mapPage(PagingInfo *info, void *physical, void *virtual); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -129,7 +127,7 @@ } for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, PTR((physicalPageStart + i) << 12), - PTR((virtualPageStart + i) << 12)); + PTR((virtualPageStart + i) << 12), false); } return PTR((virtualPageStart << 12) + (U32(address) & 0xFFF)); } @@ -138,7 +136,7 @@ return kernelMapMultiplePhysicalPages(address, 1); } -void mapPage(PagingInfo *info, void *physical, void *virtual) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -149,6 +147,7 @@ directory[address->pageDirectoryIndex].pageTableID = newPageTable; directory[address->pageDirectoryIndex].present = 1; directory[address->pageDirectoryIndex].writable = 1; + directory[address->pageDirectoryIndex].belongsToUserProcess |= userPage; } void *pageTablePhysical = PTR(directory[address->pageDirectoryIndex].pageTableID << 12); @@ -157,6 +156,7 @@ pageTable[address->pageTableIndex].targetAddress = U32(physical) >> 12; pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(U32(virtual) >> 12); } @@ -165,14 +165,14 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12)); + mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12), false); return PTR(virtual << 12); } void sharePage(PagingInfo *destination, void *sourceAddress, void *destinationAddress) { - PagingInfo *source = kernelVirtualPages; + PagingInfo *sourcePagingInfo = kernelVirtualPages; void *physicalSource = - getPhysicalAddress(sourceAddress, source->pageDirectory); - mapPage(destination, physicalSource, destinationAddress); + getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); + mapPage(destination, physicalSource, destinationAddress, true); } diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index dc00a9d..0c50e6d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -110,6 +110,21 @@ db 10010010b db 11001111b db 0 + +.userCode: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +.userData: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 .end: dw .end - gdt32 - 1 dd gdt32 diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5731bda..9f875fa 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -37,5 +37,9 @@ void *destinationAddress); extern void *getPhysicalAddressKernel(void *address); +extern void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, + void *address); +extern uint32_t findPage(PagingInfo *info); +extern void *mapTemporary(void *address); #endif diff --git a/src/kernel/include/syscall.h b/src/kernel/include/syscall.h new file mode 100644 index 0000000..3df25fa --- /dev/null +++ b/src/kernel/include/syscall.h @@ -0,0 +1,6 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +extern void setupSyscalls(); + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index f5879d0..fd079cd 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -2,12 +2,14 @@ #include #include #include +#include void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapMultiplePhysicalPages(multibootInfo, 4); uint32_t tarSize = 0; void *initrd = findInitrd(address, &tarSize); + setupSyscalls(); void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); loadElf(loaderProgram); asm("mov %%eax, %0" ::"r"(0xB105F00D)); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 3bd35e9..cc9c13d 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -36,22 +36,20 @@ return temporaryPage; } -void *getPhysicalAddress(void *address, PageDirectoryEntry *pageDirectory) { +void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, void *address) { VirtualAddress *virtual = (void *)&address; - uint32_t pageTableLocation = + uint32_t pageTableId = pageDirectory[virtual->pageDirectoryIndex].pageTableID; - PageTableEntry *pageTable = PTR(pageTableLocation << 12); - pageTable = mapTemporary(pageTable); + PageTableEntry *pageTable = mapTemporary(PTR(pageTableId << 12)); uint32_t pageBase = pageTable[virtual->pageTableIndex].targetAddress; return PTR(pageBase << 12 | virtual->pageOffset); } void *getPhysicalAddressKernel(void *address) { - return getPhysicalAddress(address, kernelVirtualPages->pageDirectory); + return getPhysicalAddress(kernelVirtualPages->pageDirectory, address); } -uint32_t findPage(PagingInfo *info); -void mapPage(PagingInfo *info, void *physical, void *virtual); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -129,7 +127,7 @@ } for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, PTR((physicalPageStart + i) << 12), - PTR((virtualPageStart + i) << 12)); + PTR((virtualPageStart + i) << 12), false); } return PTR((virtualPageStart << 12) + (U32(address) & 0xFFF)); } @@ -138,7 +136,7 @@ return kernelMapMultiplePhysicalPages(address, 1); } -void mapPage(PagingInfo *info, void *physical, void *virtual) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -149,6 +147,7 @@ directory[address->pageDirectoryIndex].pageTableID = newPageTable; directory[address->pageDirectoryIndex].present = 1; directory[address->pageDirectoryIndex].writable = 1; + directory[address->pageDirectoryIndex].belongsToUserProcess |= userPage; } void *pageTablePhysical = PTR(directory[address->pageDirectoryIndex].pageTableID << 12); @@ -157,6 +156,7 @@ pageTable[address->pageTableIndex].targetAddress = U32(physical) >> 12; pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(U32(virtual) >> 12); } @@ -165,14 +165,14 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12)); + mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12), false); return PTR(virtual << 12); } void sharePage(PagingInfo *destination, void *sourceAddress, void *destinationAddress) { - PagingInfo *source = kernelVirtualPages; + PagingInfo *sourcePagingInfo = kernelVirtualPages; void *physicalSource = - getPhysicalAddress(sourceAddress, source->pageDirectory); - mapPage(destination, physicalSource, destinationAddress); + getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); + mapPage(destination, physicalSource, destinationAddress, true); } diff --git a/src/kernel/service/service.asm b/src/kernel/service/service.asm new file mode 100644 index 0000000..7ffdba1 --- /dev/null +++ b/src/kernel/service/service.asm @@ -0,0 +1,28 @@ +section .sharedFunctions + +global runFunction +global runEnd + +extern currentCr3 +extern returnStack +extern currentEsp +extern mainFunction + +runFunction: + mov eax, esp + mov [returnStack], eax + mov ecx, [currentEsp] + add ecx, 0xFFC + mov edx, [mainFunction] + mov eax, [currentCr3] + mov cr3, eax + sysexit +runEnd: + ; todo: make a sysenter call to go back to ring 0, writing to cr3 is not possible in ring 3 + jmp $ + mov eax, 0x500000 + mov cr3, eax + mov eax, [returnStack] + mov esp, eax + jmp $ + ret diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index dc00a9d..0c50e6d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -110,6 +110,21 @@ db 10010010b db 11001111b db 0 + +.userCode: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +.userData: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 .end: dw .end - gdt32 - 1 dd gdt32 diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5731bda..9f875fa 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -37,5 +37,9 @@ void *destinationAddress); extern void *getPhysicalAddressKernel(void *address); +extern void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, + void *address); +extern uint32_t findPage(PagingInfo *info); +extern void *mapTemporary(void *address); #endif diff --git a/src/kernel/include/syscall.h b/src/kernel/include/syscall.h new file mode 100644 index 0000000..3df25fa --- /dev/null +++ b/src/kernel/include/syscall.h @@ -0,0 +1,6 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +extern void setupSyscalls(); + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index f5879d0..fd079cd 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -2,12 +2,14 @@ #include #include #include +#include void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapMultiplePhysicalPages(multibootInfo, 4); uint32_t tarSize = 0; void *initrd = findInitrd(address, &tarSize); + setupSyscalls(); void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); loadElf(loaderProgram); asm("mov %%eax, %0" ::"r"(0xB105F00D)); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 3bd35e9..cc9c13d 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -36,22 +36,20 @@ return temporaryPage; } -void *getPhysicalAddress(void *address, PageDirectoryEntry *pageDirectory) { +void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, void *address) { VirtualAddress *virtual = (void *)&address; - uint32_t pageTableLocation = + uint32_t pageTableId = pageDirectory[virtual->pageDirectoryIndex].pageTableID; - PageTableEntry *pageTable = PTR(pageTableLocation << 12); - pageTable = mapTemporary(pageTable); + PageTableEntry *pageTable = mapTemporary(PTR(pageTableId << 12)); uint32_t pageBase = pageTable[virtual->pageTableIndex].targetAddress; return PTR(pageBase << 12 | virtual->pageOffset); } void *getPhysicalAddressKernel(void *address) { - return getPhysicalAddress(address, kernelVirtualPages->pageDirectory); + return getPhysicalAddress(kernelVirtualPages->pageDirectory, address); } -uint32_t findPage(PagingInfo *info); -void mapPage(PagingInfo *info, void *physical, void *virtual); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -129,7 +127,7 @@ } for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, PTR((physicalPageStart + i) << 12), - PTR((virtualPageStart + i) << 12)); + PTR((virtualPageStart + i) << 12), false); } return PTR((virtualPageStart << 12) + (U32(address) & 0xFFF)); } @@ -138,7 +136,7 @@ return kernelMapMultiplePhysicalPages(address, 1); } -void mapPage(PagingInfo *info, void *physical, void *virtual) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -149,6 +147,7 @@ directory[address->pageDirectoryIndex].pageTableID = newPageTable; directory[address->pageDirectoryIndex].present = 1; directory[address->pageDirectoryIndex].writable = 1; + directory[address->pageDirectoryIndex].belongsToUserProcess |= userPage; } void *pageTablePhysical = PTR(directory[address->pageDirectoryIndex].pageTableID << 12); @@ -157,6 +156,7 @@ pageTable[address->pageTableIndex].targetAddress = U32(physical) >> 12; pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(U32(virtual) >> 12); } @@ -165,14 +165,14 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12)); + mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12), false); return PTR(virtual << 12); } void sharePage(PagingInfo *destination, void *sourceAddress, void *destinationAddress) { - PagingInfo *source = kernelVirtualPages; + PagingInfo *sourcePagingInfo = kernelVirtualPages; void *physicalSource = - getPhysicalAddress(sourceAddress, source->pageDirectory); - mapPage(destination, physicalSource, destinationAddress); + getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); + mapPage(destination, physicalSource, destinationAddress, true); } diff --git a/src/kernel/service/service.asm b/src/kernel/service/service.asm new file mode 100644 index 0000000..7ffdba1 --- /dev/null +++ b/src/kernel/service/service.asm @@ -0,0 +1,28 @@ +section .sharedFunctions + +global runFunction +global runEnd + +extern currentCr3 +extern returnStack +extern currentEsp +extern mainFunction + +runFunction: + mov eax, esp + mov [returnStack], eax + mov ecx, [currentEsp] + add ecx, 0xFFC + mov edx, [mainFunction] + mov eax, [currentCr3] + mov cr3, eax + sysexit +runEnd: + ; todo: make a sysenter call to go back to ring 0, writing to cr3 is not possible in ring 3 + jmp $ + mov eax, 0x500000 + mov cr3, eax + mov eax, [returnStack] + mov esp, eax + jmp $ + ret diff --git a/src/kernel/service/services.c b/src/kernel/service/services.c index 189b8b8..dc117b0 100644 --- a/src/kernel/service/services.c +++ b/src/kernel/service/services.c @@ -16,32 +16,18 @@ void *mainFunction = NULL; void *returnStack = 0; +extern void *functionsStart; +extern void(runFunction)(); +extern void(runEnd)(); + void run(Service *service, void *main) { currentEsp = malloc(0x1000); memset(currentEsp, 0, 0x1000); - ((void **)currentEsp)[0x3FF] = &&runEnd; + ((void **)currentEsp)[0x3FF] = runEnd; sharePage(&service->pagingInfo, currentEsp, currentEsp); currentCr3 = getPhysicalAddressKernel(service->pagingInfo.pageDirectory); mainFunction = main; - asm(".intel_syntax noprefix\n" - "mov eax, [currentCr3]\n" - "mov cr3, eax\n" - "mov eax, esp\n" - "mov [returnStack], eax\n" - "mov eax, [currentEsp]\n" - "add eax, 0xFFC\n" - "mov esp, eax\n" - "push [mainFunction]\n" - "ret\n" - ".att_syntax"); -runEnd: - currentCr3 = PTR(0x500000); - asm(".intel_syntax noprefix\n" - "mov eax, [returnStack]\n" - "mov esp, eax\n" - "mov eax, 0x500000\n" - "mov cr3, eax\n" - ".att_syntax"); + asm("jmp runFunction"); } void loadElf(void *elfStart) { @@ -53,15 +39,14 @@ PagingInfo *paging = &loaderService.pagingInfo; memset(paging, 0, sizeof(PagingInfo)); paging->pageDirectory = malloc(0x1000); - paging->pageDirectory[0x3FF].pageTableID = - U32(getPhysicalAddressKernel(kernelCodePageTable)) >> 12; - paging->pageDirectory[0x3FF].present = 1; - paging->pageDirectory[0x3FF].writable = 1; - void *data; + // todo: make this unwritable! + // todo: use functionsStart as the reference + sharePage(paging, PTR(0xFFC02000), + PTR(0xFFC02000)); // functionsStart, functionsStart); for (uint32_t i = 0; i < header->programHeaderEntryCount; i++) { for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { - data = malloc(0x1000); + void *data = malloc(0x1000); memset(data, 0, 0x1000); memcpy(elfStart + programHeader->dataOffset, data, MIN(0x1000, programHeader->segmentFileSize - page)); diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index dc00a9d..0c50e6d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -110,6 +110,21 @@ db 10010010b db 11001111b db 0 + +.userCode: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +.userData: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 .end: dw .end - gdt32 - 1 dd gdt32 diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5731bda..9f875fa 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -37,5 +37,9 @@ void *destinationAddress); extern void *getPhysicalAddressKernel(void *address); +extern void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, + void *address); +extern uint32_t findPage(PagingInfo *info); +extern void *mapTemporary(void *address); #endif diff --git a/src/kernel/include/syscall.h b/src/kernel/include/syscall.h new file mode 100644 index 0000000..3df25fa --- /dev/null +++ b/src/kernel/include/syscall.h @@ -0,0 +1,6 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +extern void setupSyscalls(); + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index f5879d0..fd079cd 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -2,12 +2,14 @@ #include #include #include +#include void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapMultiplePhysicalPages(multibootInfo, 4); uint32_t tarSize = 0; void *initrd = findInitrd(address, &tarSize); + setupSyscalls(); void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); loadElf(loaderProgram); asm("mov %%eax, %0" ::"r"(0xB105F00D)); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 3bd35e9..cc9c13d 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -36,22 +36,20 @@ return temporaryPage; } -void *getPhysicalAddress(void *address, PageDirectoryEntry *pageDirectory) { +void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, void *address) { VirtualAddress *virtual = (void *)&address; - uint32_t pageTableLocation = + uint32_t pageTableId = pageDirectory[virtual->pageDirectoryIndex].pageTableID; - PageTableEntry *pageTable = PTR(pageTableLocation << 12); - pageTable = mapTemporary(pageTable); + PageTableEntry *pageTable = mapTemporary(PTR(pageTableId << 12)); uint32_t pageBase = pageTable[virtual->pageTableIndex].targetAddress; return PTR(pageBase << 12 | virtual->pageOffset); } void *getPhysicalAddressKernel(void *address) { - return getPhysicalAddress(address, kernelVirtualPages->pageDirectory); + return getPhysicalAddress(kernelVirtualPages->pageDirectory, address); } -uint32_t findPage(PagingInfo *info); -void mapPage(PagingInfo *info, void *physical, void *virtual); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -129,7 +127,7 @@ } for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, PTR((physicalPageStart + i) << 12), - PTR((virtualPageStart + i) << 12)); + PTR((virtualPageStart + i) << 12), false); } return PTR((virtualPageStart << 12) + (U32(address) & 0xFFF)); } @@ -138,7 +136,7 @@ return kernelMapMultiplePhysicalPages(address, 1); } -void mapPage(PagingInfo *info, void *physical, void *virtual) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -149,6 +147,7 @@ directory[address->pageDirectoryIndex].pageTableID = newPageTable; directory[address->pageDirectoryIndex].present = 1; directory[address->pageDirectoryIndex].writable = 1; + directory[address->pageDirectoryIndex].belongsToUserProcess |= userPage; } void *pageTablePhysical = PTR(directory[address->pageDirectoryIndex].pageTableID << 12); @@ -157,6 +156,7 @@ pageTable[address->pageTableIndex].targetAddress = U32(physical) >> 12; pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(U32(virtual) >> 12); } @@ -165,14 +165,14 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12)); + mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12), false); return PTR(virtual << 12); } void sharePage(PagingInfo *destination, void *sourceAddress, void *destinationAddress) { - PagingInfo *source = kernelVirtualPages; + PagingInfo *sourcePagingInfo = kernelVirtualPages; void *physicalSource = - getPhysicalAddress(sourceAddress, source->pageDirectory); - mapPage(destination, physicalSource, destinationAddress); + getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); + mapPage(destination, physicalSource, destinationAddress, true); } diff --git a/src/kernel/service/service.asm b/src/kernel/service/service.asm new file mode 100644 index 0000000..7ffdba1 --- /dev/null +++ b/src/kernel/service/service.asm @@ -0,0 +1,28 @@ +section .sharedFunctions + +global runFunction +global runEnd + +extern currentCr3 +extern returnStack +extern currentEsp +extern mainFunction + +runFunction: + mov eax, esp + mov [returnStack], eax + mov ecx, [currentEsp] + add ecx, 0xFFC + mov edx, [mainFunction] + mov eax, [currentCr3] + mov cr3, eax + sysexit +runEnd: + ; todo: make a sysenter call to go back to ring 0, writing to cr3 is not possible in ring 3 + jmp $ + mov eax, 0x500000 + mov cr3, eax + mov eax, [returnStack] + mov esp, eax + jmp $ + ret diff --git a/src/kernel/service/services.c b/src/kernel/service/services.c index 189b8b8..dc117b0 100644 --- a/src/kernel/service/services.c +++ b/src/kernel/service/services.c @@ -16,32 +16,18 @@ void *mainFunction = NULL; void *returnStack = 0; +extern void *functionsStart; +extern void(runFunction)(); +extern void(runEnd)(); + void run(Service *service, void *main) { currentEsp = malloc(0x1000); memset(currentEsp, 0, 0x1000); - ((void **)currentEsp)[0x3FF] = &&runEnd; + ((void **)currentEsp)[0x3FF] = runEnd; sharePage(&service->pagingInfo, currentEsp, currentEsp); currentCr3 = getPhysicalAddressKernel(service->pagingInfo.pageDirectory); mainFunction = main; - asm(".intel_syntax noprefix\n" - "mov eax, [currentCr3]\n" - "mov cr3, eax\n" - "mov eax, esp\n" - "mov [returnStack], eax\n" - "mov eax, [currentEsp]\n" - "add eax, 0xFFC\n" - "mov esp, eax\n" - "push [mainFunction]\n" - "ret\n" - ".att_syntax"); -runEnd: - currentCr3 = PTR(0x500000); - asm(".intel_syntax noprefix\n" - "mov eax, [returnStack]\n" - "mov esp, eax\n" - "mov eax, 0x500000\n" - "mov cr3, eax\n" - ".att_syntax"); + asm("jmp runFunction"); } void loadElf(void *elfStart) { @@ -53,15 +39,14 @@ PagingInfo *paging = &loaderService.pagingInfo; memset(paging, 0, sizeof(PagingInfo)); paging->pageDirectory = malloc(0x1000); - paging->pageDirectory[0x3FF].pageTableID = - U32(getPhysicalAddressKernel(kernelCodePageTable)) >> 12; - paging->pageDirectory[0x3FF].present = 1; - paging->pageDirectory[0x3FF].writable = 1; - void *data; + // todo: make this unwritable! + // todo: use functionsStart as the reference + sharePage(paging, PTR(0xFFC02000), + PTR(0xFFC02000)); // functionsStart, functionsStart); for (uint32_t i = 0; i < header->programHeaderEntryCount; i++) { for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { - data = malloc(0x1000); + void *data = malloc(0x1000); memset(data, 0, 0x1000); memcpy(elfStart + programHeader->dataOffset, data, MIN(0x1000, programHeader->segmentFileSize - page)); diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c new file mode 100644 index 0000000..2178ffb --- /dev/null +++ b/src/kernel/syscalls/syscall.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +void wrmsr(uint32_t msr, uint32_t low, uint32_t high) { + asm("wrmsr" ::"a"(low), "d"(high), "c"(msr)); +} + +void writeMsrRegister(uint32_t reg, void *value) { + wrmsr(reg, U32(value), + 0); // when transitioning to 64 bit: U32(value) >> 32); +} + +void *handleSyscall(void *cr3, Syscall *callData) { + void *pageDirectory = mapTemporary(cr3); + void *dataPhysical = getPhysicalAddress(pageDirectory, callData); + Syscall *data = kernelMapPhysical(dataPhysical); + switch (data->id) { + case SYS_REGISTER_FUNCTION: + + break; + } + return data; +} + +extern void(syscallStub)(); +void *syscallStubPtr = syscallStub; +void *syscallStubPointer = &syscallStubPtr; + +void setupSyscalls() { + writeMsrRegister(0x174, PTR(0x08)); // code segment register + writeMsrRegister(0x175, malloc(0x1000) + 0x1000); // hadler stack + writeMsrRegister(0x176, syscallStubPtr); // the handler + return; +} diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index dc00a9d..0c50e6d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -110,6 +110,21 @@ db 10010010b db 11001111b db 0 + +.userCode: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +.userData: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 .end: dw .end - gdt32 - 1 dd gdt32 diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5731bda..9f875fa 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -37,5 +37,9 @@ void *destinationAddress); extern void *getPhysicalAddressKernel(void *address); +extern void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, + void *address); +extern uint32_t findPage(PagingInfo *info); +extern void *mapTemporary(void *address); #endif diff --git a/src/kernel/include/syscall.h b/src/kernel/include/syscall.h new file mode 100644 index 0000000..3df25fa --- /dev/null +++ b/src/kernel/include/syscall.h @@ -0,0 +1,6 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +extern void setupSyscalls(); + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index f5879d0..fd079cd 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -2,12 +2,14 @@ #include #include #include +#include void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapMultiplePhysicalPages(multibootInfo, 4); uint32_t tarSize = 0; void *initrd = findInitrd(address, &tarSize); + setupSyscalls(); void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); loadElf(loaderProgram); asm("mov %%eax, %0" ::"r"(0xB105F00D)); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 3bd35e9..cc9c13d 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -36,22 +36,20 @@ return temporaryPage; } -void *getPhysicalAddress(void *address, PageDirectoryEntry *pageDirectory) { +void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, void *address) { VirtualAddress *virtual = (void *)&address; - uint32_t pageTableLocation = + uint32_t pageTableId = pageDirectory[virtual->pageDirectoryIndex].pageTableID; - PageTableEntry *pageTable = PTR(pageTableLocation << 12); - pageTable = mapTemporary(pageTable); + PageTableEntry *pageTable = mapTemporary(PTR(pageTableId << 12)); uint32_t pageBase = pageTable[virtual->pageTableIndex].targetAddress; return PTR(pageBase << 12 | virtual->pageOffset); } void *getPhysicalAddressKernel(void *address) { - return getPhysicalAddress(address, kernelVirtualPages->pageDirectory); + return getPhysicalAddress(kernelVirtualPages->pageDirectory, address); } -uint32_t findPage(PagingInfo *info); -void mapPage(PagingInfo *info, void *physical, void *virtual); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -129,7 +127,7 @@ } for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, PTR((physicalPageStart + i) << 12), - PTR((virtualPageStart + i) << 12)); + PTR((virtualPageStart + i) << 12), false); } return PTR((virtualPageStart << 12) + (U32(address) & 0xFFF)); } @@ -138,7 +136,7 @@ return kernelMapMultiplePhysicalPages(address, 1); } -void mapPage(PagingInfo *info, void *physical, void *virtual) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -149,6 +147,7 @@ directory[address->pageDirectoryIndex].pageTableID = newPageTable; directory[address->pageDirectoryIndex].present = 1; directory[address->pageDirectoryIndex].writable = 1; + directory[address->pageDirectoryIndex].belongsToUserProcess |= userPage; } void *pageTablePhysical = PTR(directory[address->pageDirectoryIndex].pageTableID << 12); @@ -157,6 +156,7 @@ pageTable[address->pageTableIndex].targetAddress = U32(physical) >> 12; pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(U32(virtual) >> 12); } @@ -165,14 +165,14 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12)); + mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12), false); return PTR(virtual << 12); } void sharePage(PagingInfo *destination, void *sourceAddress, void *destinationAddress) { - PagingInfo *source = kernelVirtualPages; + PagingInfo *sourcePagingInfo = kernelVirtualPages; void *physicalSource = - getPhysicalAddress(sourceAddress, source->pageDirectory); - mapPage(destination, physicalSource, destinationAddress); + getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); + mapPage(destination, physicalSource, destinationAddress, true); } diff --git a/src/kernel/service/service.asm b/src/kernel/service/service.asm new file mode 100644 index 0000000..7ffdba1 --- /dev/null +++ b/src/kernel/service/service.asm @@ -0,0 +1,28 @@ +section .sharedFunctions + +global runFunction +global runEnd + +extern currentCr3 +extern returnStack +extern currentEsp +extern mainFunction + +runFunction: + mov eax, esp + mov [returnStack], eax + mov ecx, [currentEsp] + add ecx, 0xFFC + mov edx, [mainFunction] + mov eax, [currentCr3] + mov cr3, eax + sysexit +runEnd: + ; todo: make a sysenter call to go back to ring 0, writing to cr3 is not possible in ring 3 + jmp $ + mov eax, 0x500000 + mov cr3, eax + mov eax, [returnStack] + mov esp, eax + jmp $ + ret diff --git a/src/kernel/service/services.c b/src/kernel/service/services.c index 189b8b8..dc117b0 100644 --- a/src/kernel/service/services.c +++ b/src/kernel/service/services.c @@ -16,32 +16,18 @@ void *mainFunction = NULL; void *returnStack = 0; +extern void *functionsStart; +extern void(runFunction)(); +extern void(runEnd)(); + void run(Service *service, void *main) { currentEsp = malloc(0x1000); memset(currentEsp, 0, 0x1000); - ((void **)currentEsp)[0x3FF] = &&runEnd; + ((void **)currentEsp)[0x3FF] = runEnd; sharePage(&service->pagingInfo, currentEsp, currentEsp); currentCr3 = getPhysicalAddressKernel(service->pagingInfo.pageDirectory); mainFunction = main; - asm(".intel_syntax noprefix\n" - "mov eax, [currentCr3]\n" - "mov cr3, eax\n" - "mov eax, esp\n" - "mov [returnStack], eax\n" - "mov eax, [currentEsp]\n" - "add eax, 0xFFC\n" - "mov esp, eax\n" - "push [mainFunction]\n" - "ret\n" - ".att_syntax"); -runEnd: - currentCr3 = PTR(0x500000); - asm(".intel_syntax noprefix\n" - "mov eax, [returnStack]\n" - "mov esp, eax\n" - "mov eax, 0x500000\n" - "mov cr3, eax\n" - ".att_syntax"); + asm("jmp runFunction"); } void loadElf(void *elfStart) { @@ -53,15 +39,14 @@ PagingInfo *paging = &loaderService.pagingInfo; memset(paging, 0, sizeof(PagingInfo)); paging->pageDirectory = malloc(0x1000); - paging->pageDirectory[0x3FF].pageTableID = - U32(getPhysicalAddressKernel(kernelCodePageTable)) >> 12; - paging->pageDirectory[0x3FF].present = 1; - paging->pageDirectory[0x3FF].writable = 1; - void *data; + // todo: make this unwritable! + // todo: use functionsStart as the reference + sharePage(paging, PTR(0xFFC02000), + PTR(0xFFC02000)); // functionsStart, functionsStart); for (uint32_t i = 0; i < header->programHeaderEntryCount; i++) { for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { - data = malloc(0x1000); + void *data = malloc(0x1000); memset(data, 0, 0x1000); memcpy(elfStart + programHeader->dataOffset, data, MIN(0x1000, programHeader->segmentFileSize - page)); diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c new file mode 100644 index 0000000..2178ffb --- /dev/null +++ b/src/kernel/syscalls/syscall.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +void wrmsr(uint32_t msr, uint32_t low, uint32_t high) { + asm("wrmsr" ::"a"(low), "d"(high), "c"(msr)); +} + +void writeMsrRegister(uint32_t reg, void *value) { + wrmsr(reg, U32(value), + 0); // when transitioning to 64 bit: U32(value) >> 32); +} + +void *handleSyscall(void *cr3, Syscall *callData) { + void *pageDirectory = mapTemporary(cr3); + void *dataPhysical = getPhysicalAddress(pageDirectory, callData); + Syscall *data = kernelMapPhysical(dataPhysical); + switch (data->id) { + case SYS_REGISTER_FUNCTION: + + break; + } + return data; +} + +extern void(syscallStub)(); +void *syscallStubPtr = syscallStub; +void *syscallStubPointer = &syscallStubPtr; + +void setupSyscalls() { + writeMsrRegister(0x174, PTR(0x08)); // code segment register + writeMsrRegister(0x175, malloc(0x1000) + 0x1000); // hadler stack + writeMsrRegister(0x176, syscallStubPtr); // the handler + return; +} diff --git a/src/kernel/syscalls/syscallStub.asm b/src/kernel/syscalls/syscallStub.asm new file mode 100644 index 0000000..ad29d6e --- /dev/null +++ b/src/kernel/syscalls/syscallStub.asm @@ -0,0 +1,18 @@ +section .sharedFunctions +bits 32 + +global syscallStub +extern handleSyscall + +syscallStub: + mov ebx, cr3 + mov ecx, 0x500000 + mov cr3, ecx + push eax + push ebx + call handleSyscall + pop ebx + mov edx, [eax+4] + mov ecx, [eax+8] + mov cr3, ebx + sysexit diff --git a/link.ld b/link.ld index 6f0a9ee..1afc715 100644 --- a/link.ld +++ b/link.ld @@ -8,11 +8,19 @@ *(.boot) } - . += 0xFFB00000; - .text : AT(ADDR(.text) - 0xFFB00000) { + . += 0xFFB00000; + .text : AT(ADDR(.text) - 0xFFB00000) { *(.text) } + . = ALIGN(4k); + functionsStart = .; + .sharedFunctions : AT(ADDR(.sharedFunctions) - 0xFFB00000) { + *(.sharedFunctions) + } + . = ALIGN(4k); + + . = ALIGN(4k); .rodata :AT (ADDR(.rodata) - 0xFFB00000) { *(.rodata) } diff --git a/src/include/syscalls.h b/src/include/syscalls.h new file mode 100644 index 0000000..19d9c15 --- /dev/null +++ b/src/include/syscalls.h @@ -0,0 +1,30 @@ +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include + +enum { + SYS_REGISTER_FUNCTION, + SYS_REQUEST, +} SyscallIds; + +typedef struct { + uint32_t id; + void *returnAddress; + void *returnEsp; +} Syscall; + +typedef struct { + Syscall; + void *handler; + char *name; +} RegisterServiceProviderSyscall; + +typedef struct { + Syscall; + char *service; + char *request; + void *data; +} RequestSyscall; + +#endif diff --git a/src/kernel/boot/boot.asm b/src/kernel/boot/boot.asm index dc00a9d..0c50e6d 100644 --- a/src/kernel/boot/boot.asm +++ b/src/kernel/boot/boot.asm @@ -110,6 +110,21 @@ db 10010010b db 11001111b db 0 + +.userCode: + dw 0xffff + dw 0 + db 0 + db 10011010b + db 11001111b + db 0 +.userData: + dw 0xffff + dw 0 + db 0 + db 10010010b + db 11001111b + db 0 .end: dw .end - gdt32 - 1 dd gdt32 diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 5731bda..9f875fa 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -37,5 +37,9 @@ void *destinationAddress); extern void *getPhysicalAddressKernel(void *address); +extern void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, + void *address); +extern uint32_t findPage(PagingInfo *info); +extern void *mapTemporary(void *address); #endif diff --git a/src/kernel/include/syscall.h b/src/kernel/include/syscall.h new file mode 100644 index 0000000..3df25fa --- /dev/null +++ b/src/kernel/include/syscall.h @@ -0,0 +1,6 @@ +#ifndef SYSCALL_H +#define SYSCALL_H + +extern void setupSyscalls(); + +#endif diff --git a/src/kernel/main.c b/src/kernel/main.c index f5879d0..fd079cd 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -2,12 +2,14 @@ #include #include #include +#include void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapMultiplePhysicalPages(multibootInfo, 4); uint32_t tarSize = 0; void *initrd = findInitrd(address, &tarSize); + setupSyscalls(); void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); loadElf(loaderProgram); asm("mov %%eax, %0" ::"r"(0xB105F00D)); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 3bd35e9..cc9c13d 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -36,22 +36,20 @@ return temporaryPage; } -void *getPhysicalAddress(void *address, PageDirectoryEntry *pageDirectory) { +void *getPhysicalAddress(PageDirectoryEntry *pageDirectory, void *address) { VirtualAddress *virtual = (void *)&address; - uint32_t pageTableLocation = + uint32_t pageTableId = pageDirectory[virtual->pageDirectoryIndex].pageTableID; - PageTableEntry *pageTable = PTR(pageTableLocation << 12); - pageTable = mapTemporary(pageTable); + PageTableEntry *pageTable = mapTemporary(PTR(pageTableId << 12)); uint32_t pageBase = pageTable[virtual->pageTableIndex].targetAddress; return PTR(pageBase << 12 | virtual->pageOffset); } void *getPhysicalAddressKernel(void *address) { - return getPhysicalAddress(address, kernelVirtualPages->pageDirectory); + return getPhysicalAddress(kernelVirtualPages->pageDirectory, address); } -uint32_t findPage(PagingInfo *info); -void mapPage(PagingInfo *info, void *physical, void *virtual); +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage); void reservePagesUntilPhysical(uint32_t endPageId) { void *buffer = (void *)0xFF800000; @@ -129,7 +127,7 @@ } for (uint32_t i = 0; i < size; i++) { mapPage(kernelVirtualPages, PTR((physicalPageStart + i) << 12), - PTR((virtualPageStart + i) << 12)); + PTR((virtualPageStart + i) << 12), false); } return PTR((virtualPageStart << 12) + (U32(address) & 0xFFF)); } @@ -138,7 +136,7 @@ return kernelMapMultiplePhysicalPages(address, 1); } -void mapPage(PagingInfo *info, void *physical, void *virtual) { +void mapPage(PagingInfo *info, void *physical, void *virtual, bool userPage) { VirtualAddress *address = (void *)&virtual; PageDirectoryEntry *directory = info->pageDirectory; if (!directory[address->pageDirectoryIndex].present) { @@ -149,6 +147,7 @@ directory[address->pageDirectoryIndex].pageTableID = newPageTable; directory[address->pageDirectoryIndex].present = 1; directory[address->pageDirectoryIndex].writable = 1; + directory[address->pageDirectoryIndex].belongsToUserProcess |= userPage; } void *pageTablePhysical = PTR(directory[address->pageDirectoryIndex].pageTableID << 12); @@ -157,6 +156,7 @@ pageTable[address->pageTableIndex].targetAddress = U32(physical) >> 12; pageTable[address->pageTableIndex].present = 1; pageTable[address->pageTableIndex].writable = 1; + pageTable[address->pageTableIndex].belongsToUserProcess = userPage; invalidatePage(U32(virtual) >> 12); } @@ -165,14 +165,14 @@ reservePage(kernelPhysicalPages, physical); uint32_t virtual = findPage(kernelVirtualPages); reservePage(kernelVirtualPages, virtual); - mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12)); + mapPage(kernelVirtualPages, PTR(physical << 12), PTR(virtual << 12), false); return PTR(virtual << 12); } void sharePage(PagingInfo *destination, void *sourceAddress, void *destinationAddress) { - PagingInfo *source = kernelVirtualPages; + PagingInfo *sourcePagingInfo = kernelVirtualPages; void *physicalSource = - getPhysicalAddress(sourceAddress, source->pageDirectory); - mapPage(destination, physicalSource, destinationAddress); + getPhysicalAddress(sourcePagingInfo->pageDirectory, sourceAddress); + mapPage(destination, physicalSource, destinationAddress, true); } diff --git a/src/kernel/service/service.asm b/src/kernel/service/service.asm new file mode 100644 index 0000000..7ffdba1 --- /dev/null +++ b/src/kernel/service/service.asm @@ -0,0 +1,28 @@ +section .sharedFunctions + +global runFunction +global runEnd + +extern currentCr3 +extern returnStack +extern currentEsp +extern mainFunction + +runFunction: + mov eax, esp + mov [returnStack], eax + mov ecx, [currentEsp] + add ecx, 0xFFC + mov edx, [mainFunction] + mov eax, [currentCr3] + mov cr3, eax + sysexit +runEnd: + ; todo: make a sysenter call to go back to ring 0, writing to cr3 is not possible in ring 3 + jmp $ + mov eax, 0x500000 + mov cr3, eax + mov eax, [returnStack] + mov esp, eax + jmp $ + ret diff --git a/src/kernel/service/services.c b/src/kernel/service/services.c index 189b8b8..dc117b0 100644 --- a/src/kernel/service/services.c +++ b/src/kernel/service/services.c @@ -16,32 +16,18 @@ void *mainFunction = NULL; void *returnStack = 0; +extern void *functionsStart; +extern void(runFunction)(); +extern void(runEnd)(); + void run(Service *service, void *main) { currentEsp = malloc(0x1000); memset(currentEsp, 0, 0x1000); - ((void **)currentEsp)[0x3FF] = &&runEnd; + ((void **)currentEsp)[0x3FF] = runEnd; sharePage(&service->pagingInfo, currentEsp, currentEsp); currentCr3 = getPhysicalAddressKernel(service->pagingInfo.pageDirectory); mainFunction = main; - asm(".intel_syntax noprefix\n" - "mov eax, [currentCr3]\n" - "mov cr3, eax\n" - "mov eax, esp\n" - "mov [returnStack], eax\n" - "mov eax, [currentEsp]\n" - "add eax, 0xFFC\n" - "mov esp, eax\n" - "push [mainFunction]\n" - "ret\n" - ".att_syntax"); -runEnd: - currentCr3 = PTR(0x500000); - asm(".intel_syntax noprefix\n" - "mov eax, [returnStack]\n" - "mov esp, eax\n" - "mov eax, 0x500000\n" - "mov cr3, eax\n" - ".att_syntax"); + asm("jmp runFunction"); } void loadElf(void *elfStart) { @@ -53,15 +39,14 @@ PagingInfo *paging = &loaderService.pagingInfo; memset(paging, 0, sizeof(PagingInfo)); paging->pageDirectory = malloc(0x1000); - paging->pageDirectory[0x3FF].pageTableID = - U32(getPhysicalAddressKernel(kernelCodePageTable)) >> 12; - paging->pageDirectory[0x3FF].present = 1; - paging->pageDirectory[0x3FF].writable = 1; - void *data; + // todo: make this unwritable! + // todo: use functionsStart as the reference + sharePage(paging, PTR(0xFFC02000), + PTR(0xFFC02000)); // functionsStart, functionsStart); for (uint32_t i = 0; i < header->programHeaderEntryCount; i++) { for (uint32_t page = 0; page < programHeader->segmentMemorySize; page += 0x1000) { - data = malloc(0x1000); + void *data = malloc(0x1000); memset(data, 0, 0x1000); memcpy(elfStart + programHeader->dataOffset, data, MIN(0x1000, programHeader->segmentFileSize - page)); diff --git a/src/kernel/syscalls/syscall.c b/src/kernel/syscalls/syscall.c new file mode 100644 index 0000000..2178ffb --- /dev/null +++ b/src/kernel/syscalls/syscall.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include + +void wrmsr(uint32_t msr, uint32_t low, uint32_t high) { + asm("wrmsr" ::"a"(low), "d"(high), "c"(msr)); +} + +void writeMsrRegister(uint32_t reg, void *value) { + wrmsr(reg, U32(value), + 0); // when transitioning to 64 bit: U32(value) >> 32); +} + +void *handleSyscall(void *cr3, Syscall *callData) { + void *pageDirectory = mapTemporary(cr3); + void *dataPhysical = getPhysicalAddress(pageDirectory, callData); + Syscall *data = kernelMapPhysical(dataPhysical); + switch (data->id) { + case SYS_REGISTER_FUNCTION: + + break; + } + return data; +} + +extern void(syscallStub)(); +void *syscallStubPtr = syscallStub; +void *syscallStubPointer = &syscallStubPtr; + +void setupSyscalls() { + writeMsrRegister(0x174, PTR(0x08)); // code segment register + writeMsrRegister(0x175, malloc(0x1000) + 0x1000); // hadler stack + writeMsrRegister(0x176, syscallStubPtr); // the handler + return; +} diff --git a/src/kernel/syscalls/syscallStub.asm b/src/kernel/syscalls/syscallStub.asm new file mode 100644 index 0000000..ad29d6e --- /dev/null +++ b/src/kernel/syscalls/syscallStub.asm @@ -0,0 +1,18 @@ +section .sharedFunctions +bits 32 + +global syscallStub +extern handleSyscall + +syscallStub: + mov ebx, cr3 + mov ecx, 0x500000 + mov cr3, ecx + push eax + push ebx + call handleSyscall + pop ebx + mov edx, [eax+4] + mov ecx, [eax+8] + mov cr3, ebx + sysexit diff --git a/src/userland/loader/main.c b/src/userland/loader/main.c index 0e9e383..c443790 100644 --- a/src/userland/loader/main.c +++ b/src/userland/loader/main.c @@ -1,4 +1,5 @@ #include +#include uint8_t inb(uint16_t port) { uint8_t result; @@ -10,7 +11,7 @@ asm volatile("outb %0, %1" : : "a"(val), "Nd"(port)); } -void Parallel_SendByte(unsigned char pData) { +void writeParallel(unsigned char pData) { unsigned char lControl; while (!(inb(0x379) & 0x80)) { @@ -24,10 +25,49 @@ } } +void testProvider(void *requestData) { + writeParallel('t'); + writeParallel('e'); + writeParallel('s'); + writeParallel('t'); +} + +void syscall(void *callData) { + Syscall *call = callData; + asm("mov %%esp, %%eax" : "=a"(call->returnEsp)); + call->returnAddress = &&returnAddress; + asm(".intel_syntax noprefix\n" + "sysenter\n" + ".att_syntax" ::"a"(callData)); +returnAddress: + call->id = 0; + return; +} + +void makeRequest(char *moduleName, char *functionName) { + RequestSyscall call = {.id = SYS_REQUEST, + .service = moduleName, + .request = functionName, + .data = 0}; + syscall(&call); +} + +void installServiceProvider(char *name, void(provider)(void *)) { + RegisterServiceProviderSyscall call = { + .id = SYS_REQUEST, + .name = name, + .handler = provider, + }; + syscall(&call); +} + +void test() { makeRequest("loader", "test"); } + int32_t main() { - // send a x to the parralel port to test stuff out - Parallel_SendByte('h'); - Parallel_SendByte('i'); - Parallel_SendByte('!'); + // writeParallel('I'); // install + installServiceProvider("test", testProvider); + // writeParallel('C'); // call + // test(); + // writeParallel('E'); // end return 0; }