Secure OS Lab
Cyber Lab S23 - Week 1
Announcements
Overview
Meet the Team
Daniel Yang
Secure OS Project Lead
Michelle Zhao
Officer
Victoria Choi
Officer
Benson Liu
Co-President
Aaron Yoo
Mentor & SWE @ Apple
You
MVP
✨Social Engineering Time ✨
Goal
Timeline
Part 1: (Guided) Developing the Bootloader & Kernel
Part 2: Design Your Own Feature
Logistics
Environment Setup
Installation
Boot Process
Boot Steps
Ruling the Boot Sector
Basic Commands
$ qemu-system-x86_64 -drive format=raw,file=boot-sect.bin
$ od -t x1 -A n boot-sect.bin
$ nasm boot-sect.asm -f bin -o boot-sect.bin
What is a boot sector?
How do we interface with devices?
Persistent storage
Objectives
Steps
Just call the BIOS routine for printing a character and run…
Shouldn’t be many issues here.
2. Print a message stored at a memory location
Next, modify your boot-sect.asm file and add a label marking a string such as “Hello World!”. You can define the string as db “Hello World!”
Make sure its before your 0x55 0xaa bytes otherwise it will be outside of the boot sector and not loaded into memory.
Don’t forget a null 0x00 byte after the string.
Now, see if you can print the string marked by your label.
Remember, labels are offsets from the start of your code. The actual location of the boot sector in memory is at 0x7c00! (Hint: check the “org directive”)
2a. print_string function
Move your code printing a string into a function. The function is located in print_string.asm.
Understand what is happening when you use “call” and “ret” in regards to the process stack.
Also understand why we want to use “pusha” and “popa” when calling the function.
2b. print_hex function
Now that you know how to call BIOS routines and how to use functions, can you create a function to print the value of a 16 bit register as hex?
Write this function in print_hex.asm.
ASM bonus knowledge time
Register: cs, ds, ss, and es
These registers provide a base address so that the CPU can calculate the absolute addresses using an offset
ex: set ds to <base>, then run mov ax, [<var addr>]. The absolute address of the data moved into ax will be <base>*16+<var addr>.
Usually only want to modify the es register in your code.
then just mov <reg>, [es:<addr>] to fetch using the es as a base address.
3. Read data from disk
First, to understand a bit more about segment registers, store a single character at a label and try to print it in your main boot-sect.asm program using the es register as the base address.
Now, look through the disk_load.asm file to see how to read disk. FYI int 0x13 loads the sectors to the address [es:bx]
In your main boot-sect.asm, first mov dl, [label] to save the boot drive number. Then move the stack to a high address like 0x8000 to avoid overwriting the loaded boot sector.
3. Read data part 2
Now, add two sectors (512 bytes/sector) worth of data after the 0x55 0xaa bytes in your boot sector code.
Even though these sectors are stored in your asm file, they will not be loaded into memory when the MBR loads the boot loader since they are after the 0x55 0xaa, which marks the end of the boot sector. In other words, the bytes will stay on persistent storage.
Now, read from disk and load to memory at an address higher than the stack. Make sure parameters for the 0x13 interrupt are correct.
Try to print the data in the memory sectors you loaded. Are they what you expected? If not review the code and debug.
x86 Print character routine
mov ah, 0x0e ; Tells BIOS to print in teletype mode
mov al, “x” ; Loads the character to be printed, in this case its an “x”
int 0x10 ; BIOS interrupt that manages graphics
Useful NASM directives/features
% include “asm_file.asm” ;include another assembly source file
[org <address>] ;provide reference point for all addresses
Extra Info
General Info: https://wiki.osdev.org/
Address Offset: https://stackoverflow.com/questions/46811232/what-does-org-0x7c00-actually-do-to-the-file
Check out our linktree: