赞
踩
本文档描述将OV项目向ZC702开发板移植的过程。
ZC702开发板可以通过SD卡和网络两种方式启动,但是从SD卡启动方式在每次OS内核变化时就需要替换SD卡中的旧OS内核,需要重复插拔SD卡,太过繁琐,不如从网络方式启动方便。这一章便描述如何建立ZC702的网络启动方式,方便以后修改OV内核。
ZC702板和开发主机Host按照下图进行连接。Host机是在VMware中安装的Debian 6,网卡配置为桥接方式,IP为10.10.70.101。嵌入式开发板分配IP为10.10.70.102(默认配置)。为了不影响物理机的网络,搭建网络环境如下:
所谓网络启动方式就是ZC702上的uboot通过tftp协议从Host上获取内核镜像。这种方式需要uboot支持tftp协议,Host支持tftp服务和nfs服务。ZC702的原始uboot就支持tftp,不需要改动,只需要在Host上安装tftp和nfs即可。
首先安装tftp:apt-get install tftp tftpd xinetd
然后配置tftp:在/etc/xinet.d/目录下创建文件tftp,并添加如下内容。
service tftp
{
socket_type = dgram
protocol = udp
wait = yes
user = zhao
server =/usr/sbin/in.tftpd
server_args = /home/zhao/xilinx/tftp #替换为你的目录,注意权限
disable = no
per_source = 11
cps =1002
flags = IPv4
}
重启tftp:
#/etc/init.d/xinetdreload
#/etc/init.d/xinetdrestart
测试tftp:首先在tftp的共享文件夹下创建一个文件test,添加内容abcdefgh;然后在另外一个目录下运行
$tftp 10.10.70.101
tftp>get test
Received 10 bytes in 0.0 seconds
参考自:http://billforums.station51.net/viewtopic.php?f=1&t=17
首先安装nfs:apt-get install nfs-kernel-server portmap nfs-common
然后配置Host上的nfs服务。编辑/etc/exports文件,添加根文件系统路径(rootpath):
/home/zhao/xilinx/tftp/fs 10.10.70.102(rw,fsid=0,insecure,no_subtree_check,async,no_root_squash)
/home/zhao/xilinx/tftp 10.10.70.102(rw,fsid=0,insecure,no_subtree_check,async)
环境搭建好以后,就可以通过网络方式启动OV了。首先将编译好的SierraTEE.bin复制到tftp服务器的目录/home/zhao/xilinx/tftp/,然后在ZC702启动后在uboot上运行如下命令:
tftp 0x3c000000SierraTEE.bin; go 0x3c000000;
这样就将SierraTEE.bin启动了。
OV自带的N world Linux内核引导器将内核启动的命令行参数写在 里,启动方式为虚拟盘作根文件系统。若改为SD卡分区作根文件系统,需要以下改动
1. 给SD卡重新分区(之前需备份SD内容):使用fdisk命令给SD卡分区,分为fat32(500M)+ext2(其余SD卡空间)两个分区,fat32为第一个分区,供boot_rom读取boot.in(fsbl+uboot)和uboot读取sierratee.bin;第二个ext2分区作根文件系统,将OV提供的根文件系统内容复制到该分区。使用如下命令:
fdisk /dev/mmcblk0;
n(新建分区)
p(主分区)
1(主分区号1)
11(起始位置11柱面)
+500M(分区大小)
第二个分区类似建立
mkdosfs /dev/mmcblk0p1 (第一个分区格式化为fat32类型)
把boot.bin和sierratee.bin等启动必须得文件(sd卡中原来的所有内容)拷贝到第一个分区
mkfs.ext2 /dev/mmcblk0p2(第二个分区格式化为ext2类型)
将虚拟盘中内容拷贝至该分区
2. 由于引导器的内核启动参数已经写死在程序里,无法修改,因此对内核编译配置项进行修改,设置自己的启动参数,并忽略引导器传递过来的启动参数,将根文件系统从虚拟盘改成SD卡的ext2分区。
修改Xilinx_dir/kernel/first/linux-xlnx/arch/arm/configs/zynq_base_trd_defconfig配置文件的CONFIG_CMDLINE配置项:
CONFIG_CMDLINE="console=tty0 console=ttyPS0,115200 noinitrd root=179:2rw ip=192.168.0.91:::255.255.255.0:ZC702:eth0 earlyprintk mem=512Mmemmap=128M$0x30000000 vmalloc=256M"
设置CONFIG_CMDLINE_FORCE项,使内核强制使用上面的启动参数,忽略引导器传递的阐述
CONFIG_CMDLINE_FORCE=y
重新执行Xilinx_dir下的build.sh,生成新的sierratee.bin,放入sd卡的fat32分区中
启动开发板,走到uboot shell界面下,运行下面的命令
mmcinfo
fatload mmc 0 0x3c000000 sierratee.bin
go 0x3c000000
之后ov启动,至N world的LINUX系统启动,此时的文件系统位于sd卡的ext2分区中,文件读写均会实际保存到sd卡中。
编译方式主要依据OV代码中的README文档。但是此README写的太过简略,甚至有的地方还有错误。本章主要简略描述OV的编译流程以及与README文档编译过程不同的步骤。本此编译正常世界只有一个Guest OS的情况。
Sierraware公司提供的适用于ZC702板的OV源代码编译过程主要受build.sh脚本控制,这个脚本主要有如下几个功能:
1. 编译Linux内核,编译过程中打上TrustZone补丁。
2. 将1的内核加上一个引导器,使其可以被TEE的安全OS引导。
3. 编译TEE,即Monitor软件和TEE OS,然后利用2编译的Linux内核镜像共同生成能够在ZC702上运行的二进制代码。此外,这一步还生成了一些可信应用客户端,用于测试TEE OS的安全服务。
4. 生成根文件系统,生成过程会将3生成的可信应用客户端放入根文件系统中的/root/otz/目录下。
5. 利用4新生成的根文件系统重新生成Linux内核。
6. 利用4新生成的根文件系统重新生成运行在ZC702上的二进制文件。
除了按照README文档修改以外,还需要对trustzone/tzone_sdk目录下的Makefile做如下修改:
1. 修改根文件系统目录,指向OV提供的ZC702专用根文件系统:
ROOT_FILE_SYSTEM_IMAGE:= /home/zhao/xilinx/Xilinx_dir/filesystem/first/ramdisk8M.image.gz
#ROOT_FILE_SYSTEM_IMAGE:= $(SDK_PATH)/../otz_linux/armv5t_min_EB_V6_V7.image
2. 修改板子参数:
#export BOARD:= VE
export BOARD:= zynq7
export ARM_CPU:=CORTEX_A9
#export ARM_CPU:=CORTEX_A15
完成上述修改就可以运行buid.sh生成运行在板子上的二进制代码了。所有生成的二进制代码都放在trustzone/tzone_sdk/bin目录下,主要包括SierraTEE.bin和一些安全客户端应用程序。下图是开发板上列出的客户端应用程序,和一些运行结果。
OV生成了很多个客户端,可以在cp_bin1.sh中将其他的客户端app放入根文件系统。但是在普通世界OS中调用这些客户端都没有任何反应。应该是此OV版本的TEE OS没有运行安全服务。
cp -f$TRUSTZONE_DIR/tzone_sdk/bin/otz_test_app.elf $TMP_MNT1/mnt/root/otz/
cp -f$TRUSTZONE_DIR/tzone_sdk/bin/otz_user_app.elf $TMP_MNT1/mnt/root/otz/
cp -f$TRUSTZONE_DIR/tzone_sdk/bin/otz_virtual_keyboard.elf $TMP_MNT1/mnt/root/otz/
cp -f$TRUSTZONE_DIR/tzone_sdk/bin/otz_play_media.elf $TMP_MNT1/mnt/root/otz/
cp -f$TRUSTZONE_DIR/tzone_sdk/otz_api/build/libotzapi.so $TMP_MNT1/mnt/lib/
build.sh负责总的调度,包括内核、TEE OS以及根文件系统的生成。在此主要分析TEE OS部分。buish.sh与trustzone中Makefile的设置使得trustzone目录中本质执行如下MAKE命令:
$(MAKE) -C $(SDK_PATH)/sierratee
sudo rm -rf sierratee/mmc_fs
boot:
$(MAKE) -C$(SDK_PATH)/sierratee boot
ENABLE_LIBCRYPT:是否产生openssl
此次编译没有让安全内核运行在单独的一个物理内核上,安全世界与正常世界共同使用CPU。下面是OV系统的启动流程:
CPU:CPU.S进行一些初始化操作,然后跳转到C语言的Secure_main函数。
|
Secure_main(Main_Secure.C):这个函数可以看作是安全内核的入口,首先进行一些系统初始化工作,然后将libc.o库以及用户的安全服务()映射到安全世界的内存空间(技术细节有待学习):
/*Load 'C' library to memory */
load_libc_to_memory();
load_user_app_to_memory();
然后通过sa_create_entry_point创建dispatcher(OTZ_SVC_GLOBAL)和linux服务(OTZ_SVC_LINUX,不知道这个服务是干什么的,以后学习),成为S世界第一次运行的服务。linux_task会调用invoke_ns_kernel将CPU切换到N世界。Invoke_ns_kernel函数将寄存器r0设置为INVOKE_NON_SECURE_KERNEL,然后调用SMC指令进入Monitor模式。Monitor模式执行下面的宏定义代码,然后跳转到正常世界。
.macro mon_switchto_nsworld_ctx
GET_CORE_CONTEXTs_sys_current
bl save_context
GET_CORE_CONTEXTns_sys_current
bl restore_context
@clear local monitor
@-------------------
clrex
.endm
|
之后N、S世界通过SMC指令调用互相转换。
通过阅读ug585-Zynq-7000-TRM.pdf和ug821-zynq-7000-swdev.pdf两篇技术文档,可知开发板加电开机之后至安全内核启动共分三部分:boot_rom,第一阶段引导程序fsbl,第二阶段引导程序(uboot)
1.首先执行片上rom中的boot_rom引导程序,引导模式由板子上的strapping
Pins决定,引导模式包括Quad-SPI, SD card, NANDFlash,NOR Flash,JTAG.四种,决定boot_rom从哪种设备上加载用户自定义的引导程序。
2.boot_rom根据boot_mode从相应设备上加载boot_image,boot_image包含第一,第二阶段引导程序(fsbl和uboot)。boot_image必须包含一个满足特定格式,能够被boot_rom识别的boot header。根据说明文档,厂商提供了一个boot_image的生成工具boot_gen和一个fsbl模板程序的源代码,并已经烧写到板子的flash中,具体的boot_image生成过程和boot_image的文件格式请参考上面两篇说明文档,由于flash中已存在厂商提供的boot_image,不用自己生成,细节不再深究。Boot_rom根据boot_header,首先将fsbl加载至片上ram(OCM)中,并将控制权移交给fsbl
3.fsbl加载第二阶段引导程序至ddr内存中&
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。