I. Preparations
Configure IMX6UL EVK platform and transplant OP-TEE to this platform.
2. Realization
1. Write an address access program running in the insecure world of linux and place it in the IMX6UL file system / home/root path.
Create a simple program test_mem.c, code as follows:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#define READ_REG32(reg) ( *((volatile int *) (reg)) )
#define ALLOC_SIZE (1024)
static int read_type()
{
void * map_base;
FILE *f;
int type,fd;
fd = open("/dev/mem", O_RDWR | O_SYNC);
if (fd) {
printf("Success to open /dev/mem fd=%08x\n", fd);
}
else {
printf("Fail to open /dev/mem fd=%08x\n", fd);
}
map_base = mmap(0, ALLOC_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x9D010000);
type = READ_REG32(map_base + 0x20);
close(fd);
munmap(map_base, ALLOC_SIZE);
printf("reg32[%08x] = value[%08x] \n", map_base, type);
type = (type & ( 1 << 27 )) >> 27 ;
printf("reg32[%08x] = value[%08x] \n", map_base, type);
return type;
}
void main()
{
printf("test read lock memory-->\n");
read_type();
}
In this paper, we simply use the common physical memory access method on the Internet, compile it with arm-linux-gnueabihf-gcc cross-compiler, generate a.out file, and place it in the file system/home/root path to test whether the memory is locked successfully.
2. Check whether the 460 [4] bit (TZASC_ENABLE) of ROM efuse is set to 1.
ROM efuse is manufactured without TZASC module by default. It is necessary to burn TZASC_ENABLE to 1 in the following steps:
(1) Set BOOTMODE to 00 and BOOTCFG and SW601 to 0000, so that IMX6UL EVK is set to BOOT FROM FUSES mode, while the default BT_FUSE_SEL is 0, which means fuse can be programmed.
(2) If (1) after setting up, ROM will be started by Nor flash, because there is no boot code, the default jump to USB Download mode, Bootloader can be downloaded to memory, and fuse can be operated.
(3) Use Mfgtool2 to load u-boot.imx into memory RAM. The configuration file is set as follows:
<UCL>
<CFG>
<STATE name="BootStrap" dev="MX6UL" vid="15A2" pid="007D"/>
</CFG>
<LIST name="SDCard" desc="Choose SD Card as media">
<CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot.imx" >Loading U-boot</CMD>
<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>
</LIST>
</UCL>
(3) Using the uboot command, this command sets fuse 0x460[28], or TZASC_ENABLE, to 1, that is, to start loading TZASC module.
fuse prog 0 6 0x10000000
The results are as follows:
3. Check whether the tzasc clock and IOMUXC_GPR_GPR9 register are set to enable:
Relevant operations can be done by static TA. As for the compilation of static TA, the IOMUXC_GPR_GPR9 is not set to enable, and the TZASC clock has been started. Note: If TZASC_ENABLE in efuse is not set to 1, setting IOMUXC_GPR_GPR9 will cause the kernel to crash.
4. Write the tzasc driver and configure the initial value of the register.
Since the TZASC1 driver has been successfully started with u-boot, the code of the security zone is mainly set up here.
#include <drivers/imx_tzasc.h>
#include <util.h>
#include <io.h>
#include <trace.h>
#define TZASC_ACTION 0x004
#define TZASC_LOCKDOWM_RANGE 0x008
#define TZASC_LOCKDOWN_SELECT 0x00C
#define TZASC_SPECULATION_CONTROL 0x030
#define TZASC_SECURITY_INVERSION_EN 0x034
#define TZASC_LOCK_RANGE_EN (1 << 31)
#define TZASC_REGION_SETUP_LOW(n) (0x100 + (n) * 16)
#define TZASC_REGION_SETUP_HIGH(n) (0x104 + (n) * 16)
#define TZASC_REGION_ATTRIBUTES(n) (0x108 + (n) * 16)
#define TZASC_REGION_0_ATTRIBUTE 0xF000003F
#define TZASC_REGION_1_ATTRIBUTE 0xC0000031
#define TZASC_REGION_1_BASE 0x9C000000
#define TZASC_REGION_SET 0x1
void imx_tzasc_init(vaddr_t base)
{
write32(TZASC_REGION_0_ATTRIBUTE, base + TZASC_REGION_ATTRIBUTES(0));
write32(TZASC_REGION_1_BASE, base + TZASC_REGION_SETUP_LOW(1));
write32(TZASC_REGION_1_ATTRIBUTE, base + TZASC_REGION_ATTRIBUTES(1));
}
void tzasc_region_set(struct tzasc_data *data, vaddr_t base)
{
uint32_t region_lock = (1 << data->region_num);
write32(data->tzasc_region_base, base + TZASC_REGION_SETUP_LOW(data->region_num));
write32(data->tzasc_region_base + data->tzasc_region_size,
base + TZASC_REGION_SETUP_HIGH(data->region_num));
write32(TZASC_LOCK_RANGE_EN | region_lock, base + TZASC_LOCKDOWM_RANGE);
}
5. Write static TA to create security zone dynamically.
Three. Test
IMX6UL EVK restart power, enter the common world command line, run a.out program in the / home/root path, and test. Because we configure this address segment as a memory security zone, the address mapping of a.out program will produce data interruption and cannot be mapped. The test results are as follows: