diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index de72999..cb41d70 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -8,5 +8,6 @@ extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); +extern void *findTarFile(void *fileStart, uint32_t fileSize, char *filename); #endif diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index de72999..cb41d70 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -8,5 +8,6 @@ extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); +extern void *findTarFile(void *fileStart, uint32_t fileSize, char *filename); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index d5d2a33..4a0c4c0 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -51,6 +51,6 @@ char commandLineParameters[0]; } MultibootModuleTag; -extern void *findInitrd(MultibootInformation *information); +extern void *findInitrd(MultibootInformation *information, uint32_t *fileSize); #endif diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index de72999..cb41d70 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -8,5 +8,6 @@ extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); +extern void *findTarFile(void *fileStart, uint32_t fileSize, char *filename); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index d5d2a33..4a0c4c0 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -51,6 +51,6 @@ char commandLineParameters[0]; } MultibootModuleTag; -extern void *findInitrd(MultibootInformation *information); +extern void *findInitrd(MultibootInformation *information, uint32_t *fileSize); #endif diff --git a/src/kernel/main.c b/src/kernel/main.c index 2173292..7fdcc82 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -5,8 +5,10 @@ void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapPhysical(multibootInfo); - void *initrd = findInitrd(address); - asm("mov %%eax, %0" ::"r"(initrd)); + uint32_t tarSize = 0; + void *initrd = findInitrd(address, &tarSize); + void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); + asm("mov %%eax, %0" ::"r"(loaderProgram)); while (1) ; } diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index de72999..cb41d70 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -8,5 +8,6 @@ extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); +extern void *findTarFile(void *fileStart, uint32_t fileSize, char *filename); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index d5d2a33..4a0c4c0 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -51,6 +51,6 @@ char commandLineParameters[0]; } MultibootModuleTag; -extern void *findInitrd(MultibootInformation *information); +extern void *findInitrd(MultibootInformation *information, uint32_t *fileSize); #endif diff --git a/src/kernel/main.c b/src/kernel/main.c index 2173292..7fdcc82 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -5,8 +5,10 @@ void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapPhysical(multibootInfo); - void *initrd = findInitrd(address); - asm("mov %%eax, %0" ::"r"(initrd)); + uint32_t tarSize = 0; + void *initrd = findInitrd(address, &tarSize); + void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); + asm("mov %%eax, %0" ::"r"(loaderProgram)); while (1) ; } diff --git a/src/kernel/memory/tar.c b/src/kernel/memory/tar.c new file mode 100644 index 0000000..5504974 --- /dev/null +++ b/src/kernel/memory/tar.c @@ -0,0 +1,29 @@ +#include "tar.h" +#include +#include + +#define SECTOR_COUNT(size) (size ? (size - 1) / 512 + 1 : 0) + +uint32_t readOctal(char *string) { + uint32_t result = 0; + while (*string) { + result += *string - '0'; + result <<= 3; + string++; + } + return result; +} + +void *findTarFile(void *fileData, uint32_t fileSize, char *fileName) { + void *currentPosition = fileData; + while (currentPosition <= fileData + fileSize) { + TarFileHeader *header = currentPosition; + uint32_t fileSize = readOctal(header->fileSize); + if (!stringEquals(header->fileName, fileName)) { + currentPosition += 512 * (SECTOR_COUNT(fileSize) + 1); + continue; + } + return currentPosition + 512; + } + return NULL; +} diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index de72999..cb41d70 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -8,5 +8,6 @@ extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); +extern void *findTarFile(void *fileStart, uint32_t fileSize, char *filename); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index d5d2a33..4a0c4c0 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -51,6 +51,6 @@ char commandLineParameters[0]; } MultibootModuleTag; -extern void *findInitrd(MultibootInformation *information); +extern void *findInitrd(MultibootInformation *information, uint32_t *fileSize); #endif diff --git a/src/kernel/main.c b/src/kernel/main.c index 2173292..7fdcc82 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -5,8 +5,10 @@ void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapPhysical(multibootInfo); - void *initrd = findInitrd(address); - asm("mov %%eax, %0" ::"r"(initrd)); + uint32_t tarSize = 0; + void *initrd = findInitrd(address, &tarSize); + void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); + asm("mov %%eax, %0" ::"r"(loaderProgram)); while (1) ; } diff --git a/src/kernel/memory/tar.c b/src/kernel/memory/tar.c new file mode 100644 index 0000000..5504974 --- /dev/null +++ b/src/kernel/memory/tar.c @@ -0,0 +1,29 @@ +#include "tar.h" +#include +#include + +#define SECTOR_COUNT(size) (size ? (size - 1) / 512 + 1 : 0) + +uint32_t readOctal(char *string) { + uint32_t result = 0; + while (*string) { + result += *string - '0'; + result <<= 3; + string++; + } + return result; +} + +void *findTarFile(void *fileData, uint32_t fileSize, char *fileName) { + void *currentPosition = fileData; + while (currentPosition <= fileData + fileSize) { + TarFileHeader *header = currentPosition; + uint32_t fileSize = readOctal(header->fileSize); + if (!stringEquals(header->fileName, fileName)) { + currentPosition += 512 * (SECTOR_COUNT(fileSize) + 1); + continue; + } + return currentPosition + 512; + } + return NULL; +} diff --git a/src/kernel/memory/tar.h b/src/kernel/memory/tar.h new file mode 100644 index 0000000..ae0fbce --- /dev/null +++ b/src/kernel/memory/tar.h @@ -0,0 +1,23 @@ +#ifndef TAR_H +#define TAR_H + +typedef struct { + char fileName[100]; + char fileMode[8]; + char ownerUID[8]; + char groupUID[8]; + char fileSize[12]; + char lastModification[12]; + char checksum[8]; + char fileType; + char linkTarget[100]; + char ustar[6]; + char ustarVersion[2]; + char ownerUserName[32]; + char ownerGroupName[32]; + char deviceMajor[8]; + char deviceMinor[8]; + char filenamePrefix[155]; +} TarFileHeader; + +#endif diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index de72999..cb41d70 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -8,5 +8,6 @@ extern void memset(void *target, uint8_t byte, uint32_t size); extern void *kernelMapPhysical(void *address); extern void *kernelMapMultiplePhysicalPages(void *address, uint32_t size); +extern void *findTarFile(void *fileStart, uint32_t fileSize, char *filename); #endif diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index d5d2a33..4a0c4c0 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -51,6 +51,6 @@ char commandLineParameters[0]; } MultibootModuleTag; -extern void *findInitrd(MultibootInformation *information); +extern void *findInitrd(MultibootInformation *information, uint32_t *fileSize); #endif diff --git a/src/kernel/main.c b/src/kernel/main.c index 2173292..7fdcc82 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -5,8 +5,10 @@ void kernelMain(void *multibootInfo) { setupMemory(); void *address = kernelMapPhysical(multibootInfo); - void *initrd = findInitrd(address); - asm("mov %%eax, %0" ::"r"(initrd)); + uint32_t tarSize = 0; + void *initrd = findInitrd(address, &tarSize); + void *loaderProgram = findTarFile(initrd, tarSize, "initrd/loader"); + asm("mov %%eax, %0" ::"r"(loaderProgram)); while (1) ; } diff --git a/src/kernel/memory/tar.c b/src/kernel/memory/tar.c new file mode 100644 index 0000000..5504974 --- /dev/null +++ b/src/kernel/memory/tar.c @@ -0,0 +1,29 @@ +#include "tar.h" +#include +#include + +#define SECTOR_COUNT(size) (size ? (size - 1) / 512 + 1 : 0) + +uint32_t readOctal(char *string) { + uint32_t result = 0; + while (*string) { + result += *string - '0'; + result <<= 3; + string++; + } + return result; +} + +void *findTarFile(void *fileData, uint32_t fileSize, char *fileName) { + void *currentPosition = fileData; + while (currentPosition <= fileData + fileSize) { + TarFileHeader *header = currentPosition; + uint32_t fileSize = readOctal(header->fileSize); + if (!stringEquals(header->fileName, fileName)) { + currentPosition += 512 * (SECTOR_COUNT(fileSize) + 1); + continue; + } + return currentPosition + 512; + } + return NULL; +} diff --git a/src/kernel/memory/tar.h b/src/kernel/memory/tar.h new file mode 100644 index 0000000..ae0fbce --- /dev/null +++ b/src/kernel/memory/tar.h @@ -0,0 +1,23 @@ +#ifndef TAR_H +#define TAR_H + +typedef struct { + char fileName[100]; + char fileMode[8]; + char ownerUID[8]; + char groupUID[8]; + char fileSize[12]; + char lastModification[12]; + char checksum[8]; + char fileType; + char linkTarget[100]; + char ustar[6]; + char ustarVersion[2]; + char ownerUserName[32]; + char ownerGroupName[32]; + char deviceMajor[8]; + char deviceMinor[8]; + char filenamePrefix[155]; +} TarFileHeader; + +#endif diff --git a/src/kernel/multiboot/multiboot.c b/src/kernel/multiboot/multiboot.c index fbfdbad..f9ce722 100644 --- a/src/kernel/multiboot/multiboot.c +++ b/src/kernel/multiboot/multiboot.c @@ -2,7 +2,7 @@ #include #include -void *findInitrd(MultibootInformation *information) { +void *findInitrd(MultibootInformation *information, uint32_t *fileSize) { MultibootInformationTag *tag = (void *)information->tags; while (tag->size) { if (tag->type == MultibootModuleTagType && @@ -12,6 +12,7 @@ uint32_t moduleSize = module->moduleEnd - module->moduleStart; void *moduleLocation = kernelMapMultiplePhysicalPages( PTR(module->moduleStart), PAGE_COUNT(moduleSize)); + *fileSize = moduleSize; return moduleLocation; } tag = ((void *)tag) + ((tag->size + 0x07) & ~0x7);