已經實作了UART的安全狀态的切換。打算基于此繼續開發OPTEE_OS相應的各類驅動。
一.資源準備
OPTEE工程源碼:OPTEE官網
注意:根據說明下載下傳hikey_debian的代碼版本。
二.實作方法
1.Hikey_Debian的代碼版本帶有helloworld的樣例TA,可以修改為調用靜态TA,當然也可以自行編寫TA調用靜态TA,調用方法前文講述過了,不再累述。
2.下載下傳OPTEE工程源碼後,本身不能支援靜态TA的編譯和調用,需修改配置檔案,修改方法參見:靜态TA配置
3.修改/devel/optee/optee_os/core/arch/arm/plat-hikey/platform_config.h檔案,經過與OP-TEE官方咨詢,确定Hikey TZPC的基位址為0xF8002000,大小為0x878,修改内容如下:
...
...
#define CONSOLE_UART_BASE 0xF7113000
#else
#error Unknown console UART
#endif
+/* TZPC */
+#define TZPC_BASE 0xF8002000
+#define TZPC_SIZE 0x878
#define CONSOLE_BAUDRATE 115200
#define CONSOLE_UART_CLK_IN_HZ 19200000
...
...
4.修改/devel/optee/optee_os/core/arch/arm/plat-hikey/main.c檔案,預設的OP-TEE的可通路硬體位址中不包含TZPC的位址,需要自行添加進去,TZPC的位址位于安全世界下,則位址空間屬性為MEM_AREA_IO_SEC,由于需要切換UART的運作狀态,同樣需要修改UART的位址權限也為SEC,也就是通路EL1下的位址,修改内容如下:
...
...
.cpu_suspend = pm_do_nothing,
.cpu_resume = pm_do_nothing,
.system_off = pm_do_nothing,
.system_reset = pm_do_nothing,
};
-register_phys_mem(MEM_AREA_IO_SEC, CONSOLE_UART_BASE, PL011_REG_SIZE);
+register_phys_mem(MEM_AREA_IO_SEC, CONSOLE_UART_BASE, PL011_REG_SIZE);
+register_phys_mem(MEM_AREA_IO_SEC, TZPC_BASE, TZPC_SIZE);
const struct thread_handlers *generic_boot_get_handlers(void)
{
return &handlers;
}
...
...
4.在/devel/optee/optee_os/core/arch/arm/sta/目錄下,建立sta_reg.c檔案,作為靜态TA檔案,内容如下:
#include <compiler.h>
#include <stdio.h>
#include <trace.h>
#include <kernel/static_ta.h>
#include <string.h>
#include <string_ext.h>
#include <mm/tee_pager.h>
#include <mm/core_memprot.h>
#include <drivers/pl011.h>
#include <io.h>
#define TA_NAME "sta_reg.ta"
#define STA_REG_UUID \
{ , , , \
{ , , , , , , , } }
#define STA_READ_STATS 0
#define STA_WRITE_STATS 1
#define CONSOLE_UART_BASE 0xF7113000
/* flag register */
/* TZPC */
#define TZPC_BASE 0xF8002000
#define TZPC_SIZE 0x878
#define SLAVE_PROTX_STATE 0x830
#define SLAVE_PROTX_SET 0x834
#define SLAVE_PROTX_CLEAN 0x838
/*
#define set_sec_uart0 (1 << 26) UART0 設定安全狀态
#define set_sec_uart1 (1 << 27) UART1 設定安全狀态
#define set_sec_uart2 (1 << 28) UART2 設定安全狀态
#define set_sec_uart3 (1 << 29) UART3 設定安全狀态
#define set_sec_uart4 (1 << 30) UART4 設定安全狀态
*/
static vaddr_t console_base(void)
{
static void *va;
if (cpu_mmu_enabled()) {
if (!va)
va = phys_to_virt(CONSOLE_UART_BASE, MEM_AREA_IO_SEC);
return (vaddr_t)va;
}
return CONSOLE_UART_BASE;
}
static vaddr_t tzpc_base(void)
{
static void *va;
if (cpu_mmu_enabled()) {
if (!va)
va = phys_to_virt(TZPC_BASE, MEM_AREA_IO_SEC);
return (vaddr_t)va;
}
return TZPC_BASE;
}
static TEE_Result read_regs(uint32_t type __unused, TEE_Param p[] __unused)
{
EMSG("TZPC_UART_STATE: 0x%x\n",read32(tzpc_base()+SLAVE_PROTX_STATE));
return TEE_SUCCESS;
}
static TEE_Result write_regs(uint32_t type __unused, TEE_Param p[] __unused)
{
vaddr_t uart_base = console_base();
int ch;
MSG("TZPC_WRITE_UART:on the write");
write32(, tzpc_base()+SLAVE_PROTX_SET);
DMSG("TZPC_WRITE_UART:on the write finish");
DMSG("welcome into the secure world!\n");
DMSG("please input 'a' to back the normal world!\n");
DMSG("TZPC_UART_STATE: 0x%x\n",read32(tzpc_base()+SLAVE_PROTX_STATE));
do
{
ch = pl011_getchar(uart_base);
}while(ch != )
write32(, tzpc_base()+SLAVE_PROTX_CLEAN);
DMSG("have been back to the normal world!\n");
return TEE_SUCCESS;
}
/*
* Trusted Application Entry Points
*/
static TEE_Result create_ta(void)
{
return TEE_SUCCESS;
}
static void destroy_ta(void)
{
}
static TEE_Result open_session(uint32_t ptype __unused,
TEE_Param params[] __unused,
void **ppsess __unused)
{
return TEE_SUCCESS;
}
static void close_session(void *psess __unused)
{
}
static TEE_Result invoke_command(void *psess __unused,
uint32_t cmd, uint32_t ptypes,
TEE_Param params[])
{
switch (cmd) {
case STA_READ_STATS:
return read_regs(ptypes, params);
case STA_WRITE_STATS:
return write_regs(ptypes, params);
default:
break;
}
return TEE_ERROR_BAD_PARAMETERS;
}
static_ta_register(.uuid = STA_REG_UUID, .name = TA_NAME,
.create_entry_point = create_ta,
.destroy_entry_point = destroy_ta,
.open_session_entry_point = open_session,
.close_session_entry_point = close_session,
.invoke_command_entry_point = invoke_command);
這個靜态TA的主要功能是配置TZPC,并使用設定寄存器對其進行修改,使UART0處于安全狀态下,無法被普通世界下的DEBIAN系統通路,直到輸入‘a‘,切換回非安全狀态,具體的各寄存器功能可以參見Hi6210sft的相關寄存器接口的功能介紹。