更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_vdso.h 文件参考

浏览源代码.

函数

UINT32 OsVdsoInit (VOID)
 vdso初始化 更多...
 
vaddr_t OsVdsoLoad (const LosProcessCB *)
 OsVdsoLoad 为指定进程加载vdso
本质是将系统镜像中的vsdo部分映射到进程空间 更多...
 
VOID OsVdsoTimevalUpdate (VOID)
 OsVdsoTimevalUpdate
更新时间,根据系统时钟中断不断将内核一些数据刷新进VDSO的数据页; 更多...
 

函数说明

◆ OsVdsoInit()

UINT32 OsVdsoInit ( VOID  )

vdso初始化

在文件 los_vdso.c96 行定义.

97{//so文件不保存在文件系统中,而是存在于系统镜像中,镜像中的位置在代码区和数据区中间
98 g_vdsoSize = &__vdso_text_end - &__vdso_data_start;//VDSO 会映射两块内存区域:代码段 [vdso],只读数据区 [vvar] 数据页
99 //先检查这是不是一个 ELF文件
100 if (memcmp((CHAR *)(&__vdso_text_start), ELF_HEAD, ELF_HEAD_LEN)) {//.incbin OHOS_VDSO_SO 将原封不动的一个二进制文件编译到当前文件中
101 PRINT_ERR("VDSO Init Failed!\n");
102 return LOS_NOK;
103 }
104 return LOS_OK;
105}
char CHAR
Definition: los_typedef.h:63
STATIC size_t g_vdsoSize
Definition: los_vdso.c:94
CHAR __vdso_data_start
数据区起始地址 __vdso_data_start < __vdso_text_start
CHAR __vdso_text_end
代码区结束地址
CHAR __vdso_text_start
代码区起始地址
int memcmp(const void *str1, const void *str2, size_t n)
Definition: memcmp.c:37
函数调用图:

◆ OsVdsoLoad()

vaddr_t OsVdsoLoad ( const LosProcessCB processCB)

OsVdsoLoad 为指定进程加载vdso
本质是将系统镜像中的vsdo部分映射到进程空间

参数
processCB
返回
参见

在文件 los_vdso.c147 行定义.

148{
149 INT32 ret = -1;
150 LosVmMapRegion *vdsoRegion = NULL;
151 UINT32 flag = VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_EXECUTE; //用户空间区,可读,可执行,但不可写
152 //用户区,可读可执行
153 if ((processCB == NULL) || (processCB->vmSpace == NULL)) {
154 return 0;
155 }
156
157 (VOID)LOS_MuxAcquire(&processCB->vmSpace->regionMux);
158 //由虚拟空间提供加载内存
159 vdsoRegion = LOS_RegionAlloc(processCB->vmSpace, 0, g_vdsoSize, flag, 0);//申请进程空间 g_vdsoSize 大小线性区,用于映射
160 if (vdsoRegion == NULL) {
161 PRINT_ERR("%s %d, region alloc failed in vdso load\n", __FUNCTION__, __LINE__);
162 goto LOCK_RELEASE;
163 }
164 vdsoRegion->regionFlags |= VM_MAP_REGION_FLAG_VDSO;//标识为 vdso区
165 //为vsdo做好映射,如此通过访问进程的虚拟地址就可以访问到真正的vsdo
166 ret = OsVdsoMap(processCB->vmSpace, g_vdsoSize, LOS_PaddrQuery((VOID *)(&__vdso_data_start)),
167 vdsoRegion->range.base, flag);//__vdso_data_start 为 vdso 的起始地址
168 if (ret != LOS_OK) {//映射失败就释放线性区
169 ret = LOS_RegionFree(processCB->vmSpace, vdsoRegion);
170 if (ret) {
171 PRINT_ERR("%s %d, free region failed, ret = %d\n", __FUNCTION__, __LINE__, ret);
172 }
173 ret = -1;
174 }
175
176LOCK_RELEASE:
177 (VOID)LOS_MuxRelease(&processCB->vmSpace->regionMux);
178 if (ret == LOS_OK) {
179 return (vdsoRegion->range.base + PAGE_SIZE);
180 }
181 return 0;
182}
signed int INT32
Definition: los_typedef.h:60
unsigned int UINT32
Definition: los_typedef.h:57
STATIC INT32 OsVdsoMap(LosVmSpace *space, size_t len, PADDR_T paddr, VADDR_T vaddr, UINT32 flag)
OsVdsoMap 映射,这里先通过内核地址找到 vdso的物理地址,再将物理地址映射到进程的线性区. 结论是每个进程都可以拥有自己的 vdso区,映射到同一个块物理地址.
Definition: los_vdso.c:122
STATIC INLINE STATUS_T LOS_MuxAcquire(LosMux *m)
Definition: los_vm_lock.h:48
STATIC INLINE STATUS_T LOS_MuxRelease(LosMux *m)
Definition: los_vm_lock.h:53
PADDR_T LOS_PaddrQuery(VOID *vaddr)
通过虚拟地址查询映射的物理地址
Definition: los_vm_map.c:550
STATUS_T LOS_RegionFree(LosVmSpace *space, LosVmMapRegion *region)
释放进程空间指定线性区
Definition: los_vm_map.c:694
LosVmMapRegion * LOS_RegionAlloc(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags, VM_OFFSET_T pgoff)
Definition: los_vm_map.c:581
LosVmSpace * vmSpace
VADDR_T base
Definition: los_vm_map.h:84
UINT32 regionFlags
Definition: los_vm_map.h:125
LosVmMapRange range
Definition: los_vm_map.h:123
LosMux regionMux
Definition: los_vm_map.h:149
函数调用图:
这是这个函数的调用关系图:

◆ OsVdsoTimevalUpdate()

VOID OsVdsoTimevalUpdate ( VOID  )

OsVdsoTimevalUpdate
更新时间,根据系统时钟中断不断将内核一些数据刷新进VDSO的数据页;

返回
参见
OsTickHandler 函数

在文件 los_vdso.c203 行定义.

204{
205 VdsoDataPage *kVdsoDataPage = (VdsoDataPage *)(&__vdso_data_start);//获取vdso 数据区
206
207 LockVdsoDataPage(kVdsoDataPage);//锁住数据页
208 OsVdsoTimeGet(kVdsoDataPage); //更新数据页时间
209 UnlockVdsoDataPage(kVdsoDataPage);//解锁数据页
210}
STATIC VOID LockVdsoDataPage(VdsoDataPage *vdsoDataPage)
对数据页加锁
Definition: los_vdso.c:184
STATIC VOID UnlockVdsoDataPage(VdsoDataPage *vdsoDataPage)
对数据页加锁
Definition: los_vdso.c:190
VOID OsVdsoTimeGet(VdsoDataPage *vdsoDataPage)
将最新的时间刷进数据页
Definition: time.c:1200
函数调用图:
这是这个函数的调用关系图: