📄 linux.c
字号:
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 + -