diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index 2470bcc..d78cce4 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,6 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel - module2 /initrd.tar + module2 /initrd.tar initrd boot } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index 2470bcc..d78cce4 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,6 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel - module2 /initrd.tar + module2 /initrd.tar initrd boot } diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 1d40818..de72999 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -7,5 +7,6 @@ extern void reservePagesUntilPhysical(uint32_t endPageId); extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); +extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); #endif diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index 2470bcc..d78cce4 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,6 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel - module2 /initrd.tar + module2 /initrd.tar initrd boot } diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 1d40818..de72999 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -7,5 +7,6 @@ extern void reservePagesUntilPhysical(uint32_t endPageId); extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); +extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index 26c0f93..d5d2a33 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -10,39 +10,47 @@ typedef enum { BootCommandLineType = 1, - ModulesType = 3, + MultibootModuleTagType = 3, BasicMemoryInformationType = 4, BiosBootDeviceType = 5, } MultibootType; typedef struct { - uint32_t type; // multiboot type - uint32_t size; -} MultibootModuleInfo; + uint32_t totalSize; + uint32_t reserved; + uint8_t tags[]; +} MultibootInformation; typedef struct { - MultibootModuleInfo; + uint32_t type; // multiboot type + uint32_t size; +} MultibootInformationTag; + +typedef struct { + MultibootInformationTag; uint32_t memUpper; uint32_t memLower; } BasicMemoryInformation; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t biosDevice; uint32_t partition; uint32_t subPartition; } BiosBootDevice; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; char string[0]; } BootCommandLine; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t moduleStart; uint32_t moduleEnd; - char string[0]; -} Modules; + char commandLineParameters[0]; +} MultibootModuleTag; + +extern void *findInitrd(MultibootInformation *information); #endif diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index 2470bcc..d78cce4 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,6 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel - module2 /initrd.tar + module2 /initrd.tar initrd boot } diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 1d40818..de72999 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -7,5 +7,6 @@ extern void reservePagesUntilPhysical(uint32_t endPageId); extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); +extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index 26c0f93..d5d2a33 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -10,39 +10,47 @@ typedef enum { BootCommandLineType = 1, - ModulesType = 3, + MultibootModuleTagType = 3, BasicMemoryInformationType = 4, BiosBootDeviceType = 5, } MultibootType; typedef struct { - uint32_t type; // multiboot type - uint32_t size; -} MultibootModuleInfo; + uint32_t totalSize; + uint32_t reserved; + uint8_t tags[]; +} MultibootInformation; typedef struct { - MultibootModuleInfo; + uint32_t type; // multiboot type + uint32_t size; +} MultibootInformationTag; + +typedef struct { + MultibootInformationTag; uint32_t memUpper; uint32_t memLower; } BasicMemoryInformation; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t biosDevice; uint32_t partition; uint32_t subPartition; } BiosBootDevice; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; char string[0]; } BootCommandLine; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t moduleStart; uint32_t moduleEnd; - char string[0]; -} Modules; + char commandLineParameters[0]; +} MultibootModuleTag; + +extern void *findInitrd(MultibootInformation *information); #endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 672e7dd..ac89942 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -1,7 +1,15 @@ #ifndef UTIL_H #define UTIL_H +#include + #define U32(x) (uint32_t)(uintptr_t)(x) #define PTR(x) (void *)(uintptr_t)(x) +#define NULL PTR(0) + +#define PAGE_COUNT(x) (((x - 1) / 4096) + 1) + +extern bool stringEquals(char *string1, char *string2); + #endif diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index 2470bcc..d78cce4 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,6 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel - module2 /initrd.tar + module2 /initrd.tar initrd boot } diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 1d40818..de72999 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -7,5 +7,6 @@ extern void reservePagesUntilPhysical(uint32_t endPageId); extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); +extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index 26c0f93..d5d2a33 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -10,39 +10,47 @@ typedef enum { BootCommandLineType = 1, - ModulesType = 3, + MultibootModuleTagType = 3, BasicMemoryInformationType = 4, BiosBootDeviceType = 5, } MultibootType; typedef struct { - uint32_t type; // multiboot type - uint32_t size; -} MultibootModuleInfo; + uint32_t totalSize; + uint32_t reserved; + uint8_t tags[]; +} MultibootInformation; typedef struct { - MultibootModuleInfo; + uint32_t type; // multiboot type + uint32_t size; +} MultibootInformationTag; + +typedef struct { + MultibootInformationTag; uint32_t memUpper; uint32_t memLower; } BasicMemoryInformation; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t biosDevice; uint32_t partition; uint32_t subPartition; } BiosBootDevice; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; char string[0]; } BootCommandLine; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t moduleStart; uint32_t moduleEnd; - char string[0]; -} Modules; + char commandLineParameters[0]; +} MultibootModuleTag; + +extern void *findInitrd(MultibootInformation *information); #endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 672e7dd..ac89942 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -1,7 +1,15 @@ #ifndef UTIL_H #define UTIL_H +#include + #define U32(x) (uint32_t)(uintptr_t)(x) #define PTR(x) (void *)(uintptr_t)(x) +#define NULL PTR(0) + +#define PAGE_COUNT(x) (((x - 1) / 4096) + 1) + +extern bool stringEquals(char *string1, char *string2); + #endif diff --git a/src/kernel/main.c b/src/kernel/main.c index 3d19504..2173292 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -5,7 +5,8 @@ void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapPhysical(multibootInfo); - asm("mov %%eax, %0" ::"r"(address)); + void *initrd = findInitrd(address); + asm("mov %%eax, %0" ::"r"(initrd)); while (1) ; } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index 2470bcc..d78cce4 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,6 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel - module2 /initrd.tar + module2 /initrd.tar initrd boot } diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 1d40818..de72999 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -7,5 +7,6 @@ extern void reservePagesUntilPhysical(uint32_t endPageId); extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); +extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index 26c0f93..d5d2a33 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -10,39 +10,47 @@ typedef enum { BootCommandLineType = 1, - ModulesType = 3, + MultibootModuleTagType = 3, BasicMemoryInformationType = 4, BiosBootDeviceType = 5, } MultibootType; typedef struct { - uint32_t type; // multiboot type - uint32_t size; -} MultibootModuleInfo; + uint32_t totalSize; + uint32_t reserved; + uint8_t tags[]; +} MultibootInformation; typedef struct { - MultibootModuleInfo; + uint32_t type; // multiboot type + uint32_t size; +} MultibootInformationTag; + +typedef struct { + MultibootInformationTag; uint32_t memUpper; uint32_t memLower; } BasicMemoryInformation; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t biosDevice; uint32_t partition; uint32_t subPartition; } BiosBootDevice; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; char string[0]; } BootCommandLine; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t moduleStart; uint32_t moduleEnd; - char string[0]; -} Modules; + char commandLineParameters[0]; +} MultibootModuleTag; + +extern void *findInitrd(MultibootInformation *information); #endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 672e7dd..ac89942 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -1,7 +1,15 @@ #ifndef UTIL_H #define UTIL_H +#include + #define U32(x) (uint32_t)(uintptr_t)(x) #define PTR(x) (void *)(uintptr_t)(x) +#define NULL PTR(0) + +#define PAGE_COUNT(x) (((x - 1) / 4096) + 1) + +extern bool stringEquals(char *string1, char *string2); + #endif diff --git a/src/kernel/main.c b/src/kernel/main.c index 3d19504..2173292 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -5,7 +5,8 @@ void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapPhysical(multibootInfo); - asm("mov %%eax, %0" ::"r"(address)); + void *initrd = findInitrd(address); + asm("mov %%eax, %0" ::"r"(initrd)); while (1) ; } diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index cf36e66..0213f25 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -80,7 +80,7 @@ } } -uint32_t findPage(PagingInfo *info) { +uint32_t findMultiplePages(PagingInfo *info, uint32_t size) { for (uint32_t veryCoarse = info->pageSearchStart / 1024;; veryCoarse++) { if (info->isPageAllocatedCoarse[veryCoarse] == ~0) { continue; @@ -89,9 +89,18 @@ if (info->isPageAllocatedCoarse[veryCoarse] & (1 << coarse)) { continue; } - uint32_t coarsePageId = (veryCoarse * 32 + coarse); + uint32_t coarsePageId = veryCoarse * 32 + coarse; for (uint8_t fine = 0; fine < 32; fine++) { - if (info->isPageAllocated[coarsePageId] & (1 << fine)) { + bool fail = false; + for (uint32_t check = 0; check < size; check++) { + uint32_t currentFine = fine + check; + if (info->isPageAllocated[coarsePageId + currentFine / 32] & + (1 << (currentFine % 32))) { + fail = true; + break; + } + } + if (fail) { continue; } return coarsePageId * 32 + fine; @@ -100,13 +109,22 @@ } } +uint32_t findPage(PagingInfo *info) { return findMultiplePages(info, 1); } + +void *kernelMapMultiplePhysicalPages(void *address, uint32_t size) { + uint32_t physicalPageStart = U32(address) >> 12; + uint32_t virtualPageStart = findMultiplePages(kernelVirtualPages, size); + for (uint32_t i = 0; i < size; i++) { + reservePage(physicalPages, physicalPageStart + i); + reservePage(kernelVirtualPages, virtualPageStart + i); + kernelUtilityPages[virtualPageStart + i].targetAddress = + physicalPageStart + i; + kernelUtilityPages[virtualPageStart + i].writable = 1; + kernelUtilityPages[virtualPageStart + i].present = 1; + } + return PTR((virtualPageStart << 12) + (U32(address) & 0xFFF)); +} + void *kernelMapPhysical(void *address) { - uint32_t physicalPage = U32(address) >> 12; - reservePage(physicalPages, physicalPage); - uint32_t virtualPage = findPage(kernelVirtualPages); - reservePage(kernelVirtualPages, virtualPage); - kernelUtilityPages[virtualPage].targetAddress = physicalPage; - kernelUtilityPages[virtualPage].writable = 1; - kernelUtilityPages[virtualPage].present = 1; - return PTR((virtualPage << 12) + (U32(address) & 0xFFF)); + return kernelMapMultiplePhysicalPages(address, 1); } diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index 2470bcc..d78cce4 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,6 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel - module2 /initrd.tar + module2 /initrd.tar initrd boot } diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 1d40818..de72999 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -7,5 +7,6 @@ extern void reservePagesUntilPhysical(uint32_t endPageId); extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); +extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index 26c0f93..d5d2a33 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -10,39 +10,47 @@ typedef enum { BootCommandLineType = 1, - ModulesType = 3, + MultibootModuleTagType = 3, BasicMemoryInformationType = 4, BiosBootDeviceType = 5, } MultibootType; typedef struct { - uint32_t type; // multiboot type - uint32_t size; -} MultibootModuleInfo; + uint32_t totalSize; + uint32_t reserved; + uint8_t tags[]; +} MultibootInformation; typedef struct { - MultibootModuleInfo; + uint32_t type; // multiboot type + uint32_t size; +} MultibootInformationTag; + +typedef struct { + MultibootInformationTag; uint32_t memUpper; uint32_t memLower; } BasicMemoryInformation; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t biosDevice; uint32_t partition; uint32_t subPartition; } BiosBootDevice; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; char string[0]; } BootCommandLine; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t moduleStart; uint32_t moduleEnd; - char string[0]; -} Modules; + char commandLineParameters[0]; +} MultibootModuleTag; + +extern void *findInitrd(MultibootInformation *information); #endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 672e7dd..ac89942 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -1,7 +1,15 @@ #ifndef UTIL_H #define UTIL_H +#include + #define U32(x) (uint32_t)(uintptr_t)(x) #define PTR(x) (void *)(uintptr_t)(x) +#define NULL PTR(0) + +#define PAGE_COUNT(x) (((x - 1) / 4096) + 1) + +extern bool stringEquals(char *string1, char *string2); + #endif diff --git a/src/kernel/main.c b/src/kernel/main.c index 3d19504..2173292 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -5,7 +5,8 @@ void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapPhysical(multibootInfo); - asm("mov %%eax, %0" ::"r"(address)); + void *initrd = findInitrd(address); + asm("mov %%eax, %0" ::"r"(initrd)); while (1) ; } diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index cf36e66..0213f25 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -80,7 +80,7 @@ } } -uint32_t findPage(PagingInfo *info) { +uint32_t findMultiplePages(PagingInfo *info, uint32_t size) { for (uint32_t veryCoarse = info->pageSearchStart / 1024;; veryCoarse++) { if (info->isPageAllocatedCoarse[veryCoarse] == ~0) { continue; @@ -89,9 +89,18 @@ if (info->isPageAllocatedCoarse[veryCoarse] & (1 << coarse)) { continue; } - uint32_t coarsePageId = (veryCoarse * 32 + coarse); + uint32_t coarsePageId = veryCoarse * 32 + coarse; for (uint8_t fine = 0; fine < 32; fine++) { - if (info->isPageAllocated[coarsePageId] & (1 << fine)) { + bool fail = false; + for (uint32_t check = 0; check < size; check++) { + uint32_t currentFine = fine + check; + if (info->isPageAllocated[coarsePageId + currentFine / 32] & + (1 << (currentFine % 32))) { + fail = true; + break; + } + } + if (fail) { continue; } return coarsePageId * 32 + fine; @@ -100,13 +109,22 @@ } } +uint32_t findPage(PagingInfo *info) { return findMultiplePages(info, 1); } + +void *kernelMapMultiplePhysicalPages(void *address, uint32_t size) { + uint32_t physicalPageStart = U32(address) >> 12; + uint32_t virtualPageStart = findMultiplePages(kernelVirtualPages, size); + for (uint32_t i = 0; i < size; i++) { + reservePage(physicalPages, physicalPageStart + i); + reservePage(kernelVirtualPages, virtualPageStart + i); + kernelUtilityPages[virtualPageStart + i].targetAddress = + physicalPageStart + i; + kernelUtilityPages[virtualPageStart + i].writable = 1; + kernelUtilityPages[virtualPageStart + i].present = 1; + } + return PTR((virtualPageStart << 12) + (U32(address) & 0xFFF)); +} + void *kernelMapPhysical(void *address) { - uint32_t physicalPage = U32(address) >> 12; - reservePage(physicalPages, physicalPage); - uint32_t virtualPage = findPage(kernelVirtualPages); - reservePage(kernelVirtualPages, virtualPage); - kernelUtilityPages[virtualPage].targetAddress = physicalPage; - kernelUtilityPages[virtualPage].writable = 1; - kernelUtilityPages[virtualPage].present = 1; - return PTR((virtualPage << 12) + (U32(address) & 0xFFF)); + return kernelMapMultiplePhysicalPages(address, 1); } diff --git a/src/kernel/multiboot/multiboot.c b/src/kernel/multiboot/multiboot.c new file mode 100644 index 0000000..fbfdbad --- /dev/null +++ b/src/kernel/multiboot/multiboot.c @@ -0,0 +1,20 @@ +#include +#include +#include + +void *findInitrd(MultibootInformation *information) { + MultibootInformationTag *tag = (void *)information->tags; + while (tag->size) { + if (tag->type == MultibootModuleTagType && + stringEquals(((MultibootModuleTag *)tag)->commandLineParameters, + "initrd")) { + MultibootModuleTag *module = (void *)tag; + uint32_t moduleSize = module->moduleEnd - module->moduleStart; + void *moduleLocation = kernelMapMultiplePhysicalPages( + PTR(module->moduleStart), PAGE_COUNT(moduleSize)); + return moduleLocation; + } + tag = ((void *)tag) + ((tag->size + 0x07) & ~0x7); + } + return NULL; +} diff --git a/rootfs/boot/grub/grub.cfg b/rootfs/boot/grub/grub.cfg index 2470bcc..d78cce4 100644 --- a/rootfs/boot/grub/grub.cfg +++ b/rootfs/boot/grub/grub.cfg @@ -3,6 +3,6 @@ menuentry "honey os" { multiboot2 /boot/kernel - module2 /initrd.tar + module2 /initrd.tar initrd boot } diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index 1d40818..de72999 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -7,5 +7,6 @@ extern void reservePagesUntilPhysical(uint32_t endPageId); extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); +extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index 26c0f93..d5d2a33 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -10,39 +10,47 @@ typedef enum { BootCommandLineType = 1, - ModulesType = 3, + MultibootModuleTagType = 3, BasicMemoryInformationType = 4, BiosBootDeviceType = 5, } MultibootType; typedef struct { - uint32_t type; // multiboot type - uint32_t size; -} MultibootModuleInfo; + uint32_t totalSize; + uint32_t reserved; + uint8_t tags[]; +} MultibootInformation; typedef struct { - MultibootModuleInfo; + uint32_t type; // multiboot type + uint32_t size; +} MultibootInformationTag; + +typedef struct { + MultibootInformationTag; uint32_t memUpper; uint32_t memLower; } BasicMemoryInformation; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t biosDevice; uint32_t partition; uint32_t subPartition; } BiosBootDevice; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; char string[0]; } BootCommandLine; typedef struct { - MultibootModuleInfo; + MultibootInformationTag; uint32_t moduleStart; uint32_t moduleEnd; - char string[0]; -} Modules; + char commandLineParameters[0]; +} MultibootModuleTag; + +extern void *findInitrd(MultibootInformation *information); #endif diff --git a/src/kernel/include/util.h b/src/kernel/include/util.h index 672e7dd..ac89942 100644 --- a/src/kernel/include/util.h +++ b/src/kernel/include/util.h @@ -1,7 +1,15 @@ #ifndef UTIL_H #define UTIL_H +#include + #define U32(x) (uint32_t)(uintptr_t)(x) #define PTR(x) (void *)(uintptr_t)(x) +#define NULL PTR(0) + +#define PAGE_COUNT(x) (((x - 1) / 4096) + 1) + +extern bool stringEquals(char *string1, char *string2); + #endif diff --git a/src/kernel/main.c b/src/kernel/main.c index 3d19504..2173292 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -5,7 +5,8 @@ void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapPhysical(multibootInfo); - asm("mov %%eax, %0" ::"r"(address)); + void *initrd = findInitrd(address); + asm("mov %%eax, %0" ::"r"(initrd)); while (1) ; } diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index cf36e66..0213f25 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -80,7 +80,7 @@ } } -uint32_t findPage(PagingInfo *info) { +uint32_t findMultiplePages(PagingInfo *info, uint32_t size) { for (uint32_t veryCoarse = info->pageSearchStart / 1024;; veryCoarse++) { if (info->isPageAllocatedCoarse[veryCoarse] == ~0) { continue; @@ -89,9 +89,18 @@ if (info->isPageAllocatedCoarse[veryCoarse] & (1 << coarse)) { continue; } - uint32_t coarsePageId = (veryCoarse * 32 + coarse); + uint32_t coarsePageId = veryCoarse * 32 + coarse; for (uint8_t fine = 0; fine < 32; fine++) { - if (info->isPageAllocated[coarsePageId] & (1 << fine)) { + bool fail = false; + for (uint32_t check = 0; check < size; check++) { + uint32_t currentFine = fine + check; + if (info->isPageAllocated[coarsePageId + currentFine / 32] & + (1 << (currentFine % 32))) { + fail = true; + break; + } + } + if (fail) { continue; } return coarsePageId * 32 + fine; @@ -100,13 +109,22 @@ } } +uint32_t findPage(PagingInfo *info) { return findMultiplePages(info, 1); } + +void *kernelMapMultiplePhysicalPages(void *address, uint32_t size) { + uint32_t physicalPageStart = U32(address) >> 12; + uint32_t virtualPageStart = findMultiplePages(kernelVirtualPages, size); + for (uint32_t i = 0; i < size; i++) { + reservePage(physicalPages, physicalPageStart + i); + reservePage(kernelVirtualPages, virtualPageStart + i); + kernelUtilityPages[virtualPageStart + i].targetAddress = + physicalPageStart + i; + kernelUtilityPages[virtualPageStart + i].writable = 1; + kernelUtilityPages[virtualPageStart + i].present = 1; + } + return PTR((virtualPageStart << 12) + (U32(address) & 0xFFF)); +} + void *kernelMapPhysical(void *address) { - uint32_t physicalPage = U32(address) >> 12; - reservePage(physicalPages, physicalPage); - uint32_t virtualPage = findPage(kernelVirtualPages); - reservePage(kernelVirtualPages, virtualPage); - kernelUtilityPages[virtualPage].targetAddress = physicalPage; - kernelUtilityPages[virtualPage].writable = 1; - kernelUtilityPages[virtualPage].present = 1; - return PTR((virtualPage << 12) + (U32(address) & 0xFFF)); + return kernelMapMultiplePhysicalPages(address, 1); } diff --git a/src/kernel/multiboot/multiboot.c b/src/kernel/multiboot/multiboot.c new file mode 100644 index 0000000..fbfdbad --- /dev/null +++ b/src/kernel/multiboot/multiboot.c @@ -0,0 +1,20 @@ +#include +#include +#include + +void *findInitrd(MultibootInformation *information) { + MultibootInformationTag *tag = (void *)information->tags; + while (tag->size) { + if (tag->type == MultibootModuleTagType && + stringEquals(((MultibootModuleTag *)tag)->commandLineParameters, + "initrd")) { + MultibootModuleTag *module = (void *)tag; + uint32_t moduleSize = module->moduleEnd - module->moduleStart; + void *moduleLocation = kernelMapMultiplePhysicalPages( + PTR(module->moduleStart), PAGE_COUNT(moduleSize)); + return moduleLocation; + } + tag = ((void *)tag) + ((tag->size + 0x07) & ~0x7); + } + return NULL; +} diff --git a/src/kernel/util/strings.c b/src/kernel/util/strings.c new file mode 100644 index 0000000..9ceb113 --- /dev/null +++ b/src/kernel/util/strings.c @@ -0,0 +1,12 @@ +#include + +bool stringEquals(char *string1, char *string2) { + while (*string1) { + if (*string1 != *string2) { + return false; + } + string1++; + string2++; + } + return *string1 == *string2; +}