ARM TZ learning and experiment (1)

1 Overview

I saw a very good git on the linaro official website. The amount of code in it is not large, but it is a good learning use case. Let me record the learning process below.

2. Code download

link: code link

https://git.linaro.org/virtualization/qemu-tztest.git/

3. Compile and run

3.1 Install related tools

sudo apt-get install qemu-system-aarch64

3.2 configuration

Run in the source code directory:

./configure --arch=aarch64

Automatically generate aarch64.mk

CFLAGS += -DFORMAT="elf64-littleaarch64" -mcmodel=large
CFLAGS += -DARCH="aarch64"
CFLAGS += -DAARCH64

3.3 compile

Execute make in the source code directory

3.4 run

Add the following content to the Makefile in the root directory ( remove the "+" sign when copying ):

diff --git a/Makefile b/Makefile
index dbdc10a..f5e63aa 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,7 @@ CFLAGS += -I$(ARCH) -I../common/$(ARCH) -I../common
 CFLAGS += $(call cc-option, -fomit-frame-pointer, "")
 CFLAGS += $(call cc-option, -fno-stack-protector, "")
 CFLAGS += $(call cc-option, -fno-stack-protector-all, "")
-
+CFLAGS += -DDEBUG
 export CFLAGS
 
 BIOS_IMAGE             = tztest.img
@@ -71,6 +71,11 @@ $(EL0_S_IMAGE):
 $(EL0_NS_IMAGE):
        $(MAKE) -C el0/nonsecure all

+run:
+       qemu-system-aarch64 -bios tztest.img -machine virt,secure=on -cpu cortex-a57 -serial stdio
+
 clean:
        $(MAKE) -C libcflat clean
        $(MAKE) -C el3 clean

implement:

make run

Run the LOG as follows:

qemu-system-aarch64 -bios tztest.img -machine virt,secure=on -cpu cortex-a57 -serial stdio
VNC server running on 127.0.0.1:5900
#EL3 started...350377984
rambase:40000000, ptbase:40040000

[DEBUG] mem_unmap_va (secure): unmapped PTE 0x40043000 (VA:0x0, PA:0x0)
[DEBUG] mem_map_pa (secure): mapped VA:0x40055000 to PA:0x40055000 - PTE:0x400512a8 (0x40055443)
[DEBUG] mem_map_pa (secure): mapped VA:0xf001000000 to PA:0x40054000 - PTE:0x40055000 (0x40054443)
[DEBUG] mem_map_pa (secure): mapped VA:0xf001001000 to PA:0x40056000 - PTE:0x40055008 (0x40056443)EL1 (�e) started...

[DEBUG] mem_unmap_va (secure): unmapped PTE 0x41043080 (VA:0x10000, PA:0x10000)
[DEBUG] mem_map_pa (secure): mapped VA:0x41058000 to PA:0x41058000 - PTE:0x410552c0 (0x41058443)
[DEBUG] mem_map_pa (secure): mapped VA:0xc001000000 to PA:0x41057000 - PTE:0x41058000 (0x41057443)
[DEBUG] mem_map_pa (secure): mapped VA:0xc001000000 to PA:0x40054000 - PTE:0x41058000 (0x40054443)
[DEBUG] mem_map_pa (secure): mapped VA:0x41059000 to PA:0x41059000 - PTE:0x410552c8 (0x41059443)
[DEBUG] mem_map_pa (secure): mapped VA:0x4105a000 to PA:0x4105a000 - PTE:0x410552d0 (0x4105a443)
[DEBUG] mem_map_pa (secure): mapped VA:0xf001001000 to PA:0x40056000 - PTE:0x4105a008 (0x40056443)
[DEBUG] mem_map_pa (secure): mapped VA:0x50000 to PA:0x50000 - PTE:0x41043280 (0x50443)
[DEBUG] el1_load_el0 (secure): Loading aarch64 EL0 test image...

[DEBUG] mem_map_pa (secure): mapped VA:0x51000 to PA:0x51000 - PTE:0x41043288 (0x51443)
[DEBUG] mem_map_pa (secure): mapped VA:0x52000 to PA:0x52000 - PTE:0x41043290 (0x52443)
[DEBUG] mem_map_pa (secure): mapped VA:0x53000 to PA:0x53000 - PTE:0x41043298 (0x53443)
[DEBUG] mem_map_pa (secure): mapped VA:0x54000 to PA:0x54000 - PTE:0x410432a0 (0x54443)
[DEBUG] mem_map_pa (secure): mapped VA:0x55000 to PA:0x55000 - PTE:0x410432a8 (0x55443)
[DEBUG] mem_map_pa (secure): mapped VA:0x56000 to PA:0x56000 - PTE:0x410432b0 (0x56443)
[DEBUG] mem_map_pa (secure): mapped VA:0x57000 to PA:0x57000 - PTE:0x410432b8 (0x57443)
[DEBUG] mem_map_pa (secure): mapped VA:0x58000 to PA:0x58000 - PTE:0x410432c0 (0x58443)
[DEBUG] mem_map_pa (secure): mapped VA:0x59000 to PA:0x59000 - PTE:0x410432c8 (0x59443)
[DEBUG] mem_map_pa (secure): mapped VA:0x5a000 to PA:0x5a000 - PTE:0x410432d0 (0x5a443)

4. Code compilation

4.1 Root Directory Makefile

# 定义目标对象
BIOS_IMAGE 		= tztest.img
LIBCFLAT		= libcflat.a
EL3_IMAGE		= el3/el3.bin
EL1_S_IMAGE		= el1/secure/el1_sec.bin
EL1_NS_IMAGE	= el1/nonsecure/el1_nsec.bin
EL0_S_IMAGE 	= el0/secure/el0_sec.elf
EL0_NS_IMAGE 	= el0/nonsecure/el0_nsec.elf

# tztest.img编译与依赖,将el3.bin el1_sec.bin等文件打包成tztest.img文件
$(BIOS_IMAGE): $(LIBCFLAT) $(EL3_IMAGE) $(EL1_S_IMAGE) $(EL1_NS_IMAGE) \
			   $(EL0_S_IMAGE) $(EL0_NS_IMAGE)
	dd if=$(EL3_IMAGE) of=$@ 2> /dev/null
	dd oflag=seek_bytes seek=65536 if=$(EL1_S_IMAGE) of=$@ 2> /dev/null
	dd oflag=seek_bytes seek=131072 if=$(EL1_NS_IMAGE) of=$@ 2> /dev/null
	dd oflag=seek_bytes seek=196608 if=$(EL0_NS_IMAGE) of=$@ 2> /dev/null
	dd oflag=seek_bytes seek=327680 if=$(EL0_S_IMAGE) of=$@ 2> /dev/null
	chmod +x $(BIOS_IMAGE)
	
# 编译一个轻量级的libc
$(LIBCFLAT):
	$(MAKE) -C libcflat all

# 编译el3的image
$(EL3_IMAGE):
	$(MAKE) -C el3 all
# 编译secure el1的image
$(EL1_S_IMAGE):
	$(MAKE) -C el1/secure all
# 编译non secure el1的镜像
$(EL1_NS_IMAGE):
	$(MAKE) -C el1/nonsecure all
# 编译secure el0的镜像
$(EL0_S_IMAGE):
	$(MAKE) -C el0/secure all
# 编译non seucre el0的镜像
$(EL0_NS_IMAGE):
	$(MAKE) -C el0/nonsecure all

4.1.1 dd command in the shell

dd if=$(EL3_IMAGE) of=$@ 2> /dev/null
2> /dev/null是将错误信息重定向,不输出,遇到报错,不在终端上输出错误信息

dd: Copy a file in blocks of the specified size, and perform the specified conversion while copying.

  • if=filename: input filename, the default is standard input. That is, specify the source file. <if=input file>
  • of=filename: output filename, the default is standard output. That is, specify the destination file. <of=output file>
  • ibs=bytes: read bytes bytes at a time, that is, specify a block size of bytes bytes.
    obs=bytes: Output bytes bytes at a time, that is, specify a block size of bytes bytes.
    bs=bytes: At the same time, set the block size of the read/output to bytes bytes.
  • cbs=bytes: Convert bytes bytes at a time, that is, specify the conversion buffer size.
  • skip=blocks: Skip blocks blocks from the beginning of the input file before starting to copy.
  • seek=blocks: Skip blocks blocks from the beginning of the output file before starting to copy.

4.2 el3/Makefile

This records the VPATH of a Makefile, as follows:

VPATH	= $(ARCH):../common/$(ARCH):../common:../tztest/el3:../tztest

It means that the source files such as .c and .S under these directories can be found automatically, without adding the directory name, as follows:

EL3_OBJS		= el3_init.o \
				  el3_exception.o \
				  el3.o \
				  el3_monitor_asm.o \
				  mem_util.o \
				  builtins.o \
				  tztest.o \
				  tztest_el3.o

The tztest_el3.c file is in the ./tztest/el3/tztest_el3.c path. After we add the VPATH path, we don’t need to add the name of the folder on obj. The compiler will automatically search for the source code under these directories.

5. Add printing LOG to assembly

UART address of the virt platform:

#define UART0_BASE 0x09000000

Print LOG by the following method

	ldr x0, =0x09000000
	ldr x1, =35  //printf "#"
	str x1, [x0]
    str x1, [x0]
    str x1, [x0]
    str x1, [x0]
    str x1, [x0]

The LOG is printed as follows:
##### in many places are all printed by us (remember to make clean && make && make run when compiling, to take effect, the Makefile is not well written, which causes the incremental compilation of the root directory to not take effect )

qemu-system-aarch64 -bios tztest.img -machine virt,secure=on -cpu cortex-a57 -serial stdio
VNC server running on 127.0.0.1:5900
#####EL3 started...23025664

in the end, have fun…

Guess you like

Origin blog.csdn.net/weixin_47139576/article/details/131739927