Implement Your Own Operating System (week 03)

Kasun Madhumal
5 min readAug 6, 2021

--

With the earliest computers, from the late 1940s to the mid-1950s, the programmer interacted directly with the computer hardware, there was no OS. These computers were run from a console consisting of display lights, toggle switches, some form of the input device, and a printer. Programs in machine code were loaded via the input device (e.g., a card reader).

This article will introduce how to display text on the console just as composing data to the serial port . Moreover, we will make our first driver, that is, code that goes about as a layer between the kernel and the hardware, giving a higher deliberation than discussing straightforwardly with the hardware.

I try to discuss this article under the two main topics :

  • The first part of this chapter is about creating a driver for the framebuffer to be able to display text on the console.
  • The second part shows how to create a driver for the serial port.

Note: This is the week 03 article of the “implement Your Own Operating System” article series. If you are new to this article series, please study the previous articles.

The Framebuffer

frame buffer An area of memory used to store information related to the pixels of a display. A frame buffer for a color display has a set of planes each defining one bit of the color information of each point. Typically a color display will have a frame buffer with up to 24 planes, 8 each for defining red, green, and blue values (see RGB color model).

Writing Text

Writing text to the console via the framebuffer is done with memory-mapped I/O. The starting address of the memory-mapped I/O for the framebuffer is 0x000B8000 . The memory is divided into 16 bit cells, where the 16 bits determine both the character, the foreground color and the background color.

The following code shows how this can be wrapped into a function:

The function can then be used as follows:

Moving the Cursor

Moving the cursor of the framebuffer is done via two different I/O ports.The framebuffer has two I/O ports, one for accepting the data, and one for describing the data being received. Port 0x3D4 is the port that describes the data and port 0x3D5 is for the data itself.

The out assembly code instruction can’t be executed directly in C. Therefore it is a good idea to wrap out in a function in assembly code which can be accessed from C via the cdecl calling standard :

By storing this function in a file called io.s and also creating a header io.h, the out assembly code instruction can be conveniently accessed from C:

The Driver

The driver should provide an interface that the rest of the code in the OS will use for interacting with the framebuffer.

Below are the complete codes for the frame_buffer.c and frame_buffer.h files.

frame_buffer.c

frame_buffer.h

fb_write( ), serial_configure( ),serial_write( ) functions are calling from kmain.c file. Therefore we want to update kmain.c file.

kmain.c file

also we want to make io.s file and io.h file. Below are the complete codes for the io.s and io.h files.

io.s

io.h

The Serial Ports

The serial port is an interface for communicating between hardware devices and although it is available on almost all motherboards, it is seldom exposed to the client in the form of a DE-9 connector nowadays. The serial port is not difficult to utilize, and, more importantly, it can be utilized as a logging utility in Bochs . If a computer has support for a serial port, then, at that point it for the most part has support for multiple serial ports, however we will only utilize one of the ports. This is on the grounds that we will only utilize the serial ports for logging. Furthermore, we will only utilize the serial ports for output, not input. The serial ports are completely controlled via I/O ports.

Configuring the Serial Port

The first data that need to be sent to the serial port is configuration data. In order for two hardware devices to be able to talk to each other they must agree upon a couple of things. These things include:

  • The speed used for sending data (bit or baud rate)
  • If any error checking should be used for the data (parity bit, stop bits)
  • The number of bits that represent a unit of data (data bits)

Configuring the Line

Configuring the line means to configure how data is being sent over the line. The serial port has an I/O port, the line command port, that is used for configuration.

An example is shown below:

We will use the mostly standard value 0x03 , meaning a length of 8 bits, no parity bit, one stop bit and break control disabled. This is sent to the line command port, as seen in the following example:

Writing Data to the Serial Port

Writing information to the serial port is done via the information I/O port. However, before writing, the transmit FIFO queue must be unfilled (all previous writes more likely than not finished). The transmit FIFO queue is unfilled if bit 5 of the line status I/O port is equivalent to one.

Reading the contents of an I/O port is done via the in assembly code instruction. It is basically impossible to utilize the in assembly code instruction from C, therefore it must be wrapped (the same way as the out assembly code instruction):

Checking if the transmit FIFO is empty can then be done from C:

Below are the complete codes for the serial_port.c and serial_port.h files.

serial_port.c

serial_port.h

Configuring Bochs

To save the output from the first serial serial port the Bochs configuration file bochsrc.txt must be updated. The com1 configuration instructs Bochs how to handle first serial port:

com1: enabled=1, mode=file, dev=com1.out

bochsrc.txt file after adding new codes

The output from serial port one will now be stored in the file com1.out.

after the implementation you can see this output:

Hope you all get good idea on how to display text on the console as well as writing data to the serial port.

Reference: Helin, E., & Renberg, A. (2015). The little book about OS development

Thank you for reading….

— Kasun Madhumal —

--

--

Kasun Madhumal
Kasun Madhumal

Written by Kasun Madhumal

software engineering student (university of kelaniya)

No responses yet