You are currently reviewing an older revision of this page.
Hafnium is a reference Secure Partition Manager (SPM) for systems that implement the Armv8.4-A Secure-EL2 extension. It enables multiple, isolated Secure Partitions (SPs) to run at Secure-EL1.
The Total Compute software stack also includes the BL32 (SPM), which is implemented as a Hafnium software component. You can find the introduction information at Total Compute Platform Software Components.
The following figure shows the software stack of the TC platform:
The TC software stack can support both the buildroot and Android file systems, because the hafnium is part of fimrware. This guide uess the buildroot file system as an example.
Debugging Hafnium on the TC Platform requires three major steps:
Step 1: Set up the workspace for the TC software stack
Step 2: Work on the Hafnium component of TC software stack
Step 3: Set up Arm DS to debug Hafnium
Perform the following steps to build the whole software stack. Consider the buildroot file system as an example. For more information about seting up workspace, see the Total Compute (TC) User Guide.
1. Download and set up the workspace. The content of the workspace directory is as follows:
2. Build the software stack. For example, you can use the build command ./run_docker.sh ./build-all.sh build. After the build is successfully complete, the output images are as follows:
./run_docker.sh ./build-all.sh build
3. Run the related image as follows to boot up successfully:
./run-scripts/tc2/run_model.sh -m <model binary path> -d buildroot
The boot flow of AP firmware is as follows:
BL1 --> BL2 --> BL1 --> BL31 --> BL32(SPM) --> BL31 --> BL33
Perform the following steps to xxxxx (Roy这里需要加信息,你下面两个步骤的目的是什么)::
1. Enable the debug build option.
Add the debug build option to ensure that the symbol file can be used for later debugging as follows:
diff --git a/build/BUILD.gn b/build/BUILD.gn index 1baac1ba..80b9f44d 100644 --- a/build/BUILD.gn +++ b/build/BUILD.gn @@ -20,6 +20,7 @@ config("compiler_defaults") { "-fstack-protector-all", ] + asmflags = ["-g"] cflags_c = [ "-std=c11" ] cflags_cc = [ "-std=c++2a" ]
2. Modify and build Hafnium seperatly.
The build scirpt build-scripts/build-hafnium.sh can be used to build the Hafnium seperately, but the hafnium.bin image is added into the FIP package. Therefore, when you modify and build the source code of hafnium, you must re-package again. The steps can be as follows: build-scripts/run_docker.sh build-scripts/build-hafnium.sh build build-scripts/run_docker.sh build-scripts/build-hafnium.sh deploy build-scripts/run_docker.sh build-scripts/build-tfa.sh build build-scripts/run_docker.sh build-scripts/build-tfa.sh deploy build-scripts/run_docker.sh build-scripts/build-flash-image.sh build build-scripts/run_docker.sh build-scripts/build-flash-image.sh deploy
build-scripts/build-hafnium.sh
hafnium.bin
build-scripts/run_docker.sh build-scripts/build-hafnium.sh build build-scripts/run_docker.sh build-scripts/build-hafnium.sh deploy build-scripts/run_docker.sh build-scripts/build-tfa.sh build build-scripts/run_docker.sh build-scripts/build-tfa.sh deploy build-scripts/run_docker.sh build-scripts/build-flash-image.sh build build-scripts/run_docker.sh build-scripts/build-flash-image.sh deploy
Perform the following steps:
1. Import the TC22 FVP model by following the steps:
A. Click ARM DS Debug Control pannel, and select Debug Congtrol--> New Debug Connection as follows:
B. Choose Model Connection.
Specify the Debug connection name, such as TC22-Hafnium-debug as follows:
TC22-Hafnium-debug
C. Add new model.
Click the Next button for Target Selection. You can select Add a new model ... as follows:
D. Configure the FVP model path.
Choose Select Model Interface(Iris)--> Next--> Launch and connect to specific model --> Next, and browse the Model Path to select the downloaded file path of TC22 model as follows:
TC22 model
E. Show the imported model.
The model is imported as follows:
2. Connect the model.
A. Find the created debug connection.
Open the debug configration as follows:
B. Configure the model parameters.
For example, copy below model paramters into the label as follows:
-C board.flashloader0.fname=/data/jetzho01/tc22-2023.04.21/build-scripts/output/deploy/tc2/fip_gpt-tc.bin -C css.rss.rom.raw_image=/data/jetzho01/tc22-2023.04.21/build-scripts/output/deploy/tc2/rss_rom.bin -C css.scp.c0_pik.rvbaraddr_lw=0x1000 -C css.scp.c0_pik.rvbaraddr_up=0x0000 -C css.rss.VMADDRWIDTH=23 -C css.rss.CMU0_NUM_DB_CH=16 -C displayController=2 -C board.smsc_91c111.enabled=1 -C board.hostbridge.userNetworking=1 -C board.hostbridge.userNetPorts="5555=5555,8080=80,8022=22" --data board.dram=/data/jetzho01/tc22-2023.04.21/build-scripts/output/deploy/tc2/tc-fitImage.bin@0x20000000
C. Set the debug configurations.
1). Load the symbol files to apply and debug as follows:
2). On the window that opens, choose Debugger -> Connect only -> Execute debugger commands, and copy-paste the following lines into the text box to automatically load all symbols into the correct virtual address space each time you connect to the model:
add-symbol-file "<workspace>/build-scripts/output/tmp_build/tfa/build/tc/debug/bl1/bl1.elf" EL3:0x0add-symbol-file "<workspace>/build-scripts/output/tmp_build/tfa/build/tc/debug/bl2/bl2.elf" EL1S:0x0add-symbol-file "<workspace>/build-scripts/output/tmp_build/tfa/build/tc/debug/bl31/bl31.elf" EL3:0x0add-symbol-file "<workspace>/build-scripts/output/tmp_build/hafnium/secure_tc_clang/hafnium.elf" EL2S:0x0
3). Replace <workspace> with the path to your workspace directory.
<workspace>
The EL and number at the end of each command (for example EL2S:0) ensure the symbols are loaded into the correct virtual address space and at the correct memory offset, for software uses absolute addresses for its symbols so we ensure an offset of 0. (Roy:这段太复杂,断句不清晰,很难懂,建议拆分成几个短句)
EL2S:0
4). Click Apply -> Debug to connect to the paused model.
You can now step through the Hafnium code or set a breakpoint on the symbol corresponding to the functionality that you are interested in.
A. Find the entrypoint for Hafnium image.
Entry point of Hafnium code piece is here, for example:
.section .init.entry, "ax" .global entry entry: /* Linux aarch64 image header. */ b 0f .word 0 .quad 0x1000 /* text_offset */ .quad image_size /* image_size */ .quad 0 /* flags */ .quad 0 /* res2 */ .quad 0 /* res3 */ .quad 0 /* res4 */ .word 0x644d5241 /* magic */ .word 0 /* * Calculate the difference between the actual load address and the * preferred one. We'll use this to relocate. */ 0: adrp x25, entry add x25, x25, :lo12:entry
Regarding the entrypoint (loading address) of Hafnium for the TC22 platform, the Hafnium(BL32) is loaded by AP BL2. The image address is defined as BL32_BASE, which can be found at hereh. Specifically for the TC22 platform, the address is redefined as:"#define TC_EL2SPMC_LOAD_ADDR (TC_TZC_DRAM1_BASE + 0x04000000)"The TC_TZC_DRAM1_BASE is defined as 0xF900_0000, so the loading address for Hafnium (BL32_BASE) is 0xFD00_0000.More plaform definitions about this can be found here.
BL32_BASE
"#define TC_EL2SPMC_LOAD_ADDR (TC_TZC_DRAM1_BASE + 0x04000000)"
TC_TZC_DRAM1_BASE
0xF900_0000
0xFD00_0000
B. Stop at the entrypoint.
Set the breakpoint of entry, which is the entrypoint of Hafnium as follows:
entry
C. Check the entry address of Hafnium.
Then Run the code (Roy:run 什么东西,是code吗), and it stops at the first instruction. The address is 0xFD000000 as follows:
The following figure shows you the initialization flow of Hafnium:Example: one_time_init function
one_time_init
Consider the example of setting a breakpoint of one_time_init. (Roy:后面的这句话需要补充信息,什么jump into what?) jump into it as shown in the following figure: