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

📄 linux_init.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * *//***************************************************************** * Attempt to set up the linux tags so that the kernel can grab * configuration information.  *****************************************************************/#include <stdio.h>#include <stdlib.h>#include <sys/file.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <string.h>#include "linux_init.h"#include "sim.h"#include "addr_layout.h"#include "simmisc.h"#include "machine_params.h"#include "sim_error.h"#define TAGVALPTR(t) ((void*)(((void*)(t)) - ((t)->size)))#define NEXTTAGPTR(t) ((void*)(TAGVALPTR(t) - (sizeof(tag))))TagList tagPairs;void LongTagSet(long_tag *initTag, enum bi_tag type, unsigned long size, long val);void IntTagSet(int_tag *initTag, enum bi_tag type, unsigned long size,int val);static struct nlist *get_nlist(char *symbol);static char *ld_isymbol(char *symbol);/***************************************************************** * Initialize all the tags to their default values.  * * Note that we have not initialzied the drive_info or the  * mount_root_rdonly field, as they should not concern us. *****************************************************************/voidTagInit(int machine, TagList* tagPairs)   {  ASSERT( MEM_SIZE(machine) > 1024 * 1024);  IntTagSet(&(tagPairs->machtype),tag_machtype,sizeof(int),MACH_SIMOS_PORT0);  IntTagSet(&(tagPairs->cputype),tag_cputype,sizeof(int),CPU_R4400SC);  LongTagSet(&(tagPairs->memlower),tag_memlower,sizeof(long),0);  LongTagSet(&(tagPairs->memupper),tag_memupper,sizeof(long),(long)(MEM_SIZE(machine) + K0BASE));  LongTagSet(&(tagPairs->icache_size),tag_icache_size,sizeof(long),(1024*32));  LongTagSet(&(tagPairs->icache_linesize),tag_icache_linesize,sizeof(long),(64));  LongTagSet(&(tagPairs->dcache_size),tag_dcache_size,sizeof(long),(1024*32));  LongTagSet(&(tagPairs->dcache_linesize),tag_dcache_linesize,sizeof(long),(64));  LongTagSet(&(tagPairs->scache_size),tag_scache_size,sizeof(long),(1024*1024));  LongTagSet(&(tagPairs->scache_linesize),tag_scache_linesize,sizeof(long),(128));  IntTagSet(&(tagPairs->tlb_entries),tag_tlb_entries,sizeof(int),64);  IntTagSet(&(tagPairs->ramdisk_size),tag_ramdisk_size,sizeof(int),0);  IntTagSet(&(tagPairs->ramdisk_base),tag_ramdisk_base,sizeof(int),0);  IntTagSet(&(tagPairs->mount_root_rdonly),tag_mount_root_rdonly,sizeof(int),0);  IntTagSet(&(tagPairs->vram_base),tag_vram_base,sizeof(int),0);  IntTagSet(&(tagPairs->machgroup),tag_machgroup,sizeof(int),MACH_GROUP_SIMOS);  tagPairs->command_line.atag.tag = tag_command_line;  tagPairs->command_line.atag.size = COMMAND_LINE_SIZE;  tagPairs->command_line.data[0] = '\0';  tagPairs->drive_info.atag.tag = tag_drive_info;  tagPairs->drive_info.atag.size = sizeof(struct drive_info_struct);  tagPairs->dummy.tag = tag_dummy;  tagPairs->dummy.size = 0;  return;}void IntTagSet(int_tag *initTag, enum bi_tag type, unsigned long size,int val){  initTag->atag.tag = type;  initTag->atag.size = size;  initTag->data = val;}   void LongTagSet(long_tag *initTag, enum bi_tag type, unsigned long size, long val){  initTag->atag.tag = type;  initTag->atag.size = size;  initTag->data = val;}/***************************************************************** * I can't get this kernel into COFF format, so we need  * our own loader for its a.out-ish format. *****************************************************************/static struct nlist *symbols;static char *strings;static long strsize, numsymbols;intLinuxLoadImage(char *pathname, VA startaddr, int nbytes, VA*  entry,               int  filter){  int sfd, fd, retval;  struct exec kexec;    struct nlist *n1;  off_t filesize;  Sim_Warning("inside LinuxLoadImage\n");  /* Shouldn't reach this --ejs */  return (ENOEXEC);#if 0  *** We no longer use this function to load the linux kernel --ejs  /* TagInit(); debugging --ejs*/  if ((fd = open (pathname, O_RDONLY)) < 0) {    retval = errno;    goto error;  }  if (read (fd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) {    Sim_Warning("LinuxLoadImage: Bad header read\n");    retval = ENOEXEC;    goto error;  }  if(N_MAGIC(kexec) != OMAGIC &&     N_MAGIC(kexec) != NMAGIC &&     N_MAGIC(kexec) != ZMAGIC &&     N_MAGIC(kexec) != QMAGIC) {    Sim_Warning("LinuxLoadImage: Bad header magic number\n");    retval = ENOEXEC;/*    goto error;*/  }    if (N_MACHTYPE(kexec) != M_MIPS1 && N_MACHTYPE(kexec) != M_MIPS2) {    Sim_Warning("LinuxLoadImage: Bad machine type\n");    retval = ENOEXEC;    goto error;  }  /*   * Read file's symbol table   *   * Open kernel executable and read exec header - we need to   * use a second open file since the ARC standard doesn't   * support reverse seeking on files which might run us in   * trouble later on.   */    if ((sfd = open (pathname, O_RDONLY)) == -1) {    retval = errno;    goto error;  }     symbols = (struct nlist *)malloc (kexec.a_syms);  if (!symbols) {    retval = errno;    goto error;  }/* seeking to symbol table */    lseek (sfd, N_SYMOFF(kexec), SEEK_SET);/* Reading symbol table */    read (sfd, symbols, kexec.a_syms);    numsymbols = kexec.a_syms / sizeof (struct nlist);    filesize = lseek (sfd, 0, SEEK_END);    strsize = filesize - N_STROFF(kexec);    strings = (char *)malloc (strsize);  if (!strings) {    free (symbols);    symbols = NULL;    goto error;  }  lseek (sfd, N_STROFF(kexec), SEEK_SET);  read (sfd, strings, strsize);  /* read text and data segments in at K0BASE.  Zero out BSS */  if (lseek (fd, N_TXTOFF(kexec), SEEK_SET) == -1) {    Sim_Warning("LinuxLoadImage: Can't seek to text\n");    retval = ENOEXEC;    goto error;  }  Sim_Warning("LinuxLoadImage: Load text to %#x size %#x\n", (char *)K0_TO_MEMADDR(BE2HO_4(startaddr)), BE2HO_4(kexec.a_text));  if ((retval = read(fd, (char *)K0_TO_MEMADDR(BE2HO_4(startaddr)), BE2HO_4(kexec.a_text)) ) != kexec.a_text) {    Sim_Warning("LinuxLoadImage: Couldn't read text segment - size %#x of %#x\n",                retval, kexec.a_text);    retval = ENOEXEC;    goto error;  }  if (lseek(fd, N_DATOFF(kexec), SEEK_SET) == -1) {    Sim_Warning("LinuxLoadImage: Can't seek to data\n");    retval = ENOEXEC;    goto error;  }  Sim_Warning("LinuxLoadImage: Load data to %#x size %#x\n",               (char *)K0_TO_MEMADDR(BE2HO_4(startaddr+kexec.a_text)),               BE2HO_4(kexec.a_data));  if (read (fd, (char *)K0_TO_MEMADDR(BE2HO_4(startaddr + kexec.a_text)),             BE2HO_4(kexec.a_data)) != kexec.a_data) {    Sim_Warning("LinuxLoadImage: Couldn't read data segment\n");    retval = ENOEXEC;    goto error;  }  memset((char *) K0_TO_MEMADDR(BE2HO_4(startaddr + kexec.a_text + kexec.a_data)),          0, kexec.a_bss);    /* set value of a0 to startaddr, which is K0BASE */      Sim_Warning("Read in kexec.a_entry 0x%x\n", kexec.a_entry);  if (!(n1 = get_nlist(ld_isymbol("stext")))) {    Sim_Warning("LinuxLoadImage: Couldn't read kernel_entry from symbol table\n");    retval = ENOEXEC;    goto error;  } else {    Sim_Warning("The symb tab entry:  0x%x, the header entry 0x%x  sizeof header 0x%x\n",n1->n_value,kexec.a_entry, sizeof(kexec));  }  retval = 0;  /* CHANGE THIS */  *entry = (aout_entryfunc) (n1->n_value );/*  *entry = (aout_entryfunc) kexec.a_entry;*/   error:    if (strings) {    free (strings);  }  if (symbols) {    free (symbols);    symbols = NULL;  }      (void) close(fd);  (void) close(sfd);  return(retval);#endif  }/* * Read a symbol from the kernel executable */static struct nlist *get_nlist(char *symbol){   struct nlist *nl, *p = NULL;      for (nl = symbols; nl < symbols + numsymbols; nl++) {      /*       * We accept only extern visible .text, .data and .bss symbols.       */      if (strcmp (symbol, strings + nl->n_un.n_strx) == 0          && ((nl->n_type == N_TEXT | N_EXT) ||              (nl->n_type == N_DATA | N_EXT) ||              (nl->n_type == N_BSS  | N_EXT))) {         p = (struct nlist *)malloc (sizeof (struct nlist)                                     + strlen(strings + nl->n_un.n_strx) + 1);         if (!p)            break;         *p = *nl;         p->n_un.n_name = (char *)(p+1);         strcpy (p->n_un.n_name, strings + nl->n_un.n_strx);      }   }   return p;}static char *ld_isymbol(char *symbol){   static char isymbol[64];      /*    strcpy(isymbol, STR(C_LABEL_PREFIX));*/   strcat(isymbol, symbol);      return isymbol;}

⌨️ 快捷键说明

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