示例#1
0
// Печать заголовков файла, заданного именем
void aout_info(char *Name)
{
   char name83[11];
   Exec exec;

   Make83Name(Name, name83);
   DirEntry Entry;
   if (FindEntry(0, name83, &Entry) == (uint)-1)
   {
      printf("Cannot open file '%s'!\n", Name);
      return;
   }
   LoadPart(&Entry, &exec, 0, sizeof(Exec));


   printf("midmag\t= 0x%x\n",   exec.a_midmag);
   printf("text\t= %d\n",     exec.a_text);
   printf("data\t= %d\n",     exec.a_data);
   printf("bss\t= %d\n",      exec.a_bss);
   printf("syms\t= %d\n",     exec.a_syms);
   printf("entry\t= 0x%x\n",    exec.a_entry);
   printf("trsize\t= %d\n",   exec.a_trsize);
   printf("drsize\t= %d\n",   exec.a_drsize);

   printf("\nflags\t= 0x%x\n", N_FLAG(exec));
   printf("machine\t= ");
   switch (N_MID(exec))
   {
      case M_OLDSUN2:   printf("OldSun2"); break;
      case M_68010:     printf("m68010"); break;
      case M_68020:     printf("m68020"); break;
      case M_SPARC:     printf("sparc"); break;
      case M_386:       printf("386"); break;
      case M_MIPS1:     printf("mips1"); break;
      case M_MIPS2:     printf("mips2"); break;
      default:          printf("unknown?"); return;
   }
   printf("\n");
   if (N_MID(exec) != M_386)
   {
      printf("Only 386's binaries are supported\n");
      return;
   }

   printf("magic\t= ");
   switch (N_MAGIC(exec))
   {
      case OMAGIC:   printf("omagic"); break;
      case NMAGIC:   printf("nmagic"); break;
      case ZMAGIC:   printf("zmagic"); break;
      case QMAGIC:   printf("qmagic"); break;
      case CMAGIC:   printf("cmagic"); break;
      default:       printf("bad magic"); return;
   }


//   Relocation_Info rels[100];
// FIXME: добавить вывод relocation records
}
示例#2
0
// Является ли файл A.OUT-бинарником?
bool aout_is(char *Name)
{
   char name83[11];

   Make83Name(Name, name83);
   DirEntry Entry;
   if (FindEntry(0, name83, &Entry) == (uint)-1)
      return 0;

   uint FirstLong;
   LoadPart(&Entry, &FirstLong, 0, sizeof(uint));
   return FirstLong==0x0064010b;
}
示例#3
0
文件: L3View.c 项目: deeice/ldglite
struct L3PartS *LoadRC()
{
  extern struct L3PartS *FindPart(int Internal, char *DatName);
  extern int LoadPart(struct L3PartS * PartPtr, int IsModel, char *ReferencingDatfile);

  struct L3PartS *PartPtr;

  PartPtr = FindPart(0, "ldconfig.ldr");
  if (PartPtr)
    if (LoadPart(PartPtr, false, NULL) != 2)
      return(PartPtr);

  PartPtr = FindPart(0, "ldliterc.dat");
  if (!PartPtr)
    return NULL; //partnum not found
  //if (LoadPart(PartPtr, false, Parts[0].DatName) == 2)
  if (LoadPart(PartPtr, false, NULL) == 2)
  {
    return NULL;
  }

  return(PartPtr);
}
示例#4
0
// Обработчик #PF для A.OUT-процессов
// Аргумент - адрес, по которому программа попыталась обратиться
// Результат - адрес загруженной страницы + флаги, или 0, если процесс "ошибся адресом"
ulong aout_pf(uint address)
{
   TaskStruct *task = Task[Current];

   // Наибольшая страница, которая будет загружаться из файла
   // (я все время предполагаю, что размеры секций кратны странице)
   uint filepages = task->header.a_text + task->header.a_data;

   // Объем АП процесса
   uint maxpage = filepages + PAGE_ADDR(task->header.a_bss + 0xfff)
      + USER_STACK_PAGES * PAGE_SIZE;

   bool ok = 0;

   // Преобразуем адрес в адрес страницы
   ulong pageaddr = PAGE_ADDR(address);
   ulong *tmppage = 0;

   // Если это страница должна грузиться из файла
   if (address < filepages)
   {
      // Выделяем страницу...
      tmppage = (ulong*)alloc_first_page();

      // ... и загружаем ее. Пользуемся тем, что LoadPart остановится
      // на конце файла.
      LoadPart(&task->file, tmppage, pageaddr+N_TXTOFF(task->header), PAGE_SIZE);

      ok = 1;
   }

   // Если это страница bss или стека
   if (address >= filepages && address < maxpage)
   {
      // Выделяем страницу...
      tmppage = (ulong*)alloc_first_page();
      // ... и обнуляем ее
      memset(tmppage, 0, PAGE_SIZE);

      ok = 1;
   }

   if (ok)
      return (ulong)tmppage + PAGE_ATTR;
   else
      return 0;
}
示例#5
0
// Запуск файла, заданного именем
// (см. комментарии в binfmt.c)
void aout_load(char *Name)
{
   char name83[11];
   DirEntry Entry;

   Make83Name(Name, name83);

   if (FindEntry(0, name83, &Entry) == (uint)-1)
   {
      printf("Cannot open file '%s'!\n", Name);
      return;
   }

   // Грузим заголовок
   Exec exec;
   LoadPart(&Entry, &exec, 0, sizeof(Exec));

   // Проверяем пригодность файла
   if (N_MID(exec) != M_386)
   {
      printf("Only 386's binaries are supported\n");
      return;
   }
   if (N_MAGIC(exec) != ZMAGIC)
   {
      printf("Not-ZMAGIC binaries are not supported yet\n");
      return;
   }

   // Количество страниц в каждой секции
   ushort TextPages = (exec.a_text + 0xfff) / PAGE_SIZE;
   ushort DataPages = (exec.a_data + 0xfff) / PAGE_SIZE;
   ushort  BSSPages = (exec.a_bss  + 0xfff) / PAGE_SIZE;


   // Создаем каталог страниц
   ulong *pg_dir = (ulong*)alloc_first_page();
   // И записываем в него системные таблицы
   memset(pg_dir, 0, PAGE_SIZE);
   pg_dir[0x200]  = 0x3000 + SYS_PAGE_ATTR;
   pg_dir[0x201]  = 0x4000 + SYS_PAGE_ATTR;


   // Создаем для процесса TaskStruct
   TaskStruct *task = (TaskStruct*)alloc_first_page();

   // Достаем адрес GDT
   GDTDescriptor GDT;
   __asm__("sgdt %0":: "m" (GDT));
   ushort desc_count = (GDT.Size + 1) >> 3;
   // Сюда допишем TSS
   ushort tssn = desc_count;


   // Заполняем атрибуты
   task->pid = CurPID++;
   task->tsss = tssn << 3;
   task->BinFormat = BIN_AOUT;
   // Копируем DirEntry и заголовок A.OUT
   memcpy(&task->file, &Entry, sizeof(DirEntry));
   memcpy(&task->header, &exec, sizeof(Exec));

   
   // Заполняем TSS
   task->tss.tl = 0;
   task->tss.esp0 = (ulong)&task->syscall_stack + sizeof(task->syscall_stack); // Стек для системных вызовов
   task->tss.ss0 = KERNEL_DS;

   task->tss.cr3 = (ulong)pg_dir;
   task->tss.eip = exec.a_entry;
   task->tss.eflags = 0x200; // Только IF
   task->tss.eax = task->tss.ebx =
      task->tss.ecx = task->tss.edx =
      task->tss.esi = task->tss.edi = 0;
   // Стек следует сразу за остальными секциями
   task->tss.esp = task->tss.ebp = (TextPages+DataPages+BSSPages + USER_STACK_PAGES) * PAGE_SIZE - 4; // 4 байта на адрес возврата
   task->tss.cs = USER_CS;
   task->tss.es = task->tss.ss =
      task->tss.ds = task->tss.fs =
      task->tss.gs = USER_DS;
   task->tss.ldt = 0;
   task->tss.iomap_trace = 0;

   // Чтобы процесс имел возможность нормально завершится, мы должны предоставить ему адрес
   // возврата в стеке. Процесс передаст управление по этому адресу при выходе из main().
   // Для этого мы маппируем страницу с функцией user_exit_code (head.S) в АП процесса.
   // Адрес, по которому мы ее будет маппировать, расположим сразу после стека (FIXME: создаем
   // сами себе грабли для динамической линковки...)

   addr_t exit_page = (TextPages+DataPages+BSSPages+USER_STACK_PAGES) * PAGE_SIZE;

   // FIXME: Я НЕ ТЕСТИРОВАЛ ЗАВЕРШЕНИЕ ПРОЦЕССОВ A.OUT
   addr_t stack_page = alloc_first_page();
   map_page(stack_page, task, PAGE_ADDR(task->tss.esp), PAGE_ATTR);
   *(ulong*)(stack_page+0xffc) = exit_page;
   map_page((addr_t)&user_exit_code, task, exit_page, PA_USER | PA_P | PA_NONFREE);


   // Создаем в GDT дескриптор для TSS
   // FIXME: Их нужно удалять при завершении процесса!

   // TSS адресуется через верхнюю память
   ulong tss_addr = (ulong)&task->tss + 0x80000000;
   GDT.Addr = (Descriptor*)((ulong)GDT.Addr - 0x80000000);
   GDT.Addr[tssn].a = (tss_addr<<16)|0x0067;
   GDT.Addr[tssn].b = (tss_addr&0xff000000)|0x00408b00|((tss_addr>>16)&0xff);
   GDT.Addr = (Descriptor*)((ulong)GDT.Addr + 0x80000000);

   GDT.Size += 8; // Один дескриптор добавили
   __asm__("lgdt %0"::"m"(GDT));

   // Ура
   Task[NTasks] = task;
   NTasks++;
}