Legacy改UFEI的内核修改

彭博厚
2023-12-01

将Bootloader方式从Legacy改成UFEI之后,由于Bootloader的获取的信息存放在了不同的数据结构中,因此内核程序需要进行相应的调整。

一、内核头程序head.S

田宇老师的《一个UEFI引导程序的实现》一文提出:“由于数据段描述符在GDT表中的位置无法确定,从而就无法直接通过段选择子对段寄存器进行赋值。不过,好在栈段寄存器SS指向的段是可读写的,那么将此段作为数据段是可行的。”
基于此关键修改部分如下:

#include "linkage.h"

.section .text

ENTRY(_start)

    mov    %ss,    %ax
    mov    %ax,    %ds
    mov    %ax,    %es
    mov    %ax,    %fs
    mov    %ax,    %ss
    mov    $0x7E00,    %esp

    movq    $0x101000,    %rax
    movq    %rax,        %cr3

//=======    load GDTR

    lgdt    GDT_POINTER(%rip)

//=======    load    IDTR

    lidt    IDT_POINTER(%rip)

    mov    $0x10,    %ax
    mov    %ax,    %ds
    mov    %ax,    %es
    mov    %ax,    %fs
    mov    %ax,    %gs
    mov    %ax,    %ss

    movq    _stack_start(%rip),    %rsp

//=======    load    cr3

    movq    $0x101000,    %rax
    movq    %rax,        %cr3
    movq    switch_seg(%rip),    %rax
    pushq    $0x08
    pushq    %rax
    lretq

......

//=======    init page
.align 8

.org    0x1000

__PML4E:

    .quad    0x102007
    .fill    255,8,0
    .quad    0x102007
    .fill    255,8,0

.org    0x2000

__PDPTE:

    .quad    0x103007    /* 0x103003 */
    .fill    511,8,0

.org    0x3000

__PDE:

    .quad    0x000087    
    .quad    0x200087
    .quad    0x400087
    .quad    0x600087
    .quad    0x800087
    .quad    0xa00087        /*0x a00000*/
    .quad    0xc00087
    .quad    0xe00087
    .quad    0x1000087
    .quad    0x1200087        /*0x1000000*/
    .quad    0x1400087
    .quad    0x1600087
    .quad    0x1800087
    .fill    499,8,0

二、内存初始化函数init_memory

内存的信息如今放在了boot_para_info->E820_Info.E820_Entry之中,因此需要对内存初始化函数init_memory进行相应的修改:
核心代码在于将

p = (struct E820 *)0xffff800000007e00;

修改为

p = (struct EFI_E820_MEMORY_DESCRIPTOR *)boot_para_info->E820_Info.E820_Entry;

三、帧缓存区地址重映射

此处也用到了bootloader获取的VBE信息,因此也需要进行相应的修改:

  • FB_addr初始值:
unsigned int * FB_addr = (unsigned int *)Phy_To_Virt(boot_para_info->Graphics_Info.FrameBufferBase);
  • 页表基地址:
unsigned long phy = boot_para_info->Graphics_Info.FrameBufferBase + i;

FB_addr更改值:

Pos.FB_addr = (unsigned int *)Phy_To_Virt(boot_para_info->Graphics_Info.FrameBufferBase);
 类似资料: