![]() |
COS 318 : Operating system Fall 2004, Princeton University Project 1: Bootup Mechanism |
Introductory Precept: Wed 9/21, 7:30-8:30pm
Design Review: Mon 9/26, 7:30-10:30pm
Project Due: Mon 10/03, 11:59pm
Note
about lab computers:
Abstract
The purpose of this project is to write the bootup code for a simple operating system that we will be developing for the rest of the semester. Your job is to implement two programs: bootblock.s and createimage.c. The bootblock is the boot code that resides on the boot sector and its responsibility is to load the rest of the operating system image from other sectors into memory. The createimage code is a tool (in this case a Linux tool) to create a bootable operating system image including the bootblock and the rest of the operating system.
The "bootblock" and "createimage" from this assignment will be used throughout the semester.
We have provided code for project 1 for you to use as a starting point. The code can be found on the princeton machines (arizona.princeton.edu) in either /u/cos318/1_pre/* (or the tarfile /u/cos318/1_pre.tar. To untar the code type 'tar -xvf 1_pre.tar'). The 1_pre directory should contain six files:
A word about debugging: unless you are already familiar with assembly
programming, you may find debugging low-level boot code more difficult
at first. We will cover some general strategies for debugging the boot
strap in section, but you may also find it useful to use a PC simulator such
as Bochs or Qemu. More information on Bochs may be found here.
The bootblock gets loaded at memory address 0x07c0:0000. Your bootblock should load the OS starting at 0x0000:1000. In real mode, you have 640 KBytes starting at 0x0000:0000. The low memory area has some system data like the interrupt vectors and BIOS data. So, to avoid overwriting them, you should only use memory above 0x0000:1000 for this assignment.
To design and implement this, you need to learn about x86 architecture, CPU resets and how to read a sector from the USB flash drive with BIOS (described below). We have provided you with a trivial and useless kernel (kernel.s) to test whether your implementation works.
Note: You can assume that the entire OS is less or equal to
127 sectors for this project. If you are working on your home machines
rather than the lab machines, please make sure your program also run
on lab machine before submit it because your TA will be testing your
program on lab machine.
The links on the main page provide assistance in understanding x86
assembly language and architecture. The precept will also give
assistance in understanding these topics.
To test your bootblock you can use the createimage.given file.
Type './createimage.given --extended ./bootblock ./kernel' then 'cat
image > /dev/sda' to copy the image onto the USB flash disk.
Note: On the lab machines,
the USB flash disk will be detected as /dev/sda. But on other linux
machines you might have, USB flash disk could be detected as /dev/sdb
or even sd? depending on whether other SCSI devices are present in the
system. Please be careful and make sure your USB flash disk is mounted
on /dev/sda before saving the image to /dev/sda. Otherwise, you risk
ruin your file system on your exististing hard disk.
man -M man createimage
Please ignore the "-vm" option for this project.
Essentially, createimage takes a bootloader and several executables and
places them all into one image file. The bootloader must be
placed in the first sector, while all other executables should be
placed
at offset specified in the ELF header. To read an ELF file use
fopen, fread, and fseek (see man pages for descriptions). The
program header (figure 2-1 of the
ELF Documentation) contains information about each segment in the ELF
and should be used to determine the address at which to place the
segment. Be aware of the following:
You should read:
Program Submission
Submit your final solution electronically on arizona.princeton.edu using the following command:
/u/cos318/bin/318submit 1 README Makefile bootblock.s createimage.c
The submit command copies your files to the directory /u/cos318/submit/UserLogin/number and lists all the files that you have submitted for assignment number. UserLogin is your user account name. If you execute submit after the project deadline, your files are placed in directory number_late. You can run submit more than once, and you can submit partial lists of files.
Each group needs to submit only one copy. This means that only
one of you needs to submit.
So, the following code sequence writes the character 'K' (ascii
0x4b) to the top left corner of the screen.
movw 0xb800,%bx
movw %bx,%es
movw $0x074b,%es:(0x0)
This code sequence is very useful for debugging.
Called with:
ah = 2
al = number of sectors to read,
ch = cylinder number, (lowest 8 bits of the 10-bit cylinder
number, 0 based)
cl, bits 6&7 = cylinder number bits 8 and 9.
bits 0-5 = starting sector number, 1 to 63
dh = starting head number, 0 to 255
dl = drive number, (0x80 + zero based hard driver number)
(Note: use dl = 0x80 for the first hard disk. For this project, if you
want to boot USB flash disk on the lab machines, you can set dl to be
0x80 because on our lab machines, the USB flash disk will be treated as
the first bootable hard disk with dl=0x80. On other machines, this
might not be true since different BIOS could treat the USB flash disk
as different devices like floppy disk, see note below for
more information.)
es:bx = pointer where to place information read from diskette
Returns:
ah = return status (0 if successful)
al = burst error length if ah = 11; undefined on most BIOSes for
other ah return status values.
carry = 0 successful, = 1 if error occurred
Called with:
ah = 0x0e
al = character to write
bh = active page number (Use 0x00)
bl = foreground color (graphics mode only) (Use 0x02)
Returns:
character displayed
In order to get extra credits, your
bootloader will need to be able to load more than 128 sectors. In order
to do that, you will need to use another BIOS call listed below. With
that BIOS call, you will be able to get the disk parameter and then
read sector by sector to load more than 128 sectors.
This function gets the drive parameters for the specified driver.
Called with:
ah = 8
dl = driver number (0x80 + zero based hard driver number)
returns:
if successful:
ah = 0
al = undefined
carry = 0
ch = maximum cylinder number (lowest 8 bits of the 10-bits cylinder
number, 0 based)
cl, bits 6&7 = cylinder number bits 8 and 9.
bits 0-5 = maximum sector number, 1 to 63
dh = maximum head number, 0 to 255
ah = 7
carry = 1
al = cx = dx = 0
if failed (because no hard disk exists)
ah = 1
carry = 1
al = bx = cx = dx = es = 0
COS318 Staff