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

📄 linux.c

📁 Hermit-at-1.1.3,一款bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
	  o_argc = get_option_count ();	}		{	char *o_argv[o_argc + 3];	if (argc > 1) {	  for (i = 0; i < argc; i++) {	    o_argv[i] = argv[i];	  }	}	else {	  if (o_argc <= 1) {	    o_argv[o_argc++] = console;	  }	  else {	    get_options(o_argv);	  }	}	major = RAMDISK_MAJOR;	minor = RAMDISK0_MINOR;	if (!argc) {	  if (!(*get_bbu_reg_addr(NS_BBU_GPIO_STATUS_1) &		GPIO_STATUS_1_FLASHBOOT)) {	    if (ide_detect_devices ()) {	      return 0;	    }	    led_on();	    if (ide_startup_devices ()) {	      return 0;	    }	    if (ide_read_sectors (0, 0, buf, 1)) {	      return 0;	    }	    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 (!memcmp (pde->name, "boot", 4)) {		    break;		  }		}	      }	      if ((addr_t)pde - (addr_t)buf >		  SECTOR_SIZE * sectors_per_block - 12 ||		  !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;		}		gzimage = 0;		ext = 0;		if (pde->name_len >= 5) {		  if (!memcmp(pde->name, "Image", 5) ||		      !memcmp(pde->name, "linux", 5)) {		    if (pde->name_len == 5) {		      break;		    }		    if (pde->name_len >= 9) {		      if (!memcmp(pde->name + 5, ".bin", 4)) {			ext = 4;			if (pde->name_len == 9) {			  break;			}		      }		    }		    if (pde->name_len == 5 + ext + 3) {		      if (!memcmp(pde->name + 5 + ext, ".gz", 3)) {			gzimage = 1;			break;		      }		    }		  }		}	      }	      if ((addr_t)pde - (addr_t)buf >		  SECTOR_SIZE * sectors_per_block - 16 ||		  !pde->rec_len) {		hprintf ("Can't find /boot/Image(or linux)(.bin)(.gz)\n");		continue;	      }	      memcpy (filename, pde->name, pde->name_len);	      filename[pde->name_len] = '\0';	      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 ("%s is not file.\n", filename);		continue;	      }	      file_size = pinode->i_size;	      if (file_size <= 0) {		hprintf ("%s size is zero.\n", filename);		continue;	      }	      if (file_size > INITRD_LOAD_ADDRESS - LINUX_LOAD_ADDRESS) {		hprintf ("%s size is too large.\n", filename);		continue;	      }	      hprintf ("%s is found.\n", filename);	      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 ("%s data read error.\n", filename);		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 ("%s data read error.\n", filename);		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 ("%s data read error.\n", filename);		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 ("%s data read error.\n", filename);		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 ("%s data read error.\n", filename);		  break;		}		if (copy_file (addr_per_block, (unsigned long *)buf, start,				 sectors_per_block, &file_size,				 &load_address)) {		  hprintf ("%s data read error.\n", filename);		  break;		}	      }	      if (file_size <= 0) {		gunzip_kernel = 0;		break;	      }	      hprintf ("%s size is too large.\n", filename);	      continue;	    }	    if (gunzip_kernel) {	      return 0;	    }	    hprintf ("done.\n");	    if (gzimage) {	      boost_on (BOOST_LINUX_MODE);	      gunzip_object		(" kernel", INITRD_LOAD_ADDRESS, LINUX_LOAD_ADDRESS);	      boost_off ();	    }	    major = IDE0_MAJOR;	    minor = 1 + i;	  }	}	argc = o_argc;	argv = o_argv;	if (argc < 1)		return -H_EUSAGE;	led_on();		boost_on (BOOST_LINUX_MODE);	if (gunzip_kernel) {	  gunzip_object (" kernel", LINUX_SRC_ADDRESS, LINUX_LOAD_ADDRESS);	}	if (major == RAMDISK_MAJOR) {	  gunzip_object ("ramdisk", INITRD_SRC_ADDRESS, INITRD_LOAD_ADDRESS);	}	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 + -