Study Guide for Hardware-Level Programming for CS644 CS644 is a class in OS kernel programming, so we write kernel code with the help of an online small OS called Xinu that we have full sources for. An OS runs right on the hardware, and turns the various devices into OS services that are easier to use. Thus to write an OS you need to know how to program the hardware yourself. Our platform for running low-level programs is a set of stripped-down PCs we call SAPCs, for standalone PCs. Standalone means without an OS. Of course if they had no software at all on them they would be useless. We have a debugger/downloader system called "Tutor" running on them. This software derives from Linux, but only its lower layers, so it doesn't look like user-level UNIX/Linux at all. It boots up the system and leaves it for you in the state that Linux sets up for its *own* kernel code environment. Linux, like other PC UNIX kernels, and Windows XP/..., runs in 32-bit protected mode of the "x86" CPU. x86 stands for Intel 386, 486, or Pentium processors--it really makes very little difference for *programming* between these versions of x86. Their real difference lies in their execution speeds. This protected mode is vastly different from "real 16-bit mode" that almost all textbooks on PCs cover. Thus don't try to read a "random" PC book on programming for this. Since SAPCs are using a Linux-kernel-like execution environment, the CPU is in "kernel mode", the privileged mode allowing full use of the instruction set, including the privileged instructions that user-level programs are not allowed to use, since they always run in "user mode" in the CPU. (Their system calls cause transition to kernel mode.) Steps. 0. You have already put "module load ulab" in your .cshrc, so that you have some important environment variables such as pcex. You have used mtip already. 2. Read "Notes on Using C to access hardware registers", linked the the class web page. Don't worry about LPT except as an example. Read $pcinc/serial.h. Read $pcex/echo.c and run echo.lnx, its x86 executable. inpt and outpt are proto'd in $pcinc/cpu.h, with some documentation. 3. Set up a hw3 dir under cs644 and copy $pcex/makefile and *.c to it. Do "make C=echo" and see the steps for building echo.lnx. Find the compiler and the loader in the output. 4. Modify echo.c to do three echoes for each char--call it echo3.c. If you lose some, it may be because the transmitter wasn't ready yet--you need to check the UART_LSR_THRE bit (transmitter holding reg empty) and see it on before sending something to a busy transmitter. 5. Read timer.c in $pcex and timer.h in $pcinc. Build and run timer.lnx. Note there is a handout on this program. OK, now you see how to work with devices without using interrupts. Time to start on interrupts. 6. Read the class notes, and the Slides On Interrupts linked from the class web page. 7. Read and run $pcex/timetest.c and typewr.c. You'll see it's actually easier to read the programs for this than understand the hardware side. Go back to step 6 until clear. 8. Modify timetest.c to ouput an ! every 10 ticks, rather than a * on each tick: call this timetest2.c. Have it stop after 100 ticks, not after it reaches 400M loops. 9. Time to start the rest of hw2. Delivery: echo3.c echo3.script showing run of echo3 timetest2.c timetest2.script