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

📄 linux.c

📁 Hermit-at-1.1.3,一款bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
	else {	  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 (!(IO_GPIO_PBDR & PBDR_FLASHBOOT)) {	    for (d = 0; d < IDE_MAX_DEVICES; d++) {	      if (ide_detect_devices (d)) {		continue;	      }	      if (ide_startup_devices ()) {		continue;	      }	      if (ide_read_sectors (0, 0, buf, 1)) {		continue;	      }	      IO_GPIO_PEDR = 0x1;	      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/hd%c%d: start=0x%x, size=0x%x\n",			 'a' + (d << 1), 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;	      }	      IO_GPIO_PEDR = 0x0;	      if (gunzip_kernel) {		continue;	      }	      hprintf ("done.\n");	      if (gzimage) {		boost_on (BOOST_LINUX_MODE);		gunzip_object		  (" kernel", INITRD_LOAD_ADDRESS, LINUX_LOAD_ADDRESS);		boost_off ();	      }	      major = (d ? IDE1_MAJOR : IDE0_MAJOR);	      minor = 1 + i;	      break;	    }	    if (d >= IDE_MAX_DEVICES) {	      return 0;	    }	  }	}	argc = o_argc;	argv = o_argv;	argv[argc++] = mtdparts;	if (argc < 1)		return -H_EUSAGE;		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 + -