Загрузка...

Linux 01: My first simple bootloader

--------------------------------------------
Initial code:
--------------------------------------------
.code16
.global demo

demo:
jmp demo

.fill 510-(.-demo), 1, 0
.word 0xaa55

--------------------------------------------
Final code:
--------------------------------------------
.code16
.global demo

demo:
mov $msg, %si
mov $0xe, %ah

print_msg:
lodsb
cmp $0, %al
je finish
int $0x10
jmp print_msg

finish:
hlt

msg: .asciz "Hello world! This is my first bootloader :)"

.fill 510-(.-demo), 1, 0
.word 0xaa55

--------------------------------------------

Have you ever been curious about how your computer starts booting after you press the power button? I was always curious about it, so I started digging into Linux kernel code and its related bootloader, called GRUB2 or GRand Unified Bootloader version 2.

In this video, I will show what I have learned about this initial process, focus on creating a simple bootloader to demo the basic concept behind it.

First, let's take a look at some related information on 8086 microprocessor based computer.

As soon as the power button is pressed, assuming the power supply meets the requirement of so-called "Power good signal", a pulse is sent to CPU to start a chain of actions. First, as part of POST or Power On Self Test, all registers are set to 0, including instruction register IP, except code segment register CS, which is set to 0xFFFF. BIOS or Basic Input and Output System is loaded at CS = 0xFFFF, and IP offset 0x0000. With 20 address lines, the real mode memory size is 2^20, or 1 MB. By left shifting CS by 4 bits, the BIOS entry address is 0xFFFF0. As the last step of BIOS loading, the entry address is checked to see if it is empty. If yes, the booting process stops. If not, BIOS will start loading MBR or Master Boot Record. MBR is also known as bootloader.

Here are some details. BIOS initiates interrupt 0x19 routine. We can think interrupts in assembly as functions in C language. It invokes service program at 0x0E6F2 to load MBR from side 0, track 0, section 1 on bootable device, for example, floppy disk, USB, or hard drive, which is exactly 512 bytes. The target address is 0x07C00. These 512 bytes are ended with magic number 0x55AA. This is the only way to tell the BIOS this chunk of code is bootable.

The takeaway from this procedure is four pieces of information that are useful when we create our simple bootloader:

(1) bootloader or MBR (master boot record) is in 16-bit memory mode;
(2) the entry address for bootloader is 0x7C00;
(3) the magic number at the end of bootloader must be 0x55AA;
(4) the size of bootloader is exactly 512 bytes.

Next, we need to set up development environment. My computer is running Windows 10 operating system. To use Linux assembler to compile and build the bootloader code, I installed Ubuntu in VirtualBox. It's a relatively straightforward process. You can find many resources online to explain how to do it. Or you may be running Linux on your machine at this moment, so it would be redundant for me to explain how to set up a Linux system.

To test my first bootloader binary, I installed QEMU in Linux. A single command in Ubuntu terminal will accomplish this installation: sudo apt-get install qemu.

To write bootloader assembly code, I use Visual Studio Code. You can use any text editor. There are only two steps to install Visual Studio Code. First, download .deb package for Ubuntu from Microsoft Visual Studio website. Then run Ubuntu package manager command dpkg, for example, sudo dpkg -i code_1.26.0-1534177765_amd64.deb

Now I will start my dev machine to demo how to create and test a simple bootloader in Linux. Open VirtualBox. Select Ubuntu virtual machine. Log in. Run Visual Studio Code from Terminal by typing "code". Click "Open folder". Create a folder, then create a new file called boot.s.

.....................
(Please refer to the video for details)
.....................

In summary, we have created a bootloader in less than 20 lines of assembly code, 18 exactly. 6 in the initial code, 12 more in the improved version to display a message. The practical bootloaders like GRUB2 or GRand Unified Bootloader version 2 is much more complicated, but they all have to follow the fundamental rules, like 512 bytes size limitation of MBR or Master Boot Record, entry address at 0x7C00, end with magic number 0x55AA, operates in 16-bit real memory address mode.

This is a brief introduction to a simple bootloader. I skipped detailed explanation of assembly instructions used in the code, since there are plenty of resources online to provide the detailed descriptions. Hope you have learned something useful here.

Thanks for watching!

Видео Linux 01: My first simple bootloader канала LiLeoWang
Яндекс.Метрика
Все заметки Новая заметка Страницу в заметки
Страницу в закладки Мои закладки
На информационно-развлекательном портале SALDA.WS применяются cookie-файлы. Нажимая кнопку Принять, вы подтверждаете свое согласие на их использование.
О CookiesНапомнить позжеПринять