📄 kernelloader.c
字号:
//// Visopsys// Copyright (C) 1998-2005 J. Andrew McLaughlin// // This program is free software; you can redistribute it and/or modify it// under the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 of the License, or (at your option)// any later version.// // This program is distributed in the hope that it will be useful, but// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License// for more details.// // You should have received a copy of the GNU General Public License along// with this program; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// kernelLoader.c// // This file contains the functions belonging to the kernel's executable// program loader.#include "kernelLoader.h"#include "kernelFile.h"#include "kernelMemory.h"#include "kernelMalloc.h"#include "kernelMultitasker.h"// next one added by Davide Airaghi#include "kernelParameters.h"#include "kernelMisc.h"#include "kernelPage.h"#include "kernelError.h"#include <string.h>#include <stdio.h>#include <stdlib.h>// This is the static list of file class registration functions. If you// add any to this, remember to update the LOADER_NUM_FILECLASSES value// in the header file.static kernelFileClass *(*classRegFns[LOADER_NUM_FILECLASSES]) (void) = { kernelFileClassConfig, kernelFileClassText, kernelFileClassBmp, kernelFileClassIco, kernelFileClassJpg, kernelFileClassBoot, kernelFileClassElf, kernelFileClassBinary};kernelFileClass emptyFileClass = { FILECLASS_NAME_EMPTY, NULL, { } };static kernelFileClass *fileClassList[LOADER_NUM_FILECLASSES];static int numFileClasses = 0;static kernelDynamicLibrary *libraryList = NULL;static void parseCommand(char *commandLine, int *argc, char *argv[]){ // Attempts to take a raw 'commandLine' string and parse it into a command // name and arguments. int count; *argc = 0; // Loop through the command string for (count = 0; *commandLine != '\0'; count ++) { // Remove leading whitespace while ((*commandLine == ' ') && (*commandLine != '\0')) commandLine += 1; if (*commandLine == '\0') break; // If the argument starts with a double-quote, we will discard // that character and accept characters (including whitespace) // until we hit another double-quote (or the end) if (*commandLine != '\"') { argv[*argc] = commandLine; // Accept characters until we hit some whitespace (or the end of // the arguments) while ((*commandLine != ' ') && (*commandLine != '\0')) commandLine += 1; } else { // Discard the " commandLine += 1; argv[*argc] = commandLine; // Accept characters until we hit another double-quote (or the // end of the arguments) while ((*commandLine != '\"') && (*commandLine != '\0')) commandLine += 1; } *argc += 1; if (*commandLine == '\0') break; *commandLine++ = '\0'; } return;}static void *load(const char *filename, file *theFile, int kernel){ // This function merely loads the named file into memory (kernel memory // if 'kernel' is non-NULL, otherwise user memory) and returns a pointer // to the memory. The caller must deallocate the memory when finished // with the data int status = 0; void *fileData = NULL; // Make sure the filename and theFile isn't NULL if ((filename == NULL) || (theFile == NULL)) { kernelError(kernel_error, "NULL filename or file structure"); return (fileData = NULL); } // Initialize the file structure we're going to use kernelMemClear((void *) theFile, sizeof(file)); // Now, we need to ask the filesystem driver to find the appropriate // file, and return a little information about it status = kernelFileFind(filename, theFile); if (status < 0) { // Don't make an official error. Print a message instead. kernelError(kernel_error, "The file '%s' could not be found.", filename); return (fileData = NULL); } // If we get here, that means the file was found. Make sure the size // of the program is greater than zero if (theFile->size == 0) { kernelError(kernel_error, "File to load is empty (size is zero)"); return (fileData = NULL); } // Get some memory into which we can load the program if (kernel) fileData = kernelMalloc(theFile->blocks * theFile->blockSize); else fileData = kernelMemoryGet((theFile->blocks * theFile->blockSize), "file data"); if (fileData == NULL) return (fileData); // We got the memory. Now we can load the program into memory status = kernelFileOpen(filename, OPENMODE_READ, theFile); if (status < 0) { // Release the memory we allocated for the program if (kernel) kernelFree(fileData); else kernelMemoryRelease(fileData); return (fileData = NULL); } status = kernelFileRead(theFile, 0, theFile->blocks, fileData); if (status < 0) { // Release the memory we allocated for the program if (kernel) kernelFree(fileData); else kernelMemoryRelease(fileData); return (fileData = NULL); } return (fileData);}static void populateFileClassList(void){ // Populate our list of file classes int count; for (count = 0; count < LOADER_NUM_FILECLASSES; count ++) fileClassList[numFileClasses++] = classRegFns[count]();} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Below here, the functions are exported for external use////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void *kernelLoaderLoad(const char *filename, file *theFile){ // This function merely loads the named file into memory and returns // a pointer to the memory. The caller must deallocate the memory when // finished with the data // Make sure the filename and theFile isn't NULL if ((filename == NULL) || (theFile == NULL)) { kernelError(kernel_error, "NULL filename or file structure"); return (NULL); } return (load(filename, theFile, 0 /* not kernel */));}kernelFileClass *kernelLoaderGetFileClass(const char *className){ // Given a file class name, try to find it in our list. This is internal // for kernel use only. int count; // Has our list of file classes been initialized? if (!numFileClasses) populateFileClassList(); // Find the named file class for (count = 0; count < numFileClasses; count ++) { if (!strcmp(fileClassList[count]->className, className)) return (fileClassList[count]); } // Not found return (NULL);}kernelFileClass *kernelLoaderClassify(const char *fileName, void *fileData, int size, loaderFileClass *class){ // Given some file data, try to determine whether it is one of our known // file classes. int count; // Check params. fileData and size can be NULL. if ((fileName == NULL) || (class == NULL)) return (NULL); // Has our list of file classes been initialized? if (!numFileClasses) populateFileClassList(); // Empty file? if ((fileData == NULL) || !size) { strcpy(class->className, FILECLASS_NAME_EMPTY); class->flags = LOADERFILECLASS_EMPTY; return (&emptyFileClass); } // Determine the file's class for (count = 0; count < numFileClasses; count ++) if (fileClassList[count]->detect(fileName, fileData, size, class)) return (fileClassList[count]); // Not found return (NULL);}kernelFileClass *kernelLoaderClassifyFile(const char *fileName, loaderFileClass *loaderClass){ // This is a wrapper for the function above, and just temporarily loads // the first sector of the file in order to classify it. int status = 0; file theFile; int readBlocks = 0; void *fileData = NULL; kernelFileClass *class = NULL; #define PREVIEW_READBLOCKS 4 // Check params if ((fileName == NULL) || (loaderClass == NULL)) return (class = NULL); // Initialize the file structure we're going to use kernelMemClear(&theFile, sizeof(file)); status = kernelFileOpen(fileName, OPENMODE_READ, &theFile); if (status < 0) return (class = NULL); readBlocks = min(PREVIEW_READBLOCKS, theFile.blocks); if (readBlocks) { fileData = kernelMalloc(readBlocks * theFile.blockSize); if (fileData == NULL) { kernelFileClose(&theFile); return (class = NULL); } status = kernelFileRead(&theFile, 0, readBlocks, fileData); if (status < 0) { kernelFree(fileData); kernelFileClose(&theFile); return (class = NULL); } } class = kernelLoaderClassify(fileName, fileData, min(theFile.size, (readBlocks * theFile.blockSize)), loaderClass); if (fileData) kernelFree(fileData); kernelFileClose(&theFile); return (class);}loaderSymbolTable *kernelLoaderGetSymbols(const char *fileName, int dynamic){ // Given a file name, get symbols. loaderSymbolTable *symTable = NULL; void *loadAddress = NULL; file theFile;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -