📄 kernelloader.c
字号:
kernelFileClass *fileClassDriver = NULL; loaderFileClass class; // Check params if (fileName == NULL) { kernelError(kernel_error, "File name is NULL"); return (symTable = NULL); } // Load the file data into memory loadAddress = (unsigned char *) load(fileName, &theFile, 1 /* kernel memory */); if (loadAddress == NULL) return (symTable = NULL); // Try to determine what kind of executable format we're dealing with. fileClassDriver = kernelLoaderClassify(fileName, loadAddress, theFile.size, &class); if (fileClassDriver == NULL) { kernelFree(loadAddress); return (symTable = NULL); } if (fileClassDriver->executable.getSymbols) // Get the symbols symTable = fileClassDriver->executable .getSymbols(loadAddress, dynamic, 0 /* not kernel */); kernelFree(loadAddress); return (symTable);}int kernelLoaderLoadProgram(const char *command, int privilege){ // This takes the name of an executable to load and creates a process // image based on the contents of the file. The program is not started // by this function. int status = 0; file theFile; void *loadAddress = NULL; kernelFileClass *fileClassDriver = NULL; loaderFileClass class; char procName[MAX_NAME_LENGTH]; char tmp[MAX_PATH_NAME_LENGTH]; int newProcId = 0; processImage execImage; // added by Davide Airaghi int require_ring0 = 0; if (privilege & PRIVILEGE_KERNEL) { require_ring0 = 1; privilege &= ~ PRIVILEGE_KERNEL; } // Check params if (command == NULL) { kernelError(kernel_error, "Command line to load is NULL"); return (status = ERR_NULLPARAMETER); } kernelMemClear(&execImage, sizeof(processImage)); // Set up argc and argv strncpy(execImage.commandLine, command, MAXSTRINGLENGTH); parseCommand(execImage.commandLine, &(execImage.argc), execImage.argv); // Load the program code/data into memory loadAddress = (unsigned char *) load(execImage.argv[0], &theFile, 0 /* not kernel */); if (loadAddress == NULL) return (status = ERR_INVALID); // Try to determine what kind of executable format we're dealing with. fileClassDriver = kernelLoaderClassify(execImage.argv[0], loadAddress, theFile.size, &class); if (fileClassDriver == NULL) { kernelMemoryRelease(loadAddress); return (status = ERR_INVALID); } // Make sure it's an executable if (!(class.flags & LOADERFILECLASS_EXEC)) { kernelError(kernel_error, "File \"%s\" is not an executable program", command); kernelMemoryRelease(loadAddress); return (status = ERR_PERMISSION); } // We may need to do some fixup or relocations if (fileClassDriver->executable.layoutExecutable) { status = fileClassDriver->executable .layoutExecutable(loadAddress, &execImage); if (status < 0) { kernelMemoryRelease(loadAddress); return (status); } } // Just get the program name without the path in order to set the process // name status = kernelFileSeparateLast(execImage.argv[0], tmp, procName); if (status < 0) strncpy(procName, command, MAX_NAME_LENGTH); // Set up and run the user program as a process in the multitasker // modified by Davide Airaghi if (!require_ring0) newProcId = kernelMultitaskerCreateProcess(procName, privilege, &execImage); else newProcId = kernelMultitaskerCreateProcess(procName, privilege | PRIVILEGE_KERNEL, &execImage); if (newProcId < 0) { // Release the memory we allocated for the program kernelMemoryRelease(loadAddress); kernelMemoryRelease(execImage.code); return (newProcId); } if (class.flags & LOADERFILECLASS_DYNAMIC) { // It's a dynamically-linked program, so we need to link in the required // libraries if (fileClassDriver->executable.link) { status = fileClassDriver->executable .link(newProcId, loadAddress, &execImage); if (status < 0) { kernelMemoryRelease(loadAddress); kernelMemoryRelease(execImage.code); return (status); } } } // Unmap the new process' image memory from this process' address space. status = kernelPageUnmap(kernelCurrentProcess->processId, execImage.code, execImage.imageSize); if (status < 0) kernelError(kernel_warn, "Unable to unmap new process memory from current " "process"); // Get rid of the old file memory kernelMemoryRelease(loadAddress); // All set. Return the process id. return (newProcId);}int kernelLoaderLoadLibrary(const char *libraryName){ // This takes the name of a library to load and creates a shared library // in the kernel. int status = 0; file theFile; void *loadAddress = NULL; kernelFileClass *fileClassDriver = NULL; loaderFileClass class; processImage libImage; kernelDynamicLibrary *library = NULL; char tmp[MAX_PATH_NAME_LENGTH]; // Check params if (libraryName == NULL) { kernelError(kernel_error, "Library name to load is NULL"); return (status = ERR_NULLPARAMETER); } kernelMemClear(&libImage, sizeof(processImage)); // Load the program code/data into memory loadAddress = (unsigned char *) load(libraryName, &theFile, 1 /* kernel */); if (loadAddress == NULL) return (status = ERR_INVALID); // Try to determine what kind of executable format we're dealing with. fileClassDriver = kernelLoaderClassify(libraryName, loadAddress, theFile.size, &class); if (fileClassDriver == NULL) { kernelFree(loadAddress); return (status = ERR_INVALID); } // Make sure it's a dynamic library if (!(class.flags & LOADERFILECLASS_DYNAMIC) || !(class.flags & LOADERFILECLASS_LIB)) { kernelError(kernel_error, "File \"%s\" is not a shared library", libraryName); kernelFree(loadAddress); return (status = ERR_PERMISSION); } // Get memory for our dynamic library library = kernelMalloc(sizeof(kernelDynamicLibrary)); if (library == NULL) { kernelFree(loadAddress); return (status = ERR_MEMORY); } // Just get the library name without the path, and set it as the default // library name. The file class driver can reset it to something else // if desired. status = kernelFileSeparateLast(libraryName, tmp, library->name); if (status < 0) strncpy(library->name, libraryName, MAX_NAME_LENGTH); if (fileClassDriver->executable.layoutLibrary) { // Do our library layout status = fileClassDriver->executable.layoutLibrary(loadAddress, library); if (status < 0) { kernelFree(loadAddress); kernelFree(library); return (status); } } // Add it to our list of libraries library->next = libraryList; libraryList = library; // Get rid of the old memory kernelFree(loadAddress); return (status = 0);}kernelDynamicLibrary *kernelLoaderGetLibrary(const char *libraryName){ // Searches through our list of loaded dynamic libraries for the requested // one, and returns it if found. The name can be either a full pathname, // or just a short one such as 'libc.so'. If not found, calls the // kernelLoaderLoadLibrary() function to try and load it, before searching // the list again. kernelDynamicLibrary *library = libraryList; char shortName[MAX_NAME_LENGTH]; char tmp[MAX_PATH_NAME_LENGTH]; int count; // Check params if (libraryName == NULL) { kernelError(kernel_error, "Library name is NULL"); return (library = NULL); } // If the library name is fully-qualified, get the short version without // the path. if (kernelFileSeparateLast(libraryName, tmp, shortName) < 0) strncpy(shortName, libraryName, MAX_NAME_LENGTH); for (count = 0; count < 2; count ++) { while (library) { if (!strncmp(shortName, library->name, MAX_NAME_LENGTH)) return (library); else library = library->next; } // If we fall through, it wasn't found. Try to load it. sprintf(tmp, "/system/libraries/%s", shortName); if (kernelLoaderLoadLibrary(tmp) < 0) return (library = NULL); // Loop again. library = libraryList; } // If we fall through, we don't have the library. return (library = NULL);}int kernelLoaderExecProgram(int processId, int block){ // This is a convenience function for executing a program loaded by // the kernelLoaderLoadProgram function. The calling function could // easily accomplish this stuff by talking to the multitasker. If // blocking is requested, the exit code of the program is returned to // the caller. int status = 0; // Start user program's process status = kernelMultitaskerSetProcessState(processId, proc_ready); if (status < 0) return (status); // Now, if we are supposed to block on this program, we should make // the appropriate call to the multitasker if (block) { status = kernelMultitaskerBlock(processId); // ...Now we're waiting for the program to terminate... // Return the exit code from the program return (status); } else // Return successfully return (status = 0);}int kernelLoaderLoadAndExec(const char *command, int privilege, int block){ // This is a convenience function that just calls the // kernelLoaderLoadProgram and kernelLoaderExecProgram functions for the // caller. int processId = 0; int status = 0; processId = kernelLoaderLoadProgram(command, privilege); if (processId < 0) return (processId); status = kernelLoaderExecProgram(processId, block); // All set return (status);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -