基于龙芯2F的U-Boot固件移植与显卡优化
2015-06-21何超勇钱晓捷
何超勇钱晓捷
(郑州大学信息工程学院,河南郑州450001)
基于龙芯2F的U-Boot固件移植与显卡优化
何超勇钱晓捷
(郑州大学信息工程学院,河南郑州450001)
为提高基于龙芯2F的Yeeloong 8089平台的扩展性,阐述了U-Boot固件的基本架构和在该平台上的移植过程。描述了PCI设备特别是显卡的初始化过程,通过在U-Boot中引入视频图形阵列(VGA)基本输入输出系统(BIOS)模拟器的方式解决了在非x86架构平台上使用通用显卡的问题。经过调试和验证,U-Boot稳定运行于Yeeloong 8089平台,能够通过显卡显示启动信息,并可以成功引导Debian Linux内核。
龙芯2F U-Boot 模拟器 显卡 移植
1 引言
龙芯2F是一款由中科院计算所于2007年研制的高性能低功耗64位通用处理器。该处理器完整实现了MIPS III指令集,采用CMOS 90nm工艺制造,主频为1GHz并且支持软件动态调节处理器频率。因为主要面向桌面应用,所以在芯片内集成了DDR2内存控制器、PCI/PCI-X总线控制器、Local-Bus接口、中断控制器以及视频加速单元。
在嵌入式系统中,固件兼具PC机BIOS和bootloader(如GRUB、LILO)的功能,主要负责开机时对系统的硬件进行初始化和测试,并根据测试结果来引导操作系统内核或者将出错信息反馈给用户。由于该过程和具体硬件密切相关,固件一般都依赖于CPU的体系结构和板级硬件配置,基本没有通用性,至少需要移植和优化改进。
逸珑(Yeeloong)8089是由江苏中科梦兰电子科技有限公司推出的一款采用龙芯2F处理器和嵌入式系统架构的创新型笔记本电脑产品,摒弃了在x86体系计算机上沿袭多年的BIOS,转而使用固件来直接加载和引导操作系统内核。本文总结了基于该平台U-Boot固件移植过程中的关键问题,并针对非x86架构平台下通用显卡的优化实现进行了详述。
2 U-Boot移植
U-Boot是由德国的DENX小组所开发的一款应用广泛的嵌入式系统固件开源软件,支持ARM、AVR32、Blackfin、MicroBlaze、MIPS、Nios、PowerPC、x86等数量众多的处理器架构平台。U-Boot遵循GPL软件协议,向所有用户开放源代码,具有清晰简洁的代码树结构,并且文档资料和社区支持非常丰富。Yeeloong 8089平台目前所使用的固件系统为PMON 2000,该固件虽然能够满足基本的功能应用,但是其软件本身代码结构杂乱无序、移植困难,社区趋于瘫痪,用户数量匮乏,对后续的开发和功能扩展十分不利。因此,移植U-Boot到Yeeloong 8089平台,不仅能够丰富平台的应用,还能够有效提升该平台在开发者群体中的影响力。
2.1 U-Boot目录结构
U-Boot的主要功能包括硬件系统的检测和初始化、U-Boot命令行状态下各命令的稳定运行以及操作系统的正常引导。U-Boot采取了与Linux相类似的模块划分方式,同时考虑到了跨平台移植的问题。如表1所示,在U-Boot源代码主目录下,所有的源代码文件和配置文件都根据其性质和作用被组织于不同的子目录中。U-Boot的16个一级子目录,总体可以划分为3个类型:
①平台相关:主要是硬件和体系结构相关;②通用:主要是通用函数和驱动程序
③支持:主要是各种应用程序、工具和文档
表1 U-Boot一级子目录功能和类型
U-Boot的移植过程中所需要考虑的基本都是平台相关类型的子目录。U-Boot支持多种体系结构和上百种类型的开发板,对于特定的体系结构和开发板,移植过程主要是通过配置文件来选定相应的代码,同时依据实际需要来进行裁剪、添加和优化。
2.2 基于Yeeloong 8089平台的U-Boot移植
龙芯2F在启动时需要根据BEV寄存器的值来判断入口地址。当系统为冷启动时,BEV的值为1,入口地址为0xbfc00000;当系统为热启动时,BEV的值为0,入口地址为0x80000000。当目标主板上电冷启动时,龙芯2F将从0xbfc00000地址处取指令开始运行,而该地址从硬件上被映射到系统固件Flash芯片的第一条指令,也就是U-Boot的第一条指令。
U-Boot的启动分为stage1和stage2两个阶段:
(1)Stage1阶段
与体系结构、硬件配置密切相关。该部分代码主要用汇编语言实现,目的在于提高程序的执行效率。主要实现CPU、RAM、Nand Flash、Cache的初始化,建立临时堆栈,将U-boot加载到RAM,以及建立内存重定位和映射,为Stage2准备运行环境。
(2)Stage2阶段
主要实现通用的功能,如相关协议、Shell命令等。该部分代码用C语言实现,目的在于提高程序的可读性和移植性。主要实现初始化其余硬件,将内核加载到RAM,检测系统内存映射,设置启动参数,为内核准备运行环境。
U-Boot移植过程中主要使用ELDK(The Embedded Linux Development Kit)编译工具,该工具是由U-Boot项目主要维护人Wolfgang Denk所在的德国DENX软件工程公司所推出的嵌入式Linux开发套件,其中包含了GNU交叉编译开发工具、一些已经编译好的目标工具和提供在目标平台上进行函数调用的库文件。
基于Yeeloong 8089平台,U-Boot的移植的主要步骤:
①在源代码根目录的Makefile文件中,添加目标平台的配置信息;
②在board目录下,创建目标平台主板目录,并添加相应的板级初始化代码和配置文件;
③在include/configs目录下,创建包含目标平台主板设置参数的头文件;
④在arch/mips目录下,创建龙芯2F目录,并添加相应的片级初始化代码和配置文件;
⑤对代码进行配置和编译;
⑥调试并解决存在的问题。
在上述移植过程中,主要包括了片级移植和板级移植。其中片级移植和龙芯2F芯片相关,主要涉及Start.S和board.c这2个文件,其中的代码用于完成龙芯2F通用寄存器的初始化、CPO协处理器的初始化、Watchdog的初始化、Cache的初始化。板级移植和目标主板相关,涉及board子目录、common子目录、net子目录、driver子目录等多个文件,其中的代码主要是初始化相关硬件并为之提供驱动程序。
3 基于Yeeloong 8089平台的U-Boot优化
在YeeLoong 8089目标平台主板上,龙芯2F处理器通过PCI总线来对AMD CS5536南桥芯片、Sillion SM712显卡、RTL8139D网卡以及摄像头等主要外部设备进行连接和控制。移植后的U-Boot可以稳定运行于该目标平台主板上,但是还需要进行一些优化工作,主要是解决在龙芯2F这样的非x86架构平台上使用通用显卡的问题。
3.1 显卡初始化原理
在系统上电之后,固件需要通过扫描PCI总线来确定系统拥有的PCI设备,因此每一个PCI设备都需要实现一个PCI配置空间。PCI设备的配置空间大小为256字节,由多个寄存器组成,分为预定义部分和设备独立部分,典型PCI设备的配置空间如图1所示。
图1 PCI设备配置空间图
除了用于设备鉴别的Vendor ID、Device ID、Revision ID、Header Type和Class Code这5个寄存器是每个PCI设备都需要实现的以外,图1所示的其他寄存器都是由生产厂家根据PCI设备的类型和功能来决定是否实现。
在固件启动操作系统之前,必须建立一个统一的系统地址空间。固件通过扫描PCI总线,读取PCI设备的配置空间,PCI设备的寄存器(除了PCI配置寄存器)和内存(RAM和ROM)就可以通过一组特殊的寄存器,即图1所示10h--24h地址处的BAR(Base Address Register)来映射到CPU Memory空间或者CPU I/O空间中的特定地址,这样就可以避免不同PCI设备之间发生地址冲突。这个过程就被称为PCI设备的初始化过程,只有经过初始化的PCI设备才可以被正确访问和使用。
但是由于一些PCI设备(例如显卡)的复杂性较高,在该过程之后还需要设备专有的PCI Expansion ROM代码,来进一步完成设备的初始化。PCI Expansion ROM的入口地址由该PCI设备的配置空间30h地址处的Expansion ROM Base Address指明。PCI显卡设备的Expansion ROM一般被特称为VGA ROM,用于完成显卡的低级初始化和中断的设置。但是由于指令集的不兼容,龙芯2F无法正确解析和执行这些指令,会出现无法预知的错误。
VGA BIOS模拟器就是为了解决这个问题而存在的。它在非x86架构的CPU上运行,模拟执行VGA ROM中的代码和中断调用。VGA BIOS模拟器在逻辑上具有很好的内聚性,对外设I/O、MMIO、PCI配置空间的访问接口是模拟器和外界代码进行交互的唯一界面。VGA ROM中的代码指令类型相对固定,主要包括以下几种类别:
①修改寄存器的值;
②修改存储单元的值;
③修改外设I/O端口的值;
④修改外设MMIO端口的值;
⑤修改外设PCI配置空间的值。
据此,VGA BIOS模拟器所需具备的基本功能应该包括:
①能够识别和执行VGA ROM中的每一条指令;
②能够完全模拟指令的后继影响,包括中断调用;
③能够模拟和维护8086 CPU中的所有寄存器;
④提供一段空间来模拟对存储器的读写操作;
⑤拥有和外界进行交互的界面,包括外设I/O、MMIO和PCI配置空间。
3.3 VGA BIOS模拟器搭建
为了支持对于中断调用的模拟,VGA BIOS模拟器的搭建需要如下步骤:
(1)提供显卡的设备描述
在U-Boot中提供一个全局变量,通过对这个变量的访问,模拟器不需探测就可以知道平台使用的是哪一个显卡,同时可以方便地访问到该设备的相关信息。
(2)设置抽象层的函数集合指针
设置模拟器中调用I/O访问和MMIO模拟访问的界面,设置默认的中断处理函数。I/O访问的函数指针为sys_inx和sys_outx,MMIO访问的函数指针为sys_rdx和sys_wrx(x可以为b,w或者l)。这些函数指针在8086指令模拟的时候被调用,中断处理函数的初始化则会在中断指令模拟的时候进行。
(3)申请模拟器操作所需要的空间
一共需要申请分配3个空间,其中动态分配的有两个,大小分别为1MB和64KB,另外还需一个不限定大小的对应于显存的空间。1MB大小的空间用于模拟实模式下8086 CPU的地址空间,而64KB大小的空间用于模拟实模式地址空间的
3.2 VGA BIOS模拟器功能
通用显卡的VGA ROM工作在实模式下,一般使用8086格式的汇编指令来编写。非x86架构的CPU如果需要使用这种显卡,就会遇到指令集兼容性的问题。按照显卡的初始化流程,在显卡的设备寄存器和内存映射到CPU内存空间中之后,龙芯2F已经可以成功读取到VGA ROM中的代码指令,高64KB地址范围。由于历史的原因,实模式所用的1MB地址空间中的部分地址范围有着其特定的作用。在VGA BIOS模拟器中需要关注的地址空间如表2所示。
表2 模拟器所需申请空间
(4)设置中断向量表
中断向量表位于所申请的1MB实模式内存空间的0x00000—0x003FF地址范围内。中断向量表一共包含256个中断向量,其中每个中断向量均分为段值和段内偏移两部分。在中断调用时,段值和段内偏移的值分别被赋予CS和IP寄存器,组合生成20位的线性地址,表示所调用的中断例程所在的位置。在VGA BIOS模拟器中需要重点关注的2个中断是int 10h中断和int e6h中断。
(5)将VGA ROM纳入模拟器框架
由于模拟器实际执行的指令都位于VGA ROM中,所以模拟器必须获取VGA ROM的内容并做出相应的处理。VGA BIOS模拟器在初始化时将VGA ROM复制到所申请的1MB实模式内存空间中0xC0000--0xCFFFF地址范围内,之后对VGA ROM的访问就转换为对该地址范围的访问。
3.4 VGA BIOS模拟器的运行
VGA BIOS模拟器的实际执行过程就是读取VGA ROM中的指令并模拟执行,重点在于两条中断指令的模拟执行。首先是通过对int e6h中断的模拟执行来实行VGA ROM代码中中断例程的安装,为后续中断调用创造执行条件;然后是通过对int 10h中断的模拟来实现显卡framebuffer模式的设置。
中断调用和普通的函数调用一样,也可以接收多个参数来执行不同的操作。在8086指令集中,指令序列的第一个字节是opcode,也就是说指令最多是256条。由于8086指令集是变长指令集,因此在获取opcode之后,由opcode相对应的处理函数来处理后续的具体operand解析更为方便,模拟器中中断调用的执行流程如图2所示。
图2 模拟器中断调用流程图
有些指令比较特殊,可能前后两条或者多条指令会有连带影响。例如DATA指令(opcode为0x66),当模拟器遇到这条指令的时候,表示下一条指令操作的寄存器和立即数长度为32位。这时候模拟器会提供一个标志位,当下一条指令和立即数相关时,下一条指令的处理函数就会判断这个标记位,进行不同的处理。这种标记位会在下一条指令执行完成之后自动清除,不会带来更进一步的影响。
4 结束语
本文介绍了U-Boot固件在YeeLoong 8089平台的移植过程,重点描述了通用显卡的初始化过程以及在非x86体系架构下使用通用显卡的原理和方法。经测试和实际用户体验,U-Boot现在已经可以稳定运行于该目标平台,并可以成功启动Linux Debian操作系统。但是与主流的x86平台所使用的BIOS相比,U-Boot基于文字的界面对于普通用户的友好度仍有待于提高。因此如何提高系统界面的友好性和交互性将是今后工作的重点。
[1]Loongson Technology Corporation Limited.Loongson 2F User Manual v1.5[Z].2013.[龙芯中科技术有限公司.龙芯2F处理器用户手册v1.5[Z].2013.
[2]Loongson Technology Corporation Limited.Loongson 2F Data Sheet v1.1[Z].2013.[龙芯中科技术有限公司.龙芯2F处理器数据手册v1.1[Z].2013.
[3]Loongson Technology Corporation Limited.Loongson Processor White Paper v2.0[Z].2014.[龙芯中科技术有限公司.龙芯芯片产品技术白皮书v2.0[Z].2014.
[4]PCI Special Interest Group.PCI Local Bus Specification (Revision 2.3)[S].2002.
[5]Video Electronics Standards Association.VESA BIOS EXTENSION(VBE)Core Functions Standard(Version 3.0) [S].1998.
[6]Advanced Micro Devices,Inc.AMD GeodeTM CS5536 Companion Device Data Book[Z].2007.
[7]Dominic Sweetman.See MIPS Run,Second Edition[M]. Morgan Kaufmann publications,2007.
[8]Tommy Noergaard.Embedded Systems Architecture:A Comprehensive Guide for Engineers and Programmers, Second Edition[M].Newnes,2008.
[9]李雷,郑为民,刘金刚.基于PMON的龙芯BIOS初始化及VGA BIOS模拟器[J].计算机工程,2009,35(1):204-206.
[10]张菊莉,张君毅,孟小锁.基于龙芯2F架构的PMON分析与优化[J].现代电子技术,2011,34(2):19-21.
Firmware Porting and Video Card Optimization of U-Boot Based on Loongson 2F
HE Chao-yong,QIAN Xiao-jie
(School of Information Engineering,Zhengzhou University,Zhengzhou He’nan 450001,China)
In order to improve the extensibility of Yeeloong 8089 platform based on Loongson 2F,the basic structure and the porting process of the U-Boot firmware on this platform are described.The initialization process of PCI devices,especially of video care,is presented.The use of general graphic cards on the non-x86 architecture platform is implemented by introducing video graphics array (VGA)basic input/output system(BIOS)emulator into the U-Boot.The test results show that U-Boot can run stably on Yeeloong 8089 platform,and can correctly display the startup information through the video card and successfully boot the Debian Linux kernel.
Loongson 2F;U-Boot;simulator;video card;porting
TP311.54
A
1008-1739(2015)12-72-4
定稿日期:2015-05-26