smem 可以干什么? 通过smem我们可以将sbl中的数据直接传给lk或者kernel,可以不通过cmdline直接将lk中的数据丢给kernel,可以将lk中的数据丢给modem,同样也可以将modem中的一些数据丢给kernel。
sbl中调用smem接口
使用smem 首先需要在h文件中添加对应的factory_smem_type,路径如下所示:BOOT.BF.3.3.2/boot_images/core/boot/secboot3/hw/msm8952/sbl1/sbl1_hw.h
typedef struct
{
int factory_mode;
}factory_smem_type;
sbl中设置factory_smem_type中factory_mode值
void alloc_smem_for_factory_mode( bl_shared_data_type *bl_shared_data )
{
factory_smem_type * factory_info = NULL;
int sbl_factory_mode =1;
factory_info =(factory_smem_type *)smem_alloc(SMEM_ID_VENDOR,sizeof(factory_smem_type));
if (NULL == factory_info ){
boot_log_message("ERROR: alloc smem for factory_info fail!!");
return;
}
factory_info.factory_mode = sbl_factory_mode ;
memset(factory_info ,0,sizeof(factory_smem_type));
boot_log_message("alloc smem for factory_info successful");
return;
}
lk中调用smem接口
同样需要在h文件中添加对应的factory_smem_type,路径如下:platform/msm_shared/smem.h
typedef struct
{
int factory_mode;
}factory_smem_type;
lk 中设置factory_smem_type中factory_mode值
static int set_factory_mode_to_smem()
{
factory_smem_type factory_info ;
unsigned smem_status = 0;
int lk_factory_mode = 1;
memset((void*)&factory_info ,0,sizeof(factory_smem_type));
smem_status= smem_read_alloc_entry(SMEM_ID_VENDOR,&factory_info ,sizeof(factory_smem_type));
if (smem_status){
dprintf(CRITICAL,"Error: read shared memory failed\n");
return -1;
}
factory_info.factory_mode = lk_factory_mode ;
smem_status= smem_write_alloc_entry(SMEM_ID_VENDOR,&factory_info ,sizeof(factory_smem_type));
if (smem_status){
dprintf(CRITICAL,"Error: write shared memory failed\n");
return -1;
}
return 0;
}
lk中读取factory_smem_type中factory_mode值
static void get_factory_mode_from_smem()
{
int ret ;
int lk_read_factory_mode;
ret= smem_read_alloc_entry(SMEM_ID_VENDOR, &factory_info ,factory_smem_type);
lk_read_factory_mode = factory_info.factory_mode;
}
kernel 中调用smem接口
同样,首先需要添加对应的factory_smem_type,路径如下:kernel/include/soc/qcom/smem.h 中
typedef struct
{
int factory_mode;
}factory_smem_type;
kernel 中设置factory_smem_type中factory_mode值
factory_smem_type * factory_info = NULL;
int kernel_factory_mode = 1;
factory_info = (factory_smem_type *)smem_alloc(SMEM_ID_VENDOR, sizeof(factory_smem_type) ,0, SMEM_ANY_HOST_FLAG);
if (NULL == factory_info)
{
pr_err("smem_alloc failed!!!");
}else{
memcpy(factory_info->factory_mode ,kernel_factory_mode ,1);
}
kernel 中获取factory_smem_type中factory_mode值
factory_smem_type * factory_info = NULL;
int kernel_read_factory_mode;
factory_info = (factory_smem_type *)smem_get_entry(SMEM_ID_VENDOR, &smem_item_size ,0, SMEM_ANY_HOST_FLAG);
if (NULL == factory_info)
{
pr_err("smem_get_entry failed!!");
}else{
memcpy(kernel_read_factory_mode,factory_info->factory_mode ,1);
pr_info("kernel_read_factory_mode = %d \n",kernel_read_factory_mode);
}
modem侧调用smem接口
以adsp中为例,首先头文件中添加factory_smem_type,路径如下:adsp_proc/core/api/mproc/smem.h
typedef struct
{
int factory_mode;
}factory_smem_type;
adsp中获取factory_smem_type中factory_mode值
static uint32_t get_factory_mode_from_smem(void)
{
uint32_t smem_item_size = 0;
factory_smem_type * factory_info = NULL;
uint32_t adsp_factory_mode = 0;
factory_info = (factory_smem_type *)smem_get_addr(SMEM_ID_VENDOR2, &smem_item_size);
if (NULL == factory_info)
{
return 0 ;
}else{
adsp_factory_mode = factory_info->factory_mode;
}
return adsp_factory_mode;
}
补充:uefi中设置factory_smem_type中factory_mode值
EFI_SMEM_PROTOCOL * smem_protocol;
factory_smem_type * factory_info = NULL;
int uefi_factory_mode =1;
...
Status = gBS->LocateProtocol(&gEfiSMEMProtocolGuid, NULL,
(void**)&smem_protocol);
if(Status != EFI_SUCCESS)
{
AsciiPrint("ERROR: LocateProtocol returned %d\n", Status);
return Status;
}
Status = smem_protocol->SmemAlloc(SMEM_ID_VENDOR, sizeof(factory_info),
(void **)&factory_info);
if(Status != EFI_SUCCESS)
{
AsciiPrint("ERROR: SmemAlloc(SMEM_ID_VENDOR) returned %d\n", Status);
return Status;
}
if(factory_info == NULL)
{
AsciiPrint("ERROR: smem_alloc(SMEM_ID_VENDOR) != NULL\n");
return EFI_DEVICE_ERROR;
}
factory_info->factory_mode = uefi_factory_mode;
smem每个进程最终会映射到同一块物理内存。smem保存在物理内存,这样读写的速度要比磁盘要快,但是存储量不是特别大。
优缺点
(1)优点:我们可以看到使用共享内存进行进程之间的通信是非常方便的,而且函数的接口也比较简单,数据的共享还使进程间的数据不用传送,而是直接访问内存,加快了程序的效率。
(2)缺点:共享内存没有提供同步机制,这使得我们在使用共享内存进行进程之间的通信时,往往需要借助其他手段来保证进程之间的同步工作。