460 Lab #1 HELP
CS460 Lab #1 HELP
0. mtximage.gz in the samples/LAB1/ directory is a sample solution of LAB#1.
Download, gunzip and dd it to a floppy disk. Boot from the floppy disk.
The floppy disk contains an EXT2 file system, with a booter in block#0. You
may mount it under Linux to take a look at its contents. The /boot directory
contains bootable images of the MTX operating system (named mtx, image, etc.)
You only have to replace its boot block with YOUR own booter.
Also, download the assembly file boots.s and use it AS IS. It is to be
linked with a main.c to form YOUR MTX booter.
1. Logic of YOUR C code
YOUR main() function should do these:
(1). Clear screen and home cursor. (OPTIONAL:for better looking)
(2). Prompt for a filename to boot, and read in the filename;
(Assume all bootable files are in the /boot directory)
(3). Locate the file's inode, hence its disk blocks.
(4). Load the file's blocks to the segment 0x1000. While loading,
use putc('.') to show progress.
(5). return 0 if no error, else return 1;
HELP HINTS:
Use putc('1'), putc('2'),.... in your C code to help debug.
-------------------------------------------------------------
2. HOW TO LOAD disk blocks into memory:
boots.s contains a function
diskr(cyl, head, sector, buf) ushort cyl, head, sector,buf;
which calls BIOS to read the disk block at (cyl, head, sector) into memory location
(ES, buf), where (cyl, head, sector) all count from 0, and buf is an offset in the
segment ES.
In boots.s, the functions
setes(value) sets ES to any segment value, and
inces() increments ES by 0x40 (1KB in real address)
can be used to load 1KB disk blocks to contiguous memory locations.
To read a disk block, blk, into an (offset) address buf, you need to implement a
function in C
getBlock(blk, buf) ushort blk; char *buf
{
Convert blk to (cyl, head, sector);
Call diskr(cyl, head, sector, buf);
}
Mailman's Algorithm:
===================================================================
1 block = 2 sectors
s0 ... ... s17 |s18 ... ... s35
|--- head 0 ---|--- head 1----| REPEAT FOR cyl 1, cyl 2 , ....
|------------ cyl 0 ----------|
==================================================================
Figure out how to convert a blk number into (cyl, head, sector) format.
3. HOW TO FIND /boot/mtx?
Due to the 1KB size limit, you are allowed to take some short-cuts in
YOUR C code.
Examples:
(1). On a floppy disk, block size is 1KB, the inodes start block (of an EXT2
FS) is block#5, and the root inode is inode#2, i.e. NO NEED to get the
SuperBlock, GroupDescriptor, etc.
(2). You may assume a DIR has only ONE data block, which should make your
search function shorter.
3-0. Start with booting /boot/mtx by default.
3-1. Read in the root inode (as in CS360):
3-2. Search for "boot" in (data blocks of) root inode;
If found: convert i_number of "/boot" to get its inode;
3-3. Search for the "mtx" string in /boot inode.
If found: get its inode.
3-4. inode.i_block[0-11] are DIRECT blocks
inode.i_block[12] is the INDIRECT block
3-5. Loading mtx image requires changing ES. Once ES is changed, you cannot
read any disk block into the boot program area. So, you SHOULD read in the
indirect block (numbers) into memory BEFORE changing ES.
3-6. bcc generates 16-bit code, in which 32-bit operations require many MORE
instructions, hence a larger code size. For this reason, the block number
in the getBlock(blk, buf) fucntion is 16-bit or unsigned short.
However, block numbers in an EXT2 FS are 32-bit or unsigned long.
You should know how to pass the block number when calling getBlock().