This page contains information about the projects.

Check out this movie to learn about how to set up the provided development environment and how to solve Machine Problem 1 on a Windows, Linux, MacOS machine running on an Intel x86 compatible processor.

For students who only have access to machines with processors that are not compatible with the Intel x86 processor, including Mac M1 machines, see below for information about how to use university resources to access a development environment.

To set up the development image, perform the following steps. This movie walks you through the detailed steps of setting up the environment and solving Project 1.

If you are interested in accessing files from both your host machine and the Linux virtual machine in VirtualBox, check out the following links for information on how to set up shared folders.

Note: Some students prefer to set up their own development environments. (Some students even managed to set up a development environment using Visual Studio.) If you do so, most of the documentation that we provide and much of the provided support files (such as the make file, the linker script, and the scripts to copy the kernel onto a bootable device) will likely not work for you. Also, if things don't work, do not expect much sympathy or help from TA or instructor. So, set up your own development environment only if you know what you are doing. Otherwise, use the provided image! (That said, we will give some information in the FAQ on how to install a development environment on native MacOS. A very similar procedure can be used to install the development environment on native Linux.)

This is recommended only for students who do not have access to an Intel x86 compatible machine. One such case is students who own Mac/Silicon's, and who do not have access to an Intel-compatible machine. (If you have a Mac/Silicon, it may be more convenient to install the development environment natively on your machine instead of using the university-provided environment. See below for step-by-step instructions to install the development environment on MacOS.)

Access to a pre-configured virtual development environment can be done through VMware Horizon Client. A description of how to install the Horizon Client and access the development environment can be found here (Links to an external site.). The guide also contains information of how to share files and other functionalities.

Once you have installed the Horizon Client, you connect to coe-connect.engr.tamu.edu, and you should see a button called "CSCE 410/611 Desktop". Click on the button, and you see an Ubuntu login screen. You log in with user name csce410 and the same password as the one listed above for for the virtual box image. Note that these virtual machines are not persistent! If a user logs out, or disconnects for more than a day, the virtual machine will be destroyed and recreated. This means that you lose all your files stored on the virtual machine. Files can be transferred between a user's computer and the box as long as they are using the VMware Horizon Client (as opposed to the web client). Alternatively, users can download/upload files to any cloud storage (e.g. Google Drive, Github). This is a great incentive to use GitHub!!

We have good news for Mac/Silicon users! If you don't want to use the University provided development environment (which is -- admittedly -- a pain to use) see below for information about how to set up the development environment natively on your Mac. 

Kudos to Caleb Norton, a student in a previous semester, who found and described the following procedure to set up the development environment on Silicon Macs: 

We have tested out the steps described below. If you're following along and something doesn't work, post a new reply and we can investigate.

How to Install the Native Development Environment on a Silicon Mac:

Step 1: install homebrew (https://brew.sh/) Follow the directions to set up your macOS Xcode tools as well, if needed.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Step 2: install nasm, qemu, and bochs
brew install nasm qemu bochs
Step 3: add i386 toolchain formulae 
brew tap nativeos/i386-elf-toolchain
Step 4. install i386-elf-binutils and i386-elf-gcc
brew install i386-elf-binutils i386-elf-gcc

Note that some of these steps take quite a while. You may want to grab a coffee...

Now you should be able to type make to generate the binary for the kernel. 

Type make clean to delete all binaries and object files.

A Substitute for the copykernel.sh Script:

The provided shell script copykernel.sh copies the kernel binary onto an image of a bootable floppy drive (anybody remembers floppy drives?). For this, the script first mounts the image as a floppy, then copies the binary onto the floppy, and then unmounts the image again. Now you tell bochs to boot off the floppy, which contains the bootloader and the kernel binary. 

The script copykernel.sh provided with the MP source code has been developed for Linux and does not work on MacOS!

If you use the native development environment on a Mac, use the following script instead (again, kudos to Caleb Norton!): 

mkdir ./floppy
hdiutil attach dev_kernel_grub.img -mountpoint ./floppy
cp kernel.elf ./floppy
sleep 1
hdiutil detach ./floppy
rmdir ./floppy

Starting bochs on MacOS:

On the Mac you will need to configure bochs to open a bochs console. You do this by adding a line to the bochsrc.bxrc configuration file as described here: 

#display_library: wx
# other choices: win32 sdl wx carbon amigaos beos macintosh nogui rfb term svga
# ADD THE FOLLOWING LINE FOR MAXOS:
display_library: sdl2

Executing bochs on MacOS is slightly cumbersome.

You start bochs in the same fashion as on Linux:

 
bochs -f bochsrc.bxrc

Once you have started bocks, you will to type "6" for the emulation to start. The execution of bochs then seems to hang; you need to type "c" for "continue".

Now you should see the console of a booting x86 machine!

We will be testing the kernels by using them to boot a virtual machine. The preferable environment for this is Bochs. You are free to use other virtual-machine environments. We prefer Bochs because it is light-weight (albeit maybe slow) and because it emulates the hardware very accurately.

Bochs is a highly portable open source IA-32 (x86) PC emulator written in C++, that runs on most popular platforms. It includes emulation of the Intel x86 CPU, common I/O devices, and a custom BIOS. Bochs can be compiled to emulate many different x86 CPUs, from early 386 to the most recent x86-64 Intel and AMD processors, even those not in the market yet.

Additional information about how to use Bochs in this project, and how to set it up to support debugging using gdb, can be found in the following documents:

Note that, since there are several slightly different ways to integrate gdb with Bochs, the TA and instructor won't be able to be helpful in debugging your installation. If you plan to add debugging support, you will be on your own.

You may be asked to create a github repository for your 410/611 projects. If the course requires you to use github, you will receive information from the TA about how to set up your github repository. If you are not familiar with github, there are plenty of good tutorials out there.

The use of a version control system like github is beneficial in many ways. For example, the history of your git actions is a documentation of your development process. As you work on an MP and develop code, you commit new versions of files. If you diligently do that, with meaningful explanations in your commit messages, this naturally documents the development of your code. Commit frequently! Introducing lots of code and lots of changes in a single git action is not, in general, a good software practice. Working with github has other benefits. For example, if the project submission system on Canvas is not working, you won’t need to sweat about proving that you finished the project within the deadline: the git history will prove that you had concluded it. Finally, a good github commit record will be helpful in the unlikely case that you need to prove that you developed your code without violating the Aggie Honor Code.

Grading Criteria:

The general grading criteria and their weights are listed below. This list is a guideline; some MPs - most prominently MP1 - will deviate from this list.

Turnin suggestions for Machine Problems:

Q: 'make' does not work!
If typing 'make' gives you a message make: Nothing to be done for 'all', do a make clean, followed by make.

How do I copy the image to the floppy image?
Mounting an .img file makes it available as a drive. If you copy/modify files in this drive, you are updating the corresponding .img file. Think of the parallel as a floppy drive. The .img is the floppy disk. Inserting the floppy disk into the drive is performed by mounting the image (.img file). Now you can make changes to the drive. (This changes the contents of the .img file) When you are done making changes, you remove the floppy disk by unmounting the image (.img file)

Q: Are we supposed to use shared folders in our virtual machine?
A: This is not required. Some people like to be able to share files with their host OS, but this can be achieved with other means, such as GitHub, or Dropbox, or others.

Q: I keep getting a strange error: "Error 13: Invalid or unsupported executable format" What can I do?
A: In the past, this error has happened when the kernel binary was not correctly copied over to the floppy image. Also, some people are using newer compilers, which need the -fno-asynchronous-unwind-tables option in the makefile. Check out documentation for details. Other students have had success by changing the linking command in the makefile, from
  ld -m elf_i386 ...
to
  ld -m i386linux ...

Q: When I run copykernel.sh it gives me an error!
If you see the following error:
  mount: mount point /mnt/floppy does not exists 
  cp: cannot create a regular file '/mnt/floppy/': Not a directory 
  umount: /mnt/floppy: mountpoint not found
  
A: Run
  mkdir /mnt/floppy
Then run
  kopykernel.sh

Mouse stopped working in Virtualbox!
Q: I had not changed any settings but suddenly the mouse stopped capturing clicks. I can move the mouse around the screen, but after opening any window (browser, Files, etc.) I cannot click inside the window.
A: Try restarting your whole computer. It could be a library file in virtualbox and unloading the dlls might help it reset everything.

Strange linker errors
Q: So I have a mask set up for my bitmap, and when I declare them I get linker errors on compilation. Code:
  int mask[] = {128, 64, 32, 16, 8, 4, 2, 1};
Error:
  cont_frame_pool.o: In function `__static_initialization_and_destruction_0':
  /usr/include/c++/4.8/iostream:74: undefined reference to `__ZNSt8ios_base4InitC1Ev'
  /usr/include/c++/4.8/iostream:74: undefined reference to `___dso_handle'
  /usr/include/c++/4.8/iostream:74: undefined reference to `__ZNSt8ios_base4InitD1Ev'
  /usr/include/c++/4.8/iostream:74: undefined reference to `___cxa_atexit'
A: You are probably including iostream in your code. This makes for some exciting linking. Remember that we are on an island!

Error 15 when trying to boot my kernel!
Q: I get an error
  Filesystem type is fat, using whole disk /kernel.bin 
  Error 15: File not found 
A: You may have forgotten to copy the kernel onto the floppy image.

Try to set breakpoint in GDB
Q: I am getting this error while trying to set breakpoint using GDB:
  (gdb) b main()
  Function "main()" not defined.
  Make breakpoint pending on future shared library load? (y or [n]) n
  (gdb) b kernel.C:35
  No symbol table is loaded. Use the "file" command.
  Make breakpoint pending on future shared library load? (y or [n])
I have modified the makefile and compiled it again to generate the kernel.elf file. Is there anything I am missing here???
A: It looks like even though you may have connected to the running process, you never actually told gdb what file you're debugging. In your case, you'll want to run gdb with your filename as the parameter:
  gdb kernel.elf
Then once you are in gdb, you can connect to the port and whatnot. Alternatively, after starting gdb and before targeting the remote port, you can type the command:
  file kernel.elf
This has the same effect as sending the filename as a parameter when starting gdb.

Exception Nr. 6 after reset?
Q: If I hit the "Reset" button after the tests complete, I encounter Exception 6, which seems to correspond with "Invalid Opcode". Has anyone else encountered this? Or does anyone know what this indicates?
A: Exception 6 on the x86 is caused by the execution of an invalid opcode.
This means that the CPU tries to execute code that makes no sense. Not sure what causes this when you press RESET. Fortunately this problem is easy to avoid: simply power off the Bochs machine rather than resetting it...

Error when running copykernel.sh
Q: When I run sudo ./copykernel I get an error:
is not a directory/mnt/floppy
sleep : invalid time interval '1s\r'
Try sleep -- help for more information 
: not mountedfloppy 
What does that mean?
A: This means that you have the file saved in CRLF mode, i.e. It has '\r\n' endings instead of '\n'
This is caused by working in a windows environment and saving the file as such, OR sometimes pushing to Git in a windows environment will auto-change the file endings to CRLF.
To fix this, I use atom as an editor and I can change the file ending type, but otherwise I would just simply look up how to change the file endings in a Unix environment.

Compilation Requirements
Q:The instructions for the machine problems say that code compilation is usually 35% of the grade. Is this saying that the code needs to compile on the provided virtual machine?
Unfortunately the provided virtual machine is using an ancient version of GCC (4.6.3), which, for example, does not recognize the C++11 standard. Are we stuck with whatever is on the virtual machine, or are we permitted to use newer tools/standards?
A: The code has to compile on the virtual machine.
I agree that the compiler is ancient, but students who try newer versions always end up spending a lot time of time fiddling with little differences in the compiler setup, because one thing or the other does not work.
The code that we will be writing is trivial, and it will not be using STL or similar. So the C++11 issue will not be that important.

HELP! I want to use printf() and my program does not link!
A: You cannot use printf(). This function is part of a library that we don't have access to. Use Console::puts and Console::puti instead.

HELP! My assert() does not work!
Q: Scenario: The values in the two variables a and b are different, but
  assert(a=b);
does not throw an assertion error.
A: a=b does not compare a and b! Instead, it assigns the value of b to a. This always succeeds. Instead, use the statement
  assert(a==b);

Bochs output to file
Q: How can I send my output in bochs to a terminal or to a file?
A: There is a way to have bochs generate output to the terminal that runs bochs.
  • Step 1. Add the following line to the bochsrc config file:
      port_e9_hack: enabled=1
    
  • Step 2. Send the desired output to Port 0xe9:
      Machine::outportb(0xe9, 'H');
      Machine::outportb(0xe9, 'e');
      Machine::outportb(0xe9, 'l');
      Machine::outportb(0xe9, 'l');
      Machine::outportb(0xe9, 'o');
      Machine::outportb(0xe9, '\n');
    
  • Hint: It's probably best to add the outportb command to the console code.
  • Hint2: This trick sends the output to the terminal. To send the output to a file, simply redirect the output when you start bochs; e.g.
      $ bochs -f bochsrc.bxrc > myoutput.txt
    
For details, check the documentation for bochs at http://bochs.sourceforge.net/doc/docbook/user/bochsrc.html