iT邦幫忙

2023 iThome 鐵人賽

DAY 21
0
SideProject30

世界第一簡單的UEFI,實作打造自己的開機畫面系列 第 21

【Day 21】bootloader轉交控制權給kernel?ASM+UEFI寫kernel(下)

  • 分享至 

  • xImage
  •  

嗨我是k66,上一篇介紹kernel概念,本篇要來實作,先用assembly寫Kernel.asm,NASM編譯成Kernel.bin,最後寫Kernel.c以連結。

放碼上來!程式碼連結


  1. 開發Kernel.asm
BITS 64 ; 若不指定,預設是16bits
mov ecx, 0x001FA400 ; 1920x1080=0x001FA400
mov eax, 0xFF18679A ; 藍色十六進制是0x18679A,先轉B(0x9A)G(0x67)R(0x18)(0xFF),再little alien
xor rdi, rdi ; 暫存器選rdi是因為64位元,buffer之間要存值,得透過站存器,賦值前先清零。
mov rdi, 0xC0000000 ; 寫入的目的地址

Write:
    mov [rdi], eax ; eax賦值給給rdi的address
    add rdi, 4 ; 每次rdi暫存器的值都加4
    loop Write ; 迴圈

jmp $ ; 為了避免程式執行完畢回到UEFI Shell,故保持當下畫面。
  1. nasm編譯Kernel.asm
nasm Kernel.asm -f bin -o Kernel.bin
  1. Kernel.bin放至資料夾
  2. 開發Kernel.c,編譯並執行之
EFI_STATUS GetFileHandle(
    IN EFI_HANDLE ImageHandle,
    IN CHAR16 *FileName,
    OUT EFI_FILE_PROTOCOL **FileHandle
);

EFI_STATUS ReadFile(
    IN EFI_FILE_PROTOCOL *File,
    OUT EFI_PHYSICAL_ADDRESS *FileBase
);

EFI_STATUS EFIAPI UefiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable)
{
    EFI_FILE_PROTOCOL *bin;
    Status = GetFileHandle(ImageHandle, L"Kernel.bin",&bin);
    EFI_PHYSICAL_ADDRESS binAddr;
    Status = ReadFile(bin, &binAddr);
    asm("jmp %0"::"m"(binAddr));

    return Status;
}

Kernel完成!

總結

今天用assembly寫Kernel.asm,以NASM編譯成Kerbel.bin後,再寫Kernel.c並連結之。
我們明天見!



上一篇
【Day 20】bootloader轉交控制權給kernel?ASM+UEFI寫kernel(上)
下一篇
【Day 22】自己寫UEFI Boot Menu (上)
系列文
世界第一簡單的UEFI,實作打造自己的開機畫面31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言