nishakm / fakeos

a fake operating system for educational purposes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

FakeOS: Implementation and notes based on educational courses available online

About the Author's Abilities

This is my first real foray into Operating Systems. It has been years since I programmed in DOS. I have been develping on a Linux based machine for years now and hence my current experience is the reference point I choose to learn something new. With that in mind, here is my reference should anyone else want to use it:

  • Fedora VM
  • Ubuntu native install

Learning Material

FakeOS is based on the MIT online course on operating systems This does not follow any of the lab implementations but it does use some material from the first lab

Getting Started on Fedora

  • Install git and gcc (sudo dnf install git gcc)
  • Install qemu (sudo dnf install qemu)

The qemu install has a list of binaries that go into /usr/bin/ and are prefixed by qemu-. The one I used is qemu-system-x86_64. The native architecture I use is x86_64. I haven't gotten to cross compiling at this point in time

Later on in the lab I changed it to qemu-system-i386 as I found out that the kernel was compiled using CFLAGS as -m32 (meaning compiled for a 32bit processor) and gdb was erroring out because the memory address sent to it was too long. I do not know what CFLAGS means.

Lab1 of the MIT course requires you to untar lab1 which is a tar of the git history. I set the QEMU environment variable to the above qemu, and then ran make qemu, getting the correct results. See lab1 from the MIT study guide.

$ make qemu       
/usr/bin/qemu-system-x86_64 -hda obj/kern/kernel.img -serial mon:stdio -gdb tcp::26000 -D qemu.log 
WARNING: Image format was not specified for 'obj/kern/kernel.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.      

(qemu-system-x86_64:16448): Gtk-WARNING **: Allocating size to GtkScrollbar 0x564667812340 without calling gtk_widget_get_preferred_width/height(). How does the code know the size to allocate?
6828 decimal is XXX octal!             
entering test_backtrace 5              
entering test_backtrace 4              
entering test_backtrace 3              
entering test_backtrace 2              
entering test_backtrace 1              
entering test_backtrace 0              
leaving test_backtrace 0               
leaving test_backtrace 1               
leaving test_backtrace 2               
leaving test_backtrace 3               
leaving test_backtrace 4               
leaving test_backtrace 5               
Welcome to the JOS kernel monitor!     
Type 'help' for a list of commands.    
K> help            
help - Display this list of commands   
kerninfo - Display information about the kernel                               
K> kerninfo        
Special kernel symbols:                
  _start                  0010000c (phys)                                     
  entry  f010000c (virt)  0010000c (phys)                                     
  etext  f01019a9 (virt)  001019a9 (phys)                                     
  edata  f0112300 (virt)  00112300 (phys)                                     
  end    f0112944 (virt)  00112944 (phys)                                     
Kernel executable memory footprint: 75KB

If you run make qemu-nox you won't get the annoying VGA window and the Gtk-WARNING will not come up. But you will not be able to CTRL+C out of this as QEMU probably owns the terminal session. Lab1 says that the kernel writes to both the QEMU's VGA port as well as its serial port which in turn uses the terminal standard out.

When running gdb I get a warning about the auto-load-safe-path of the .gdbinit in the lab directory was declined by some other auto-load-safe-path setting. The tool said to create a ~/.gdbinit and set the auto-load-safe-path value to the lab's .gdbinit file

$ vim ~/.gdbinit
add-auto-load-safe-path /home/username/path/to/lab/.gdbinit

When running gdb in a second terminal, there will be a lot of licensing prose, which can be ignored for learning purposes. On my machine I get this output:

[f000:fff0]    0xffff0:	ljmp   $0x3630,$0xf000e05b
0x0000fff0 in ?? ()

The first line is of the form: [CS:IP] instr address: instr arguments

Where:

  • CS: Code Segment - a location in memory where the code is stored, calculated using 16xCS
  • IP: Instruction Pointer - an offset added to the above result
  • instr address - the location in memory where execution starts
  • instr - the instruction
  • arguments to the instruction

In this case:

  • 16 x CS + IP ==> 16 x f000 = f0000; f0000 + fff0 = ffff0
  • 0xffff0 is 16 bytes before the top of the BIOS area of memory
  • ljmp is "jump"
  • 0x3630 is jump to this CS (earlier in the BIOS)
  • 0xf000e05b is the IP which is different from the lab because it is 32 bits rather than 16 bits and that is all the way into the top of the extended memory location but before the memory mapped PCI device location reserved by the BIOS

The processor is designed to look for the first instruction within the BIOS memory range. After checking for peripherals, it looks for a bootable disk. When it finds it, it will read the bootloader and load it into the memory.

There is a prescribed memory location for this for a bootloader stored in the hard drive of a PC.

(gdb) b *0x7c00 <-- set breakpoint to 0x7c00 which is the memory location for the bootloader
Breakpoint 1 at 0x7c00
(gdb) c
Continuing.
The target architecture is assumed to be i8086
[   0:7c00] => 0x7c00:	cli    

Notes About Memory

Memory locations are addressable here using 32 bits. In x86_64 CPUs they are addressed using 64 bits. For a 32 bit processor the memory can go up to 2^32 address locations. meaning 4294967296 Bytes (if each memory location can hold 8 bits). Divide the number by 1024 (rather than 1000) 3 times and you get 4 GiB of memory. All the memory ranges described in lab1 follow hexadecimal memory mapping and factoring by 1024 rather than 1000 to calculate KiB and MiB.

Key things to remember:

  • 0x00000000 - 0x000A0000 (640KiB) Low Memory/Conventional Memory
  • 0x000A0000 - 0x00100000 (384KiB) Memory hole
  • 0x00100000 -> (RAM limit) Extended Memory
  • 0xFFFFFFFF -> (whatever BIOS reserves) For memory mapped 32 bit PCI devices
  • 0x000F0000 - 0x00100000 (64KiB) Where BIOS used to be (they live in flash memory now)
  • 0x00007C00 - 0x00007DFF memory where bootloader is saved to (for hard drives so it can only be 512 bytes)

Sudy Guides

References

About

a fake operating system for educational purposes