Submit: Turn in your
kprintf.c
and main.c
source files using the
turnin command on morbius.mscsnet.mu.edu or
one of the other
Systems Lab machines.
Work should be completed in pairs. Be certain
to include both names in the comment block at the top of all
source code files. It would be courteous to confirm with your
partner when submitting the assignment. You may modify any files
in the operating system, but only changes
to kprintf.c
and main.c
will be graded
for this assignment.
You will have to familiarize yourself with several new UNIX tools for this assignment. These consist of:
make
command, and arm-console
to execute your kernel image on an embedded backend device.
The source tarball we are starting with contains only a few files for the operating system proper, in the subdirectory system. We will be adding files into this directory in every subsequent assignment.
The other files in the Embedded Xinu subdirectories break down as follows:
Your task for this assignment is to write a simple synchronous serial driver for the embedded operating system, so that you can see what you are doing in all subsequent assignments.
The driver is "synchronous" because it waits for the slow I/O device to do its work, rather than using interrupts to communicate with the hardware.
The driver is "serial" because it sends characters one at a time down an RS-232 serial port interface, like the one found on most modern PC's.
The driver is a "driver" because it provides the software interface necessary for the operating system to communicate with the hardware which, in this case, is an I/O device.
This platform's serial port, or UART (Universal Asynchronous Receiver / Transmitter) is a member of the venerable 16550 family of UARTs, documented here. Of particular interest to us is section 3.3.3 of the specification, which describes the registers accessible to programmers. On this platform (Raspberry Pi 3 B+), the PL011 UART control and status registers are memory-mapped, starting with base address 0x3F201000. You can view these address definitions in include/bcm2837.h
The file system/kprintf.c has the skeleton code for three I/O-related functions: kputc(), (puts a single character to the serial port,) kgetc(), (gets a single character from the serial port,) and kcheckc() (checks whether a character is available.) Each function contains a "TODO" comment where you should add code. The actual kprintf() is already complete; it will begin working as soon as you complete the kputc() function upon which it relies.
The file main/main.c
should be modified to run a
simplified version of your codebreaker solution from the previous
assignment. To keep things simple, let us assume a maximum input of
128 characters. (If you go larger than this, you may run into
memory allocation issues with the very simple runtime we're starting with
for this assignment.)
Notes:
'\n'
in your C
code. When working with a serial port, two separate ASCII
characters must be sent to accomplish a typical newline.
The '\n'
or "newline" character (ASCII value 10)
only advances the cursor one line. A second
character, '\r'
, or "carriage return" (ASCII value
13), is also necessary to return the cursor to the far left
column. As a result, a completed version of
the kputc()
function
in system/kprintf.c
should send two characters to
the serial port UART hardware whenever a '\n'
is
seen -- first a '\r'
, and then
the '\n'
.
EOF
marker requires special handling on the
input handling of the serial driver. When a user types Ctrl-D
on the serial port, the actual ASCII value sent is value 4, or
the EOT ("end of transmission") marker from the old days of
modems. A completed version of the kgetc()
function in system/kprintf.c
should watch for the
ASCII EOT value, and return the special operating system
constant EOF
when it encounters this special
symbol.
printf()
and getchar()
functions, you will now need to use
kprintf()
and kgetc()
. We may build
real version of printf()
and getchar()
for your embedded operating system later
in the semester, but for now just understand that their behavior
is subtly more complex than what we can build right at the start.
kprintf()
calls while you are developing, or just keep
your test inputs short.
[Revised 2022 Feb 09 23:52 DWB]