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

📄 linux.c

📁 Hermit-at-1.1.3,一款bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
	  blocks_per_group, inodes_per_group, group_desc_sector,	  first_inode_table, inode_table_sector, dir_entry_table_sector,	  inode, group, file_size, file_block[15], file_data_sector,	  addr_per_block;	ext2_super_block *psb;	ext2_group_desc  *pgd;	ext2_inode       *pinode;	ext2_dir_entry   *pde = 0;	addr_t           load_address;	char *flash_option[] = {	  0,	  mem,#if !defined(CONSOLE) || (defined(CONSOLE) && CONSOLE == 1)	  console,#endif	};	char *cf_option[] = {	  0,	  mem,	  noinitrd,	  root,#if !defined(CONSOLE) || (defined(CONSOLE) && CONSOLE == 1)	  console,#endif	};	if (!argc) {	  if (*(volatile unsigned char *)(0x80000000 + PDDR) &	      PDDR_FLASHBOOT) {	    argc = sizeof (flash_option) / sizeof (char *);	    argv = flash_option;	  } else {	    if (ide_detect_devices ()) {	      return 0;	    }	    if (ide_startup_devices ()) {	      return 0;	    }	    if (ide_read_sectors (0, 0, buf, 1)) {	      return 0;	    }	    IO_LEDFLSH = 0x4c;	    memcpy (part, buf + 0x1be, sizeof(partition) * 4);	    for (i = 0; i < 4; i++) {	      if (part[i].sys_ind != 0x83) {		continue;	      }	      start = read4_little_endian (part[i].start4);	      size = read4_little_endian (part[i].size4);	      hprintf ("/dev/hda%d: start=0x%x, size=0x%x\n",		       i + 1, start, size);	      super_block_sector = start + 2;	      if (ide_read_sectors (0, super_block_sector, buf, 1)) {		hprintf ("Super block read error.\n");		continue;	      }	      psb = (ext2_super_block *)buf;	      if (psb->s_magic != 0xef53) {		hprintf ("Isn't ext2.\n");		continue;	      }	      if (psb->s_inode_size != INODE_SIZE) {		hprintf ("Bad inode size.\n");		continue;	      }	      if (psb->s_log_block_size > 2) {		hprintf ("Bad block size.\n");		continue;	      }	      sectors_per_block = 2;	      for (j = 0; j < psb->s_log_block_size; j++) {		sectors_per_block *= 2;	      }	      blocks_per_group = psb->s_blocks_per_group;	      inodes_per_group = psb->s_inodes_per_group;	      group_desc_sector =		start + sectors_per_block * (1 + psb->s_first_data_block);	      if (ide_read_sectors (0, group_desc_sector, buf, 1)) {		hprintf ("Group desc read error.\n");		continue;	      }	      pgd = (ext2_group_desc *)buf;	      first_inode_table = pgd->bg_inode_table;	      inode_table_sector =		start + sectors_per_block * first_inode_table;	      if (ide_read_sectors (0, inode_table_sector, buf, 1)) {		hprintf ("Inode table read error.\n");		continue;	      }	      for (j = 0; j < SECTOR_SIZE; j += INODE_SIZE) {		pinode = (ext2_inode *)(buf + j);		if ((pinode->i_mode & 0xf000) == 0x4000) {		  break;		}	      }	      if (j >= SECTOR_SIZE) {		hprintf ("Can't find root.\n");		continue;	      }	      dir_entry_table_sector =		start + sectors_per_block * pinode->i_block[0];	      if (ide_read_sectors		  (0, dir_entry_table_sector, buf, sectors_per_block)) {		hprintf ("Root directory entry read error.\n");		continue;	      }	      for (pde = (ext2_dir_entry *)buf;		   (addr_t)pde - (addr_t)buf <=		     SECTOR_SIZE * sectors_per_block - 12;		   pde = (ext2_dir_entry *)(((addr_t)pde) + pde->rec_len)) {		if (!pde->rec_len) {		  break;		}		if (pde->name_len == 4) {		  if (pde->name[0] == 'b' && pde->name[1] == 'o' &&		      pde->name[2] == 'o' && pde->name[3] == 't') {		    break;		  }		}	      }	      if ((addr_t)pde - (addr_t)buf >		  SECTOR_SIZE * sectors_per_block - 12) {		hprintf ("Can't find /boot\n");		continue;	      }	      if (!pde->rec_len) {		hprintf ("Can't find /boot\n");		continue;	      }	      group = (pde->inode - 1) / inodes_per_group;	      inode = (pde->inode - 1) % inodes_per_group;	      inode_table_sector = start + sectors_per_block *		(blocks_per_group * group + first_inode_table) +		inode / (SECTOR_SIZE / INODE_SIZE);	      if (ide_read_sectors (0, inode_table_sector, buf, 1)) {		hprintf ("Inode table read error.\n");		continue;	      }	      pinode = (ext2_inode *)		(buf + INODE_SIZE * (inode % (SECTOR_SIZE / INODE_SIZE)));	      if ((pinode->i_mode & 0xf000) != 0x4000) {		hprintf ("/boot is not directory.\n");		continue;	      }	      dir_entry_table_sector =		start + sectors_per_block * pinode->i_block[0];	      if (ide_read_sectors		  (0, dir_entry_table_sector, buf, sectors_per_block)) {		hprintf ("/boot directory entry read error.\n");		continue;	      }	      for (pde = (ext2_dir_entry *)buf;		   (addr_t)pde - (addr_t)buf <=		     SECTOR_SIZE * sectors_per_block - 16;		   pde = (ext2_dir_entry *)(((addr_t)pde) + pde->rec_len)) {		if (!pde->rec_len) {		  break;		}		if (pde->name_len == 5 || pde->name_len == 8) {		  if (pde->name[0] == 'I' && pde->name[1] == 'm' &&		      pde->name[2] == 'a' && pde->name[3] == 'g' &&		      pde->name[4] == 'e') {		    if (pde->name_len == 5) {		      gzimage = 0;		      break;		    }		    if (pde->name[5] == '.' && pde->name[6] == 'g' &&			pde->name[7] == 'z') {		      gzimage = 1;		      break;		    }		  }		}	      }	      if ((addr_t)pde - (addr_t)buf >		  SECTOR_SIZE * sectors_per_block - 16) {		hprintf ("Can't find /boot/Image(.gz)\n");		continue;	      }	      if (!pde->rec_len) {		hprintf ("Can't find /boot/Image(.gz)\n");		continue;	      }	      group = (pde->inode - 1) / inodes_per_group;	      inode = (pde->inode - 1) % inodes_per_group;	      inode_table_sector = start + sectors_per_block *		(blocks_per_group * group + first_inode_table) +		inode / (SECTOR_SIZE / INODE_SIZE);	      if (ide_read_sectors (0, inode_table_sector, buf, 1)) {		hprintf ("Inode table read error.\n");		continue;	      }	      pinode = (ext2_inode *)		(buf + INODE_SIZE * (inode % (SECTOR_SIZE / INODE_SIZE)));	      if ((pinode->i_mode & 0xf000) != 0x8000) {		hprintf ("/boot/Image%s is not file.\n",			 (!gzimage) ? "" : ".gz");		continue;	      }	      file_size = pinode->i_size;	      if (file_size <= 0) {		hprintf ("/boot/Image%s size is zero.\n",			 (!gzimage) ? "" : ".gz");		continue;	      }	      if (file_size > INITRD_LOAD_ADDRESS - LINUX_LOAD_ADDRESS) {		hprintf ("/boot/Image%s size is too large.\n",			 (!gzimage) ? "" : ".gz");		continue;	      }	      hprintf ("/boot/Image%s is found.\n",		       (!gzimage) ? "" : ".gz");	      for (j = 0; j < 15; j++) {		file_block[j] = pinode->i_block[j];	      }	      load_address =		(!gzimage) ? LINUX_LOAD_ADDRESS : INITRD_LOAD_ADDRESS;	      hprintf ("Copying        kernel");	      if (copy_file (12, file_block, start,			     sectors_per_block, &file_size, &load_address)) {		hprintf ("/boot/Image%s data read error.\n",			 (!gzimage) ? "" : ".gz");		continue;	      }	      if (file_size <= 0) {		gunzip_kernel = 0;		break;	      }	      file_data_sector =		start + sectors_per_block * file_block[12];	      if (ide_read_sectors		  (0, file_data_sector, buf, sectors_per_block)) {		hprintf ("/boot/Image%s data read error.\n",			 (!gzimage) ? "" : ".gz");		continue;	      }	      addr_per_block =		(SECTOR_SIZE * sectors_per_block) / sizeof(unsigned long);	      if (copy_file (addr_per_block, (unsigned long *)buf, start,			       sectors_per_block, &file_size, &load_address)) {		hprintf ("/boot/Image%s data read error.\n",			 (!gzimage) ? "" : ".gz");		continue;	      }	      if (file_size <= 0) {		gunzip_kernel = 0;		break;	      }	      file_data_sector =		start + sectors_per_block * file_block[13];	      if (ide_read_sectors		  (0, file_data_sector, buf2, sectors_per_block)) {		hprintf ("/boot/Image%s data read error.\n",			 (!gzimage) ? "" : ".gz");		continue;	      }	      for (j = 0; j < addr_per_block && file_size > 0; j++) {		file_data_sector =		  start + sectors_per_block * *(((unsigned long *)buf2) + j);		if (ide_read_sectors		    (0, file_data_sector, buf, sectors_per_block)) {		  hprintf ("/boot/Image%s data read error.\n",			   (!gzimage) ? "" : ".gz");		  break;		}		if (copy_file (addr_per_block, (unsigned long *)buf, start,				 sectors_per_block, &file_size,				 &load_address)) {		  hprintf ("/boot/Image%s data read error.\n",			   (!gzimage) ? "" : ".gz");		  break;		}	      }	      if (file_size <= 0) {		gunzip_kernel = 0;		break;	      }	      hprintf ("/boot/Image%s size is too large.\n",		       (!gzimage) ? "" : ".gz");	      continue;	    }	    IO_LEDFLSH = 0x0;	    if (gunzip_kernel) {	      return (0);	    }	    hprintf ("done.\n");	    if (gzimage) {	      boost_on ();	      gunzip_object		(" kernel", INITRD_LOAD_ADDRESS, LINUX_LOAD_ADDRESS);	      boost_off ();	    }	    argc = sizeof (cf_option) / sizeof (char *);	    root[sizeof (root) - 2] = '1' + i;	    argv = cf_option;	  }	}	if (argc < 1)		return -H_EUSAGE;		boost_on ();	if (gunzip_kernel) {	  gunzip_object (" kernel", LINUX_SRC_ADDRESS, LINUX_LOAD_ADDRESS);	}	{	  int c = argc;	  char **v = argv;	  while (--c > 0) {	    if (!strcmp (*++v, "noinitrd")) {	      break;	    }	  }	  if (c <= 0) {	    gunzip_object ("ramdisk", INITRD_SRC_ADDRESS, INITRD_LOAD_ADDRESS);	  } else {	    bytes_out = 0;	  }	}	boost_off ();	linux_cmdfunc (argc, argv);	return 0;}const command_t linux_command =	{ "linux", "<linux options>", "start Linux", &linux_cmdfunc };const command_t boot_command =	{ "boot", "", "boot default Linux kernel and ramdisk", &boot_cmdfunc };

⌨️ 快捷键说明

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