rendered paste body/* main.c * * David R.S. Robinson <rylandr@wsu.edu> * 10716615 * * Main driver for lab #2. * */#include "main.h"#define NULL ((void *) 0x0)static uint8 buffer[1024];static void get_block (uint16 block, char *buf) /* 82 */{ register uint16 linear_sector; register uint16 cylinder, head, sector; linear_sector = block + block; cylinder = linear_sector / 36; head = (linear_sector % 36) / 18; sector = ((linear_sector % 36) % 18) + 1; diskr (cylinder, head, sector, buf);}static ext2_inode *get_inode (uint16 i_num) /* 52 */{ register uint16 inode_per_block = 8; /* i_num >> 3 == i_num / inode_per_block == i_num / 8 */ get_block(BLOCK_INODE_TABLE + (i_num >> 3), buffer); return ((ext2_inode *) buffer) + (i_num % inode_per_block) - 1;}static uint16 dir_search (ext2_inode *inode, char *filename){ uint16 data_block; uint16 blocks_remain = (uint16) inode->i_blocks >> 1; /* Ensure it's a directory. */ if (inode->i_mode & 0x4000) { /* Search through the direct data blocks, looking for our file. */ for (data_block = 0; data_block < blocks_remain; data_block++) { ext2_dir_entry_2 *dentry = buffer; /* Read in the directory block. */ get_block((uint16) inode->i_block[data_block], buffer); while (dentry < (buffer + sizeof (buffer))) {#ifdef DEBUG /* Check the dentry for what we want. */ dentry->name[dentry->name_len] = 0x0;#endif if (!strcmp(dentry->name, filename)) return (uint16) dentry->inode; /* Move to the next dentry. */ dentry = ((uint8 *) dentry) + dentry->rec_len; } } } return 0;}static void load_image(ext2_inode *image_inode){ static uint32 indirect_buffer[256]; static uint32 double_indirect_buffer[256]; uint16 blocks_remain, block; /* * image_inode->i_blocks >> 1 == image_inode / 2 * * We do this because i_blocks is measured in 512-blocks, and we care about * 1024 blocks. */ blocks_remain = image_inode->i_blocks >> 1; /* * Load in the indirect and double-indirect buffer, if necessary. * * We only retrieve the first double-indirect block, because anymore than * that cannot be loaded as a kernel. */ if (blocks_remain > 12) get_block((uint16) image_inode->i_block[12], indirect_buffer); if (blocks_remain > (12 + 256)) { get_block((uint16) image_inode->i_block[13], double_indirect_buffer); get_block((uint16) *double_indirect_buffer, double_indirect_buffer); } /* Read in those blocks! */ for (block = 0; block < blocks_remain; block++) { if (block == 0) /* Direct blocks 0 - 4 to 0x90000. */ set_es(0x9000); else if (block == 4) /* Blocks 5+ to 0x10000. */ set_es(0x1000); if (block < 12) get_block(image_inode->i_block[block], 0x0); else if (block < (12 + 256)) get_block((uint16) indirect_buffer[block - 12], 0x0); else get_block((uint16) double_indirect_buffer[block - (12 + 256)], 0x0); inc_es(); }}uint16 main (void){ uint16 i_num; resetVideo (); /* Search for /sys/linux from the root inode. */ if (i_num = dir_search(get_inode(EXT2_ROOT_INODE), "sys")) { if (i_num = dir_search(get_inode(i_num), "linux")) { load_image(get_inode(i_num)); return 0; } } return 1; /* Error. */}/* vim:et:sta:set ts=8 sw=2: */