⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lprog.c

📁 GEEKOS是一个免费的操作系统内核
💻 C
字号:
/* * Code for loading and running an ELF executable in kernel mode  *  * Copyright (c) 2004 David H. Hovemeyer <daveho@cs.umd.edu> * Copyright (c) 2004 Iulian Neamtiu <neamtiu@cs.umd.edu>  * $Revision: 1.1 $ *  * This is free software.  You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". */#include <geekos/pfat.h>#include <geekos/screen.h>#include <geekos/malloc.h>#include <geekos/string.h>#include <geekos/kthread.h>#include <geekos/segment.h>#include <geekos/gdt.h>#include <geekos/mem.h>#include <geekos/int.h>#include <geekos/idt.h>#include <geekos/elf.h>#include <geekos/vfs.h>/* housekeeping routines, not much relevant */extern void Trampoline(unsigned short CodeSelector, unsigned short DataSelector, unsigned long entry);static void Printrap_Handler(struct Interrupt_State* state);static void * virtSpace;static int lprogdebug = 0;/*  * Spawn_Program() sets up the memory space, and kickstarts the program */static int Spawn_Program(char *exeFileData, struct Exe_Format *exeFormat){  struct Segment_Descriptor* desc;  unsigned long virtSize;  unsigned short codeSelector, dataSelector;  int i;  ulong_t maxva = 0;  /* Find maximum virtual address */  for (i = 0; i < exeFormat->numSegments; ++i) {    struct Exe_Segment *segment = &exeFormat->segmentList[i];    ulong_t topva = segment->startAddress + segment->sizeInMemory;         if (topva > maxva)      maxva = topva;  }  /* setup some memory space for the program */  virtSize = Round_Up_To_Page(maxva) + 4096; /* leave some slack for stack */  virtSpace = Malloc(virtSize);  memset((char *) virtSpace, '\0', virtSize);  /* Load segment data into memory */  for (i = 0; i < exeFormat->numSegments; ++i) {    struct Exe_Segment *segment = &exeFormat->segmentList[i];    memcpy(virtSpace + segment->startAddress,	   exeFileData + segment->offsetInFile,	   segment->lengthInFile);  }  /* allocate and init descriptors and selectors for code and data */  // Kernel code segment.  desc = Allocate_Segment_Descriptor();  Init_Code_Segment_Descriptor(			       desc,			       (unsigned long)virtSpace, // base address			       (virtSize/PAGE_SIZE)+10,	 // num pages			       0		         // privilege level (0 == kernel)			       );  codeSelector = Selector( 0, true, Get_Descriptor_Index( desc ) );  // Kernel data segment.  desc = Allocate_Segment_Descriptor();  Init_Data_Segment_Descriptor(			       desc,			       (unsigned long)virtSpace, // base address			       (virtSize/PAGE_SIZE)+10,	 // num pages			       0		         // privilege level (0 == kernel)			       );  dataSelector = Selector( 0, true, Get_Descriptor_Index( desc ) );  Install_Interrupt_Handler( 0x90, &Printrap_Handler );  if (lprogdebug)    {      Print("Spawn_Program(): all structures are set up\n");      Print(" virtSpace    = %x\n", (unsigned int) virtSpace);      Print(" virtSize     = %x\n", (unsigned int) virtSize);      Print(" codeSelector = %x\n", codeSelector);      Print(" dataSelector = %x\n", dataSelector);      Print("Now calling Trampoline()... \n");    }  Trampoline(codeSelector, dataSelector, exeFormat->entryAddr);   return 0;}/* Spawner is a a thread that accomodates the program to be loaded & executed * it is started from main.c */void Spawner( unsigned long arg ){  const char *program = "/c/a.exe";  char *exeFileData = 0;  ulong_t exeFileLength;  struct Exe_Format exeFormat;   /*   * Load the executable file data, parse ELF headers,   * and load code and data segments into user memory.   */  if (lprogdebug)    {      Print("Reading %s...\n", program);    }  if (Read_Fully(program, (void**) &exeFileData, &exeFileLength) != 0)    {      Print("Read_Fully failed to read %s from disk\n", program);      goto fail;    }  if (lprogdebug)    {        Print("Read_Fully OK\n");    }  if (Parse_ELF_Executable(exeFileData, exeFileLength, &exeFormat) != 0)    {      Print("Parse_ELF_Executable failed\n");      goto fail;    }  if (lprogdebug)    {       Print("Parse_ELF_Executable OK\n");    }  if (Spawn_Program(exeFileData, &exeFormat) != 0)    {      Print("Spawn_Program failed\n");      goto fail;    }    /*     * User program has been loaded, so we can free the     * executable file data now.     */    Free(exeFileData);    exeFileData = 0;  /* If we arrived here, everything was fine and the program exited */  Print("Hi ! This is the third (and last) string\n");  Print("If you see this you're happy\n");  Exit(0);fail:    /* We failed; release any allocated memory */    Disable_Interrupts();    Free(virtSpace);    Enable_Interrupts();}static void Printrap_Handler( struct Interrupt_State* state ){  char * msg = (char *)virtSpace + state->eax;  Print(msg);  g_needReschedule = true;  return;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -