12.OP-TEE OS启动(三)--service_init

   

  

通过分析tee.map文件可知,在编译完成之后,在initcall1段中存放的内容如下:

  遍历整个OP-TEE目录可知,使用service_init(宏,使用__define_initcall告诉编译器,将service_init(fn)中的fn函数的内容存放到initcall1段中,详细见上一章节)将代码内容存放到initcall1段的中的函数如下:

service_init(register_supplicant_user_ta);

service_init(verify_pseudo_tas_conformance);

service_init(tee_cryp_init);

service_init(tee_se_manager_init);

  也即是在执行initcall1段内容的时候将会依次执行register_supplicant_user_ta,verify_pseudo_tas_conformance,tee_cryp_init,tee_se_manager_init函数,上述四个函数存放在目录依次如下:

register_supplicant_user_ta: core/arch/arm/kernel/ree_fs_ta.c

verify_pseudo_tas_conformance: core/arch/arm/kernel/pseudo_ta

tee_cryp_init: core/tee/tee_cryp_utl.c

tee_se_manager_init: core/tee/se/manager.c

1. register_supplicant_user_ta

  该函数的主要作用是将用来加载TA image的操作结构体赋值给user_ta_sotre变量,该变量会在加载TA image的时候被使用到,该函数的代码如下:

/* 定义加载TA image时需要的操作函数指针 */
static const struct user_ta_store_ops ops = {
	.open = ta_open,
	.get_size = ta_get_size,
	.read = ta_read,
	.close = ta_close,
};

static TEE_Result register_supplicant_user_ta(void)
{
	return tee_ta_register_ta_store(&ops);
}

TEE_Result tee_ta_register_ta_store(const struct user_ta_store_ops *ops)
{
	user_ta_store = ops;	//赋值操作
	return TEE_SUCCESS;
}

2.verify_pseudo_tas_conformance函数

  该函数主要作用是用来校验OP-TEE OS中集成的TA的合法性,需要检查OP-TEE OS自有TA的UUID, 函数指针,相关flag。代码如下:

static TEE_Result verify_pseudo_tas_conformance(void)
{
	const struct pseudo_ta_head *start = &__start_ta_head_section;	//获取存放psedo TAs的head info的段起始地址
	const struct pseudo_ta_head *end = &__stop_ta_head_section; //获取存放psedo TAs的head info的段末尾地址
	const struct pseudo_ta_head *pta;	//定义一个纸箱TA head的变量指针

	for (pta = start; pta < end; pta++) {
		const struct pseudo_ta_head *pta2;

		/* PTAs must all have a specific UUID */
/* 检查psedo TAs的head info中包含的UUID信息是否有相同的 */
		for (pta2 = pta + 1; pta2 < end; pta2++)
			if (!memcmp(&pta->uuid, &pta2->uuid, sizeof(TEE_UUID)))
				goto err;

/* 检查invoke函数指针是否为空和相关的flag是否合法 */
		if (!pta->name ||
		    (pta->flags & PTA_MANDATORY_FLAGS) != PTA_MANDATORY_FLAGS ||
		    pta->flags & ~PTA_ALLOWED_FLAGS ||
		    !pta->invoke_command_entry_point)
			goto err;
	}
	return TEE_SUCCESS;
err:
	DMSG("pseudo TA error at %p", (void *)pta);
	panic("pta");
}


__start_ta_head_section与__stop_ta_head_section的定义见core/arch/arm/kernel/kern.ld.S文件,分别表示ta_head_section段的起始地址和末端地址如下:

  那在编译过程中,哪些部分会被添加到ta_head_section段中呢?该操作是通过使用pseudo_ta_register宏来实现的,该宏定义在core/arch/arm/include/kernel/pseudo_ta.h文件中,内容如下:

#define pseudo_ta_register(...) static const struct pseudo_ta_head __head \
			__used __section("ta_head_section") = { __VA_ARGS__ }

  该宏规定使用pseudo_ta_register参数中的pseudo_ta_head结构体变量将会被存放ta_head_section段中。在OP-TEE中会由六个TA会被打包进OP-TEE image,存在文件以及名称如下:

gprof: core/arch/arm/pta/gprof.c

interrupt_tests.ta: core/arch/arm/pta/Iiterrupt_tests.c

stats.ta: core/arch/arm/pta/stats.c

se_api_self_tests.ta: core/arch/arm/pta/se_api_self_tests.c

socket: core/arch/arm/tee/pta_socket.c

invoke_tests.pta: core/arch/arm/pta/pta_invoke_test.c
 

3. tee_cryp_init

  该函数主要完成crypto功能的初始化操作 ,该函数会调用crypto_ops结构体中的init进行初始化操作。该端代码如下是:

static TEE_Result tee_cryp_init(void)
{
	if (crypto_ops.init)
		return crypto_ops.init();

	return TEE_SUCCESS;
}

代码中的crypto_ops定义在core/lib/libtomcrypt/src/tee_ltc_provider.c文件中,该结构体中定义了各种算法的具体操作:

const struct crypto_ops crypto_ops = {
	.name = "LibTomCrypt provider",
	.init = tee_ltc_init,	//crypto初始化函数
#if defined(_CFG_CRYPTO_WITH_HASH)
/* hash算法操作函数 */
	.hash = {
		.get_ctx_size = hash_get_ctx_size,
		.init = hash_init,
		.update = hash_update,
		.final = hash_final,
	},
#endif
#if defined(_CFG_CRYPTO_WITH_CIPHER)
/* cipher相关的操作函数 */
	.cipher = {
		.final = cipher_final,
		.get_block_size = cipher_get_block_size,
		.get_ctx_size = cipher_get_ctx_size,
		.init = cipher_init,
		.update = cipher_update,
	},
#endif
#if defined(_CFG_CRYPTO_WITH_MAC)
/* 执行MAC算法操作的函数 */
	.mac = {
		.get_ctx_size = mac_get_ctx_size,
		.init = mac_init,
		.update = mac_update,
		.final = mac_final,
	},
#endif
#if defined(_CFG_CRYPTO_WITH_AUTHENC)
/* 鉴权算法相关的操作函数 */
	.authenc = {
		.dec_final = authenc_dec_final,
		.enc_final = authenc_enc_final,
		.final = authenc_final,
		.get_ctx_size = authenc_get_ctx_size,
		.init = authenc_init,
		.update_aad = authenc_update_aad,
		.update_payload = authenc_update_payload,
	},
#endif
#if defined(_CFG_CRYPTO_WITH_ACIPHER)
/* RSA算法相关的操作函数 */
	.acipher = {
#if defined(CFG_CRYPTO_RSA)
		.alloc_rsa_keypair = alloc_rsa_keypair,
		.alloc_rsa_public_key = alloc_rsa_public_key,
		.free_rsa_public_key = free_rsa_public_key,
		.gen_rsa_key = gen_rsa_key,
		.rsaes_decrypt = rsaes_decrypt,
		.rsaes_encrypt = rsaes_encrypt,
		.rsanopad_decrypt = rsanopad_decrypt,
		.rsanopad_encrypt = rsanopad_encrypt,
		.rsassa_sign = rsassa_sign,
		.rsassa_verify = rsassa_verify,
#endif
#if defined(CFG_CRYPTO_DH)
		.alloc_dh_keypair = alloc_dh_keypair,
		.gen_dh_key = gen_dh_key,
		.dh_shared_secret = do_dh_shared_secret,
#endif
#if defined(CFG_CRYPTO_DSA)
		.alloc_dsa_keypair = alloc_dsa_keypair,
		.alloc_dsa_public_key = alloc_dsa_public_key,
		.gen_dsa_key = gen_dsa_key,
		.dsa_sign = dsa_sign,
		.dsa_verify = dsa_verify,
#endif
#if defined(CFG_CRYPTO_ECC)
		/* ECDSA and ECDH */
		.alloc_ecc_keypair = alloc_ecc_keypair,
		.alloc_ecc_public_key = alloc_ecc_public_key,
		.gen_ecc_key = gen_ecc_key,
		.free_ecc_public_key = free_ecc_public_key,

		/* ECDSA only */
		.ecc_sign = ecc_sign,
		.ecc_verify = ecc_verify,
		/* ECDH only */
		.ecc_shared_secret = do_ecc_shared_secret,
#endif
	},
/* 大整数相关的操作函数 */
	.bignum = {
		.allocate = bn_allocate,
		.num_bytes = num_bytes,
		.num_bits = num_bits,
		.compare = compare,
		.bn2bin = bn2bin,
		.bin2bn = bin2bn,
		.copy = copy,
		.free = bn_free,
		.clear = bn_clear
	},
#endif /* _CFG_CRYPTO_WITH_ACIPHER */
	.prng = {
		.add_entropy = prng_add_entropy,
		.read = prng_read,
	}
};

该变量中定义的init函数指向tee_ltc_init函数,tee_ltc_init函数的内容如下,主要完成各种算法调用接口的定义和初始化:

static TEE_Result tee_ltc_init(void)
{
#if defined(_CFG_CRYPTO_WITH_ACIPHER)
	tee_ltc_alloc_mpa();
#endif
	tee_ltc_reg_algs();

	return tee_ltc_prng_init(tee_ltc_get_prng());
}

4. tee_se_manager_init

  tee_se_manager_init函数主要完成互斥体的初始化操作,内容如下:

static TEE_Result tee_se_manager_init(void)
{
	struct tee_se_manager_ctx *ctx = &se_manager_ctx;

	context_init(ctx);

	return TEE_SUCCESS;
}
static void context_init(struct tee_se_manager_ctx *ctx)
{
	TAILQ_INIT(&ctx->reader_proxies);
	mutex_init(&ctx->mutex);
	ctx->reader_count = 0;
}


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值