嗨我是k66,上一篇介紹kernel概念,本篇要來實作,先用assembly寫Kernel.asm,NASM編譯成Kernel.bin,最後寫Kernel.c以連結。
放碼上來!程式碼連結
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,故保持當下畫面。
Kernel.asm
nasm Kernel.asm -f bin -o Kernel.bin
Kernel.bin
放至資料夾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;
}
今天用assembly寫Kernel.asm,以NASM編譯成Kerbel.bin後,再寫Kernel.c並連結之。
我們明天見!