string

string
posts - 27, comments - 177, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

UEFI实战(1)

Posted on 2011-10-02 01:46 djx_zh 阅读(17280) 评论(16)  编辑 收藏 引用
本篇为UEFI实战系列第一部分。
UEFI实战前10个部分计划如下:
UEFI 实战(1) 开发环境 
讲述如何配置开发环境。
UEFI 实战(2)  HelloWorld
讲述dsc, inf文件的格式, application常用的变量,数据结构和函数。
UEFI 实战(3) C++
讲述如何用C++开发UEFI程序。
UEFI 实战(4) protocol
讲述UEFI中protocol的概念
UEFI实战(5) driver
讲述UEFI中driver模型
UEFI实战(6) 文件读写
UEFI实战(7) Hii interface 之 Form
UEFI实战(8) Hii interface 之 String 和Font
UEFI实战(9) GUI
UEFI实战(10) Network

UEFI 实战(1)
配置开发环境
1. 下载 Windows SDK
2. 下载EDK2 
3. 打开visual studio 2008 command prompt 
    cd EDK2
    edksetup.bat
4. 编辑Conf\taget.txt, 修改 编译工具TOOL_CHAIN_TAG        为
   TOOL_CHAIN_TAG        = VS2008x86
5. build
    build命令有两个参数, -a 和-p, -a 用来选择平台(IA32 X64,...) -p用来选择要编译的package,默认的package是Nt32Pkg, 所以build命令与 build -a IA32 -p Nt32Pkg\Nt32Pkg.dsc 等同,用来编译UEFI模拟器。
6. build run
    与build -a IA32 -p Nt32Pkg\Nt32Pkg.dsc run 命令等同,用来运行UEFI模拟器。
 
制作UEFI USB启动盘
分两种情况,如果目标平台是UEFI平台,按如下步骤来做:
1。 格式化U盘为FAT(FAT,FAT16, FAT32)格式 
2。 在U盘上建立目录 efi\boot
3。 将efi的应用程序 copy到 efi\boot 目录,并改名为bootx64.efi 或者bootia32.efi。
      因为UEFI的启动文件是FAT盘内efi\boot目录里的bootx64.efi 或bootia32.efi, 与legacy bios需要MBR来引导OS不同。
如果目标平台是legacy bios, 需要在U盘中制作MBR和引导文件, 按如下步骤来做:
1。 编译duet package
      build -a IA32 -p DuetPkg\DuetPkgIa32.dsc 或者
      build -a X64 -p DuetPkg\DuetPkgX64.dsc
2。 生成引导文件
      cd DuetPkg
      postbuild.bat Ia32 或者 postbuild.bat X64
3。 插入U盘,假设J:是U盘, 向U盘写入MBR
      createbootdisk usb J: FAT32 IA32 或者 createbootdisk usb J: FAT32 X64     
4。拔出并重新插入U盘, 向U盘copy UEFI文件
      createbootdisk usb J: FAT32 IA32 step2 或者 createbootdisk usb J: FAT32 X64 step2
      此命令向U盘根目录copy了efildr20, 该文件用于引导系统进入UEFI环境,并向efi\boot目录copy了引导文件bootia32.efi或bootx64.efi
接下来就可以用U盘来运行UEFI了。
 
如何Debug
UEFI有两种debug方式,一是在模拟环境Nt32Pkg下debug,另一种是通过串口调试真实环境中的UEFI程序。我从来没见过传说中的利用串口调试,所以下面只能说说Nt32Pkg下的debug。
在需要调试的代码前面加入_asm int 3; 编译,然后再模拟环境中(Nt32Pkg)中运行该程序,当模拟器执行到int 3;指令时,会弹出对话框,然后就可以调试了。

Feedback

# re: UEFI实战(1)  回复  更多评论   

2011-12-05 14:15 by 王子
您好,看到你写UEFI,知道你是这方面的专家,我这里有个问题需要请教 :怎么得到GPT分区表? 怎么读写里面的数据? 能用vs实现吗?

# re: UEFI实战(1)  回复  更多评论   

2011-12-06 00:00 by djx_zh
UEFI会为每一个分区创建一个controller, 也会为每个硬盘创建一个controller. 通过安装到controller上的DiskIo protocol可以读写每一个扇区。
每个controller上有DevicePath protocol, 你可以通过DevicePath判断该controller是一个扇区,还是一个硬盘。扇区的DevicePath的的最后一个有效Node是HD(SPEC 9.3.6.1)。
当你获得了GPT硬盘的DiskIo之后,可以利用DiskIo读第一个扇区(第0个是MBR或者Protective MBR)得到GPT header,第2~33分区存放的是EFI_PARTITION_ENTRY。 GPT用到的数据结构在MdePkg/Include/Uefi/UefiGpt.h中,GPT的格式可以参考UEFI SPEC 第5章。
可以用VS实现。

# re: UEFI实战(1)  回复  更多评论   

2012-03-09 14:54 by ningle
very very good,希望博主能把2、5、7、9、10部分也一同贴上来,特别第2,5部分,因为我没有入门了,这方面的中文资料太少了,难得遇到博主这么精通的

# re: UEFI实战(1)  回复  更多评论   

2012-03-12 07:20 by djx_zh
@ningle
谢谢关注。这几部分还没写,我尽快写吧。如果看到写的有不准确的地方,也请告诉我啊。

# re: UEFI实战(1)  回复  更多评论   

2012-10-04 15:05 by zboydong
博主能不能写一篇关于duet的

# re: UEFI实战(1)  回复  更多评论   

2013-01-24 08:00 by howard
Hi 博主,你的文章让我受益匪浅!我按照你的流程做UEFI 的USB启动盘,现在boot 成功了,可是发现shell 少了一些commands, 比如devices.之前我在OS上直接build run就可以看到那些指令,这是为什么?请博主指点!

# re: UEFI实战(1)  回复  更多评论   

2013-01-24 09:24 by howard
补充下,我的目标平台是legacy bios

# re: UEFI实战(1)  回复  更多评论   

2013-01-24 22:15 by djxzh
@howard
你用的是EDK2预先编译好的shell,这个shell比较老。 你可以自己编译ShellPKg,然后用shell.efi 覆盖掉U盘上的bootx64.efi

# re: UEFI实战(1)  回复  更多评论   

2013-01-25 06:23 by howard
赞! 现在可以了。可是UEFI找不到设备,只能看到这个USB盘,其他attached的drives 和Pcie device 都看不到,是device驱动不对吗?

# re: UEFI实战(1)  回复  更多评论   

2013-01-25 22:36 by djxzh
@howard
不知你想找什么设备呢? EDK2 只提供了有限的几种device driver, 部分网卡的driver可以到intel网站上下载。

# re: UEFI实战(1)[未登录]  回复  更多评论   

2013-11-12 15:15 by Jerry
楼主是这方面的专家,我想问一下楼主,GPT磁盘中有MBR中所谓的活动分区概念吗,GPT磁盘的系统启动和MBR磁盘的启动有什么区别吗,GPT不是寻找活动分区来启动操作系统吗?谢谢楼主!

# re: UEFI实战(1)[未登录]  回复  更多评论   

2013-11-17 23:12 by djx_zh
@Jerry
UEFI 完成硬件初始化后,会遍历GPT硬盘中的FAT分区,从FAT分区找到efi/boot/bootia32.efi 或efi/boot/bootx64.efi, 操作系统的启动由bootx64.efi或bootia32.efi完成。
MBR硬盘启动代码以二进制形式放在活动分区指定的地方。GPT硬盘的启动代码是完整的应用程序,存放在启动分区即FAT分区的efi/boot目录下

# re: UEFI实战(1)  回复  更多评论   

2015-10-21 13:44 by 马天横
我通过 build -a X64 -p Nt32Pkg\Nt32Pkg.dsc 命令创建但是出错了!错误信息是:MSVCRTD.lib(crtexe.obj):error LNK2001:无法解析的外部符号__imp_EncodePointer

# re: UEFI实战(1)[未登录]  回复  更多评论   

2015-10-21 21:59 by djx_zh
@马天横
Nt32Pkg只支持-a IA32

# re: UEFI实战(1)  回复  更多评论   

2015-12-21 12:20 by daisy
为什么我build x64就成功了~build -p NT32Pkg\NT32Pkg.dsc -a X64

# re: UEFI实战(1)  回复  更多评论   

2016-03-19 17:59 by yayake
我运行 build命令没报错,可运行 build -a X64 -p Nt32Pkg\Nt32Pkg.dsc 命令时,出现了两个uefi模拟器的窗口,而且shell阶段打印了大量的乱码,之后直接卡死了, 我用的edk版本是“UDK2015.Complete.MyWorkSpace”。

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理