Professional Documents
Culture Documents
1. Objective
● This is an optional homework, if you do it you’ll earn 20 points that are added to your
homework grade. Limited support will be provided, the lead on this assignment is Hussein
Banjak.
● The objective is to learn how to write your very own kernel from scratch and then boot up
into it.
2. Prerequisites
● switch to root using ( sudo -i ) and install the following packages:
● binutils, gcc, grub-common, make, nasm, xorriso.
● The following code should be written to and saved in a file named boot.asm. You should
store the file in the dedicated working directory for the project.
bits 32
section .text
global start
extern main ;defined in the C file
start:
cli ;block interrupts
mov esp, stack_space ;set stack pointer
call main
hlt ;halt the CPU
section .bss
resb 8192 ;8KB for stack
stack_space:
Faculty of Arts & Sciences
Department of Computer Science
CMPS 272—Operating System
Fall 2020–2021
HW3: Due Mon, Nov 2, 2020 @ 11:00 AM
● So, you wrote your boot code, and your boot code knows that there is an external main
function it needs to load into, but you don't have an external main function. Create a file in
the same working directory, and name it kernel.c.
The following code will first print “Hello from CMPS 272!” then start taking user input.
It accepts only letters, enter for processing command and space for terminating.
The only command that our shell understands is “whatami” which will print “I am the CMPS
272 shell”.
After terminating, the shell will print “Goodbye from CMPS 272”.
#define MAX_LINE_LENGTH 10
char* command[MAX_LINE_LENGTH];
unsigned int command_length = 0;
char whatami[7] = "whatami";
void clear_screen(void)
{
int index = 0;
/* there are 25 lines each of 80 columns;
each element takes 2 bytes */
while (index < 80 * 25 * 2) {
terminal_buffer[index] = ' ';
index += 1;
}
next_line_index = 1;
}
void print_new_line()
{
if(next_line_index >= 24){
next_line_index = 0;
clear_screen();
}
vga_index = 80*next_line_index;
next_line_index++;
}
Faculty of Arts & Sciences
Department of Computer Science
CMPS 272—Operating System
Fall 2020–2021
HW3: Due Mon, Nov 2, 2020 @ 11:00 AM
terminal_buffer[vga_index] = (unsigned
short)c|(unsigned short)color << 8;
vga_index++;
}
if(keycode == KEY_A){
return 'a';
}
else if(keycode == KEY_B){
return 'b';
}
else if(keycode == KEY_C){
return 'c';
}
else if(keycode == KEY_D){
return 'd';
}
else if(keycode == KEY_E){
return 'e';
}
else if(keycode == KEY_F){
return 'f';
}
else if(keycode == KEY_G){
return 'g';
}
else if(keycode == KEY_H){
return 'h';
}
Faculty of Arts & Sciences
Department of Computer Science
CMPS 272—Operating System
Fall 2020–2021
HW3: Due Mon, Nov 2, 2020 @ 11:00 AM
return 'y';
}
else if(keycode == KEY_Z){
return 'z';
}
else if(keycode == KEY_SPACE){
return -1;
}
else{
return ' ';
}
// keyboard
char get_input_keycode()
{
char ch = 0;
while((ch = inb(KEYBOARD_PORT)) != 0){
if(ch > 0)
return ch;
}
return ch;
}
/*
keep the cpu busy for doing nothing(nop)
*/
void wait_for_io(unsigned int timer_count)
{
while(1){
asm volatile("nop");
timer_count--;
if(timer_count <= 0)
break;
}
Faculty of Arts & Sciences
Department of Computer Science
CMPS 272—Operating System
Fall 2020–2021
HW3: Due Mon, Nov 2, 2020 @ 11:00 AM
// command
void reset_command(){
command_length = 0;
for(int i=0;i<MAX_LINE_LENGTH;i++){
command[i] = '\0';
}
void check_command(void)
{
if(command_length == 7)
{
for(int i=0;i<command_length+1;i++){
if(command[i] != whatami[i]){
}
else
{
print_string("Unfamiliar command, try whatami.", WHITE_COLOR);
}
command[command_length] = ch;
command_length++;
}
Faculty of Arts & Sciences
Department of Computer Science
CMPS 272—Operating System
Fall 2020–2021
HW3: Due Mon, Nov 2, 2020 @ 11:00 AM
void test_input()
{
char ch = 0;
char keycode = 0;
do{
keycode = get_input_keycode();
if(keycode == KEY_ENTER){
print_new_line();
check_command();
reset_command();
}else{
if(command_length < MAX_LINE_LENGTH){
ch = get_ascii_char(keycode);
print_char(ch, WHITE_COLOR);
add_to_command(ch);
}
}
sleep(0x04FFFFFF);
}while(ch >= 0);
}
void main(void)
{
reset_command();
terminal_buffer = (unsigned short *)VGA_ADDRESS;
vga_index = 0;
clear_screen();
test_input();
print_new_line();
● The linker takes all of the object files, puts them together and provide a bootable single
binary file (your kernel). Create a file named linker.ld your current working directory and
write the following contents into it
OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
SECTIONS
{
. = 1M;
.text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}
.data : { *(.data) }
.bss : { *(.bss) }
}
● You need to use the (GRUB) to load your kernel. Create a file named grub.cfg your current
working directory and write the following contents into it. When the time comes to build
your ISO image, you'll install this file into its appropriate directory path.
set timeout=3
7. Compilation time
● Link both object files and create the final executable program (that is, your kernel)
● Now, you should have a compiled file in the same working directory labeled kernel. This file
is your kernel. You'll be booting into that kernel shortly
ls
🡺 boot.asm boot.o grub.cfg kernel kernel.c kernel.o linker.ld
● Create a staging environment with the following directory path (from your current working
directory path)
mkdir -p iso/boot/grub
● Let's double-check that the kernel is a multiboot file type (no output is expected with a
return code of 0)
cp kernel iso/boot/
cp grub.cfg iso/boot/grub/
Faculty of Arts & Sciences
Department of Computer Science
CMPS 272—Operating System
Fall 2020–2021
HW3: Due Mon, Nov 2, 2020 @ 11:00 AM
● Make the final ISO image pointing to your iso subdirectory in your current working directory
path
Submission Criteria, a demo scheduled with TA Hussein Banjak, you will have to
show through a camera/phone a running instance of the kernel. You will be
asked questions on how you did things and why.