diff --git a/src/sys/kernel/kmod.c b/src/sys/kernel/kmod.c new file mode 100755 index 0000000..6228089 --- /dev/null +++ b/src/sys/kernel/kmod.c @@ -0,0 +1,239 @@ +/***************************************************************************************** + Copyright (c) 2002-2005 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id$ + +*****************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static spinLock_t moduleSpinLock = SPIN_LOCK_INITIALIZER; + +typedef struct _kDriver kDriver; +struct _kDriver +{ + kDriver *Next; + kDriver *Previous; + char *Description; + char *FileName; + int (*DriverEntry)(void); + int (*DriverExit)(void); /* called when driver is unloaded */ + int (*DriverInstall)(void); + int (*DriverUninstall)(void); + int (*DriverControl)(void); /* ioctl() */ +}; + +static kDriver *kModule = 0x0; + +uInt32 kmod_add(char *file, char *name) +{ + kDriver *tmp; + if(kModule == NULL) + { + kModule = kmalloc(sizeof *kModule); + kModule->Next = NULL; + kModule->Previous = NULL; + } + else + { + tmp = kmalloc(sizeof *tmp); + kModule->Previous = tmp; + tmp->Next = kModule; + kModule = tmp; + } + + kModule->FileName = file; + kModule->Description = name; + tmp = kModule; + while(tmp != NULL) + { + kprintf("[%s: %s]\n", tmp->FileName, tmp->Description); + tmp = tmp->Next; + } + + return 0; +} + +uInt32 kmod_load(const char *kmod_file) { + int i = 0x0; + int x = 0x0; + int rel = 0x0; + int sym = 0x0; + char *newLoc = 0x0; + char *shStr = 0x0; + char *dynStr = 0x0; + uInt32 *reMap = 0x0; + fileDescriptor *kmod_fd = 0x0; + elfHeader *binaryHeader = 0x0; + elfProgramHeader *programHeader = 0x0; + elfSectionHeader *sectionHeader = 0x0; + elfDynSym *relSymTab = 0x0; + elfPltInfo *elfRel = 0x0; + + /* Open kernel module */ + kmod_fd = fopen(kmod_file,"rb"); + if (kmod_fd == 0x0) { + kprintf("Can not open %s\n",kmod_file); + return 0x0; + } + + /* load module header */ + fseek(kmod_fd,0x0,0x0); + binaryHeader = (elfHeader *)kmalloc(sizeof(elfHeader)); + if(binaryHeader == 0x0) + { + kprintf("kmod: out of memory\n"); + return 0x0; + } + + assert(binaryHeader); + fread(binaryHeader,sizeof(elfHeader),1,kmod_fd); + + programHeader = (elfProgramHeader *)kmalloc(sizeof(elfProgramHeader)*binaryHeader->ePhnum); + if(programHeader == NULL) + kprintf("kmod_load: could not malloc()\n"); + fseek(kmod_fd,binaryHeader->ePhoff,0); + fread(programHeader,sizeof(elfSectionHeader),binaryHeader->ePhnum,kmod_fd); + + sectionHeader = (elfSectionHeader *)kmalloc(sizeof(elfSectionHeader)*binaryHeader->eShnum); + if(sectionHeader == NULL) + kprintf("kmod_load: could not malloc()\n"); + fseek(kmod_fd,binaryHeader->eShoff,0); + fread(sectionHeader,sizeof(elfSectionHeader),binaryHeader->eShnum,kmod_fd); + + shStr = (char *)kmalloc(sectionHeader[binaryHeader->eShstrndx].shSize); +if(shStr == NULL) + kprintf("kmod_load: could not malloc()\n"); +fseek(kmod_fd,sectionHeader[binaryHeader->eShstrndx].shOffset,0); + fread(shStr,sectionHeader[binaryHeader->eShstrndx].shSize,1,kmod_fd); + + for (i=0;iePhnum;i++) { + switch (programHeader[i].phType) { + case PT_LOAD: + case PT_DYNAMIC: + newLoc = (char *)programHeader[i].phVaddr + LD_START; + /* + Allocate Memory Im Going To Have To Make This Load Memory With Correct + Settings so it helps us in the future + */ + for (x=0;x < ((programHeader[i].phMemsz)+4095);x += 0x1000) { + /* make r/w or ro */ + if ((vmm_remapPage(vmmFindFreePage(_current->id),((programHeader[i].phVaddr & 0xFFFFF000) + x + LD_START),PAGE_DEFAULT)) == 0x0) + kpanic("vmmRemapPage: ld\n"); + memset((void *)((programHeader[i].phVaddr & 0xFFFFF000) + x + LD_START),0x0,0x1000); + } + /* Now Load Section To Memory */ + fseek(kmod_fd,programHeader[i].phOffset,0x0); + fread(newLoc,programHeader[i].phFilesz,1,kmod_fd); + break; + case PT_GNU_STACK: + /* Tells us if the stack should be executable. Failsafe to executable + until we add checking */ + break; + case PT_PAX_FLAGS: + /* Not sure... */ + break; + default: + kprintf("Unhandled Header : %08x\n", programHeader[i].phType); + break; + } + } + + for (i=0x0;ieShnum;i++) { + switch (sectionHeader[i].shType) { + case 3: + if (!strcmp((shStr + sectionHeader[i].shName),".dynstr")) { + dynStr = (char *)kmalloc(sectionHeader[i].shSize); +if(dynStr == NULL) + kprintf("kmod_load: could not malloc()\n"); + fseek(kmod_fd,sectionHeader[i].shOffset,0x0); + fread(dynStr,sectionHeader[i].shSize,1,kmod_fd); + } + break; + case 9: + elfRel = (elfPltInfo *)kmalloc(sectionHeader[i].shSize); +if(elfRel == NULL) + kprintf("kmod_load: could not malloc()\n"); + fseek(kmod_fd,sectionHeader[i].shOffset,0x0); + fread(elfRel,sectionHeader[i].shSize,1,kmod_fd); + + for (x=0x0;xeEntry + LD_START; + + kfree(dynStr); + kfree(shStr); + kfree(relSymTab); + kfree(sectionHeader); + kfree(programHeader); + kfree(binaryHeader); + fclose(kmod_fd); + + return((uInt32)i); + } + +/*** + END + ***/