对 vdso 实现注解

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    国内:https://weharmony.21cloudbox.com
    国外:https://weharmony.github.io
上级 e4db6d2c
../../../../../third_party/FreeBSD/sys/dev/usb/usb_debug.c ../../../../../third_party/FreeBSD/sys/dev/usb/usb_debug.c
\ No newline at end of file
../../../../../third_party/FreeBSD/sys/dev/usb/usb_dev.c ../../../../../third_party/FreeBSD/sys/dev/usb/usb_dev.c
\ No newline at end of file
../../../../../third_party/FreeBSD/sys/dev/usb/usb_device.c ../../../../../third_party/FreeBSD/sys/dev/usb/usb_device.c
\ No newline at end of file
...@@ -133,11 +133,11 @@ STATIC const long long g_adjPacement = (((LOSCFG_BASE_CORE_ADJ_PER_SECOND * SCHE ...@@ -133,11 +133,11 @@ STATIC const long long g_adjPacement = (((LOSCFG_BASE_CORE_ADJ_PER_SECOND * SCHE
LOSCFG_BASE_CORE_TICK_PER_SECOND) * OS_SYS_NS_PER_US); LOSCFG_BASE_CORE_TICK_PER_SECOND) * OS_SYS_NS_PER_US);
/* accumulative time delta from continuous modify, such as adjtime */ /* accumulative time delta from continuous modify, such as adjtime */
STATIC struct timespec64 g_accDeltaFromAdj; STATIC struct timespec64 g_accDeltaFromAdj;//连续修改的累积时间增量,例如 adjtime
/* accumulative time delta from discontinuous modify, such as settimeofday */ /* accumulative time delta from discontinuous modify, such as settimeofday */
STATIC struct timespec64 g_accDeltaFromSet; STATIC struct timespec64 g_accDeltaFromSet;//来自不连续修改的累积时间增量,例如 settimeofday
VOID OsAdjTime(VOID) VOID OsAdjTime(VOID)//时间调整
{ {
UINT32 intSave; UINT32 intSave;
...@@ -272,12 +272,12 @@ STATIC INLINE struct timespec64 OsTimeSpecSub(const struct timespec64 t1, const ...@@ -272,12 +272,12 @@ STATIC INLINE struct timespec64 OsTimeSpecSub(const struct timespec64 t1, const
return ret; return ret;
} }
//获取硬件时间
STATIC VOID OsGetHwTime(struct timespec64 *hwTime) STATIC VOID OsGetHwTime(struct timespec64 *hwTime)
{ {
UINT64 nowNsec; UINT64 nowNsec;
nowNsec = LOS_CurrNanosec(); nowNsec = LOS_CurrNanosec();//当前纳秒
hwTime->tv_sec = nowNsec / OS_SYS_NS_PER_SECOND; hwTime->tv_sec = nowNsec / OS_SYS_NS_PER_SECOND;
hwTime->tv_nsec = nowNsec - hwTime->tv_sec * OS_SYS_NS_PER_SECOND; hwTime->tv_nsec = nowNsec - hwTime->tv_sec * OS_SYS_NS_PER_SECOND;
} }
...@@ -1096,7 +1096,7 @@ int getitimer(int which, struct itimerval *value) ...@@ -1096,7 +1096,7 @@ int getitimer(int which, struct itimerval *value)
} }
#ifdef LOSCFG_KERNEL_VDSO #ifdef LOSCFG_KERNEL_VDSO
VOID OsVdsoTimeGet(VdsoDataPage *vdsoDataPage) VOID OsVdsoTimeGet(VdsoDataPage *vdsoDataPage)//获取数据页信息
{ {
UINT32 intSave; UINT32 intSave;
struct timespec64 tmp = {0}; struct timespec64 tmp = {0};
...@@ -1109,11 +1109,11 @@ VOID OsVdsoTimeGet(VdsoDataPage *vdsoDataPage) ...@@ -1109,11 +1109,11 @@ VOID OsVdsoTimeGet(VdsoDataPage *vdsoDataPage)
OsGetHwTime(&hwTime); OsGetHwTime(&hwTime);
LOS_SpinLockSave(&g_timeSpin, &intSave); LOS_SpinLockSave(&g_timeSpin, &intSave);
tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj); tmp = OsTimeSpecAdd(hwTime, g_accDeltaFromAdj);//添加时间
vdsoDataPage->monoTimeSec = tmp.tv_sec; vdsoDataPage->monoTimeSec = tmp.tv_sec;
vdsoDataPage->monoTimeNsec = tmp.tv_nsec; vdsoDataPage->monoTimeNsec = tmp.tv_nsec;
tmp = OsTimeSpecAdd(tmp, g_accDeltaFromSet); tmp = OsTimeSpecAdd(tmp, g_accDeltaFromSet);//添加时间
vdsoDataPage->realTimeSec = tmp.tv_sec; vdsoDataPage->realTimeSec = tmp.tv_sec;
vdsoDataPage->realTimeNsec = tmp.tv_nsec; vdsoDataPage->realTimeNsec = tmp.tv_nsec;
LOS_SpinUnlockRestore(&g_timeSpin, intSave); LOS_SpinUnlockRestore(&g_timeSpin, intSave);
......
...@@ -52,7 +52,7 @@ struct Mount {//装载 ...@@ -52,7 +52,7 @@ struct Mount {//装载
int vnodeSize; /* size of vnode list */ //节点数量 int vnodeSize; /* size of vnode list */ //节点数量
LIST_HEAD activeVnodeList; /* list of active vnodes */ //激活的节点链表 LIST_HEAD activeVnodeList; /* list of active vnodes */ //激活的节点链表
int activeVnodeSize; /* szie of active vnodes list *///激活的节点数量 int activeVnodeSize; /* szie of active vnodes list *///激活的节点数量
void *data; /* private data */ //私有数据 void *data; /* private data */ //私有数据,可使用这个成员作为一个指向它们自己内部数据的指针
uint32_t hashseed; /* Random seed for vfs hash */ //vfs 哈希随机种子 uint32_t hashseed; /* Random seed for vfs hash */ //vfs 哈希随机种子
unsigned long mountFlags; /* Flags for mount */ //装载标签 unsigned long mountFlags; /* Flags for mount */ //装载标签
char pathName[PATH_MAX]; /* path name of mount point */ //装载点路径名称 char pathName[PATH_MAX]; /* path name of mount point */ //装载点路径名称
......
...@@ -105,4 +105,4 @@ void los_vfs_init(void)//只能调用一次,多次调用将会造成文件系 ...@@ -105,4 +105,4 @@ void los_vfs_init(void)//只能调用一次,多次调用将会造成文件系
g_vfs_init = true; g_vfs_init = true;
} }
LOS_MODULE_INIT(los_vfs_init, LOS_INIT_LEVEL_KMOD_BASIC); LOS_MODULE_INIT(los_vfs_init, LOS_INIT_LEVEL_KMOD_BASIC);//文件模块初始化
...@@ -1776,4 +1776,4 @@ LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID) ...@@ -1776,4 +1776,4 @@ LITE_OS_SEC_TEXT UINT32 OsResourceFreeTaskCreate(VOID)
return ret; return ret;
} }
LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK); LOS_MODULE_INIT(OsResourceFreeTaskCreate, LOS_INIT_LEVEL_KMOD_TASK);//资源回收任务初始化
...@@ -123,7 +123,7 @@ UINT32 OsMpInit(VOID) ...@@ -123,7 +123,7 @@ UINT32 OsMpInit(VOID)
return LOS_OK; return LOS_OK;
} }
LOS_MODULE_INIT(OsMpInit, LOS_INIT_LEVEL_KMOD_TASK); LOS_MODULE_INIT(OsMpInit, LOS_INIT_LEVEL_KMOD_TASK);//多处理器模块初始化
#endif #endif
...@@ -812,7 +812,7 @@ UINT32 OsSchedInit(VOID) ...@@ -812,7 +812,7 @@ UINT32 OsSchedInit(VOID)
#endif #endif
return LOS_OK; return LOS_OK;
} }
//获取优先级最高的任务
STATIC LosTaskCB *OsGetTopTask(VOID) STATIC LosTaskCB *OsGetTopTask(VOID)
{ {
UINT32 priority, processPriority; UINT32 priority, processPriority;
...@@ -849,7 +849,7 @@ FIND_TASK: ...@@ -849,7 +849,7 @@ FIND_TASK:
OsSchedDeTaskQueue(newTask, OS_PCB_FROM_PID(newTask->processID)); OsSchedDeTaskQueue(newTask, OS_PCB_FROM_PID(newTask->processID));
return newTask; return newTask;
} }
//开始调度,每个CPU核都会执行这个函数一次.
VOID OsSchedStart(VOID) VOID OsSchedStart(VOID)
{ {
UINT32 cpuid = ArchCurrCpuid(); UINT32 cpuid = ArchCurrCpuid();
......
...@@ -80,7 +80,7 @@ const CHAR *OsGetRegionNameOrFilePath(LosVmMapRegion *region) ...@@ -80,7 +80,7 @@ const CHAR *OsGetRegionNameOrFilePath(LosVmMapRegion *region)
} }
return ""; return "";
} }
//
INT32 OsRegionOverlapCheckUnlock(LosVmSpace *space, LosVmMapRegion *region) INT32 OsRegionOverlapCheckUnlock(LosVmSpace *space, LosVmMapRegion *region)
{ {
LosVmMapRegion *regionTemp = NULL; LosVmMapRegion *regionTemp = NULL;
......
...@@ -247,7 +247,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID) ...@@ -247,7 +247,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID)
#endif #endif
} }
LOS_MODULE_INIT(OomTaskInit, LOS_INIT_LEVEL_KMOD_TASK); LOS_MODULE_INIT(OomTaskInit, LOS_INIT_LEVEL_KMOD_TASK);//初始化内存监控模块
#endif #endif
...@@ -179,9 +179,9 @@ ERROR: ...@@ -179,9 +179,9 @@ ERROR:
VM_ERR("ShmInit fail\n"); VM_ERR("ShmInit fail\n");
return LOS_NOK; return LOS_NOK;
} }
//共享内存反初始化
LOS_MODULE_INIT(ShmInit, LOS_INIT_LEVEL_VM_COMPLETE);
LOS_MODULE_INIT(ShmInit, LOS_INIT_LEVEL_VM_COMPLETE);//共享内存模块初始化
//共享内存反初始化
UINT32 ShmDeinit(VOID) UINT32 ShmDeinit(VOID)
{ {
UINT32 ret; UINT32 ret;
......
...@@ -144,12 +144,12 @@ static int HiLogBufferCopy(unsigned char *dst, unsigned dstLen, unsigned char *s ...@@ -144,12 +144,12 @@ static int HiLogBufferCopy(unsigned char *dst, unsigned dstLen, unsigned char *s
} }
return retval; return retval;
} }
//读取ring buffer
static int HiLogReadRingBuffer(unsigned char *buffer, size_t bufLen) static int HiLogReadRingBuffer(unsigned char *buffer, size_t bufLen)
{ {
size_t retval; size_t retval;
size_t bufLeft = HILOG_BUFFER - g_hiLogDev.headOffset; size_t bufLeft = HILOG_BUFFER - g_hiLogDev.headOffset;
if (bufLeft > bufLen) { if (bufLeft > bufLen) {//计算出读取方向
retval = HiLogBufferCopy(buffer, bufLen, HiLogBufferHead(), bufLen); retval = HiLogBufferCopy(buffer, bufLen, HiLogBufferHead(), bufLen);
} else { } else {
retval = HiLogBufferCopy(buffer, bufLen, HiLogBufferHead(), bufLeft); retval = HiLogBufferCopy(buffer, bufLen, HiLogBufferHead(), bufLeft);
...@@ -336,4 +336,4 @@ int OsHiLogDriverInit(VOID) ...@@ -336,4 +336,4 @@ int OsHiLogDriverInit(VOID)
return register_driver(HILOG_DRIVER, &g_hilogFops, DRIVER_MODE, NULL);//注册字符设备驱动程序,生成inode节点 return register_driver(HILOG_DRIVER, &g_hilogFops, DRIVER_MODE, NULL);//注册字符设备驱动程序,生成inode节点
} }
LOS_MODULE_INIT(OsHiLogDriverInit, LOS_INIT_LEVEL_KMOD_EXTENDED); LOS_MODULE_INIT(OsHiLogDriverInit, LOS_INIT_LEVEL_KMOD_EXTENDED);//日志模块初始化
...@@ -42,10 +42,10 @@ ...@@ -42,10 +42,10 @@
#define LOS_INIT_LEVEL_PLATFORM_EARLY 2 //平台早期 #define LOS_INIT_LEVEL_PLATFORM_EARLY 2 //平台早期
#define LOS_INIT_LEVEL_KMOD_PREVM 3 //内存模块即将开始 #define LOS_INIT_LEVEL_KMOD_PREVM 3 //内存模块即将开始
#define LOS_INIT_LEVEL_VM_COMPLETE 4 //内存模块完成 #define LOS_INIT_LEVEL_VM_COMPLETE 4 //内存模块完成
#define LOS_INIT_LEVEL_ARCH 5 // 架构级 #define LOS_INIT_LEVEL_ARCH 5 //架构级
#define LOS_INIT_LEVEL_PLATFORM 6 // 平台级 #define LOS_INIT_LEVEL_PLATFORM 6 //平台级
#define LOS_INIT_LEVEL_KMOD_BASIC 7 // 基础级 #define LOS_INIT_LEVEL_KMOD_BASIC 7 //基础级
#define LOS_INIT_LEVEL_KMOD_EXTENDED 8 // #define LOS_INIT_LEVEL_KMOD_EXTENDED 8 //扩展级
#define LOS_INIT_LEVEL_KMOD_TASK 9 //任务级 #define LOS_INIT_LEVEL_KMOD_TASK 9 //任务级
#define LOS_INIT_LEVEL_FINISH 10 #define LOS_INIT_LEVEL_FINISH 10
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
* @par Dependency: * @par Dependency:
* <ul><li>los_init.h: the header file that contains the API declaration.</li></ul> * <ul><li>los_init.h: the header file that contains the API declaration.</li></ul>
* @see * @see
*/ //将启动模块注册到启动过程 */ //将启动模块注册到启动过程,在内核启动过程中注册一个新模块作为内核功能组件的一部分。
#define LOS_MODULE_INIT(_hook, _level) OS_INIT_HOOK_REG(kernel, _hook, _level) #define LOS_MODULE_INIT(_hook, _level) OS_INIT_HOOK_REG(kernel, _hook, _level)
#endif /* _LOS_INIT_H */ #endif /* _LOS_INIT_H */
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#ifdef LOSCFG_KERNEL_CPUP #ifdef LOSCFG_KERNEL_CPUP
LITE_OS_SEC_BSS STATIC UINT16 cpupSwtmrID; LITE_OS_SEC_BSS STATIC UINT16 cpupSwtmrID; //监测CPU使用情况定时器s
LITE_OS_SEC_BSS STATIC UINT16 cpupInitFlg = 0; LITE_OS_SEC_BSS STATIC UINT16 cpupInitFlg = 0;
LITE_OS_SEC_BSS OsIrqCpupCB *g_irqCpup = NULL; LITE_OS_SEC_BSS OsIrqCpupCB *g_irqCpup = NULL;
LITE_OS_SEC_BSS STATIC UINT16 cpupMaxNum; LITE_OS_SEC_BSS STATIC UINT16 cpupMaxNum;
...@@ -59,7 +59,7 @@ LITE_OS_SEC_BSS STATIC UINT64 cpupIntTimeStart[LOSCFG_KERNEL_CORE_NUM]; ...@@ -59,7 +59,7 @@ LITE_OS_SEC_BSS STATIC UINT64 cpupIntTimeStart[LOSCFG_KERNEL_CORE_NUM];
#define CPUP_PRE_POS(pos) (((pos) == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : ((pos) - 1)) #define CPUP_PRE_POS(pos) (((pos) == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : ((pos) - 1))
#define CPUP_POST_POS(pos) (((pos) == (OS_CPUP_HISTORY_RECORD_NUM - 1)) ? 0 : ((pos) + 1)) #define CPUP_POST_POS(pos) (((pos) == (OS_CPUP_HISTORY_RECORD_NUM - 1)) ? 0 : ((pos) + 1))
//获取CPU周期
STATIC UINT64 OsGetCpuCycle(VOID) STATIC UINT64 OsGetCpuCycle(VOID)
{ {
UINT32 high; UINT32 high;
...@@ -134,7 +134,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsCpupGuard(VOID) ...@@ -134,7 +134,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsCpupGuard(VOID)
SCHEDULER_UNLOCK(intSave); SCHEDULER_UNLOCK(intSave);
} }
//创建cpu使用统计定时器
LITE_OS_SEC_TEXT_INIT UINT32 OsCpupGuardCreator(VOID) LITE_OS_SEC_TEXT_INIT UINT32 OsCpupGuardCreator(VOID)
{ {
(VOID)LOS_SwtmrCreate(LOSCFG_BASE_CORE_TICK_PER_SECOND, LOS_SWTMR_MODE_PERIOD, (VOID)LOS_SwtmrCreate(LOSCFG_BASE_CORE_TICK_PER_SECOND, LOS_SWTMR_MODE_PERIOD,
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __cplusplus */ #endif /* __cplusplus */
extern UINT32 OsVdsoInit(VOID); extern UINT32 OsVdsoInit(VOID);
extern vaddr_t OsVdsoLoad(const LosProcessCB *); extern vaddr_t OsVdsoLoad(const LosProcessCB *);
extern VOID OsVdsoTimevalUpdate(VOID); extern VOID OsVdsoTimevalUpdate(VOID);
......
...@@ -40,14 +40,14 @@ extern "C" { ...@@ -40,14 +40,14 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __cplusplus */ #endif /* __cplusplus */
typedef struct { typedef struct {//Vdso数据页结构体
/* Timeval */ /* Timeval */
INT64 realTimeSec; INT64 realTimeSec;
INT64 realTimeNsec; INT64 realTimeNsec;
INT64 monoTimeSec; INT64 monoTimeSec;
INT64 monoTimeNsec; INT64 monoTimeNsec;
/* lock DataPage 0:Unlock State 1:Lock State */ /* lock DataPage 0:Unlock State 1:Lock State */
UINT64 lockCount; UINT64 lockCount;//数据页被锁数量
} VdsoDataPage; } VdsoDataPage;
#define ELF_HEAD "\177ELF" #define ELF_HEAD "\177ELF"
......
...@@ -41,13 +41,13 @@ extern "C" { ...@@ -41,13 +41,13 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __cplusplus */ #endif /* __cplusplus */
#define LITE_VDSO_DATAPAGE __attribute__((section(".data.vdso.datapage"))) #define LITE_VDSO_DATAPAGE __attribute__((section(".data.vdso.datapage")))//vdso分页数据区
extern VOID OsVdsoTimeGet(VdsoDataPage *); extern VOID OsVdsoTimeGet(VdsoDataPage *);
extern CHAR __vdso_data_start; extern CHAR __vdso_data_start; //数据段起始地址,他们本质是在内核区的一个虚拟地址
extern CHAR __vdso_text_start; extern CHAR __vdso_text_start; //代码段起始地址
extern CHAR __vdso_text_end; extern CHAR __vdso_text_end; //代码段结束地址
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
......
...@@ -36,14 +36,23 @@ ...@@ -36,14 +36,23 @@
#include "los_vm_lock.h" #include "los_vm_lock.h"
#include "los_vm_phys.h" #include "los_vm_phys.h"
#include "los_process_pri.h" #include "los_process_pri.h"
/*
vdso 新型系统调用机制 ,虚拟动态共享库VDSO就是Virtual Dynamic Shared Object,
就是内核提供的虚拟的.so,这类.so文件不在磁盘上,而是包含在内核里面。内核把包含
某一.so的物理页在程序启动的时候映射入其进程的内存空间,对应的程序就可以当普通的.so来使用里头的函数
LITE_VDSO_DATAPAGE VdsoDataPage g_vdsoDataPage __attribute__((__used__)); 参考:http://lishiwen4.github.io/linux/vdso-and-syscall
https://vvl.me/2019/06/linux-syscall-and-vsyscall-vdso-in-x86/
STATIC size_t g_vdsoSize; #cat /proc/self/maps
*/
LITE_VDSO_DATAPAGE VdsoDataPage g_vdsoDataPage __attribute__((__used__));//使用这个数据区
STATIC size_t g_vdsoSize;
//vdso初始化
UINT32 OsVdsoInit(VOID) UINT32 OsVdsoInit(VOID)
{ {
g_vdsoSize = &__vdso_text_end - &__vdso_data_start; g_vdsoSize = &__vdso_text_end - &__vdso_data_start;//vDSO 会映射两块内存区域:代码段 [vdso],只读数据区 [vvar] 数据页
if (memcmp((CHAR *)(&__vdso_text_start), ELF_HEAD, ELF_HEAD_LEN)) { if (memcmp((CHAR *)(&__vdso_text_start), ELF_HEAD, ELF_HEAD_LEN)) {
PRINT_ERR("VDSO Init Failed!\n"); PRINT_ERR("VDSO Init Failed!\n");
...@@ -53,7 +62,8 @@ UINT32 OsVdsoInit(VOID) ...@@ -53,7 +62,8 @@ UINT32 OsVdsoInit(VOID)
} }
LOS_MODULE_INIT(OsVdsoInit, LOS_INIT_LEVEL_KMOD_EXTENDED); LOS_MODULE_INIT(OsVdsoInit, LOS_INIT_LEVEL_KMOD_EXTENDED);
//映射,这里先通过内核地址找到 vdso的物理地址,再将物理地址映射到进程的线性区.
//结论是每个进程都可以拥有自己的 vdso区,映射到同一个块物理地址.
STATIC INT32 OsVdsoMap(LosVmSpace *space, size_t len, PADDR_T paddr, VADDR_T vaddr, UINT32 flag) STATIC INT32 OsVdsoMap(LosVmSpace *space, size_t len, PADDR_T paddr, VADDR_T vaddr, UINT32 flag)
{ {
STATUS_T ret; STATUS_T ret;
...@@ -70,26 +80,26 @@ STATIC INT32 OsVdsoMap(LosVmSpace *space, size_t len, PADDR_T paddr, VADDR_T vad ...@@ -70,26 +80,26 @@ STATIC INT32 OsVdsoMap(LosVmSpace *space, size_t len, PADDR_T paddr, VADDR_T vad
} }
return LOS_OK; return LOS_OK;
} }
//为每个进程加载 vsdo
vaddr_t OsVdsoLoad(const LosProcessCB *processCB) vaddr_t OsVdsoLoad(const LosProcessCB *processCB)
{ {
INT32 ret = -1; INT32 ret = -1;
LosVmMapRegion *vdsoRegion = NULL; LosVmMapRegion *vdsoRegion = NULL;
UINT32 flag = VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_EXECUTE; UINT32 flag = VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_EXECUTE;
//用户区,可读可执行
if ((processCB == NULL) || (processCB->vmSpace == NULL)) { if ((processCB == NULL) || (processCB->vmSpace == NULL)) {
return 0; return 0;
} }
(VOID)LOS_MuxAcquire(&processCB->vmSpace->regionMux); (VOID)LOS_MuxAcquire(&processCB->vmSpace->regionMux);
//由虚拟空间提供加载内存
vdsoRegion = LOS_RegionAlloc(processCB->vmSpace, 0, g_vdsoSize, flag, 0); vdsoRegion = LOS_RegionAlloc(processCB->vmSpace, 0, g_vdsoSize, flag, 0);
if (vdsoRegion == NULL) { if (vdsoRegion == NULL) {
PRINT_ERR("%s %d, region alloc failed in vdso load\n", __FUNCTION__, __LINE__); PRINT_ERR("%s %d, region alloc failed in vdso load\n", __FUNCTION__, __LINE__);
goto LOCK_RELEASE; goto LOCK_RELEASE;
} }
vdsoRegion->regionFlags |= VM_MAP_REGION_FLAG_VDSO; vdsoRegion->regionFlags |= VM_MAP_REGION_FLAG_VDSO;//标识为 vdso区
//为vsdo做好映射,如此通过访问进程的虚拟地址就可以访问到真正的vsdo
ret = OsVdsoMap(processCB->vmSpace, g_vdsoSize, LOS_PaddrQuery((VOID *)(&__vdso_data_start)), ret = OsVdsoMap(processCB->vmSpace, g_vdsoSize, LOS_PaddrQuery((VOID *)(&__vdso_data_start)),
vdsoRegion->range.base, flag); vdsoRegion->range.base, flag);
if (ret != LOS_OK) { if (ret != LOS_OK) {
...@@ -107,22 +117,22 @@ LOCK_RELEASE: ...@@ -107,22 +117,22 @@ LOCK_RELEASE:
} }
return 0; return 0;
} }
//对数据页加锁
STATIC VOID LockVdsoDataPage(VdsoDataPage *vdsoDataPage) STATIC VOID LockVdsoDataPage(VdsoDataPage *vdsoDataPage)
{ {
vdsoDataPage->lockCount = 1; vdsoDataPage->lockCount = 1;
DMB; DMB;
} }
//对数据页加锁
STATIC VOID UnlockVdsoDataPage(VdsoDataPage *vdsoDataPage) STATIC VOID UnlockVdsoDataPage(VdsoDataPage *vdsoDataPage)
{ {
DMB; DMB;
vdsoDataPage->lockCount = 0; vdsoDataPage->lockCount = 0;
} }
//更新时间,
VOID OsVdsoTimevalUpdate(VOID) VOID OsVdsoTimevalUpdate(VOID)
{ {
VdsoDataPage *kVdsoDataPage = (VdsoDataPage *)(&__vdso_data_start); VdsoDataPage *kVdsoDataPage = (VdsoDataPage *)(&__vdso_data_start);//获取vdso 数据区
LockVdsoDataPage(kVdsoDataPage); LockVdsoDataPage(kVdsoDataPage);
OsVdsoTimeGet(kVdsoDataPage); OsVdsoTimeGet(kVdsoDataPage);
......
...@@ -27,8 +27,8 @@ ...@@ -27,8 +27,8 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
.globl __vdso_text_start .globl __vdso_text_start
.section .data.vdso.text .section .data.vdso.text
__vdso_text_start: __vdso_text_start: @vdso代码段入口
.incbin "../usr/OHOS-vdso.so" .incbin "../usr/OHOS-vdso.so" @ include bin的意思
\ No newline at end of file \ No newline at end of file
...@@ -45,7 +45,7 @@ extern "C" { ...@@ -45,7 +45,7 @@ extern "C" {
/* /*
* The dmesg buffer is start with this info structure, then the log. * The dmesg buffer is start with this info structure, then the log.
*/ */
typedef struct { typedef struct {//dmesg信息管理器,环形buf
UINT32 logSize; /* The size of log in buffer */ UINT32 logSize; /* The size of log in buffer */
UINT32 logHead; /* The index of the first log data. Data_out_flag */ UINT32 logHead; /* The index of the first log data. Data_out_flag */
UINT32 logTail; /* The index where to write, write in and plus one. Data_it_flag */ UINT32 logTail; /* The index where to write, write in and plus one. Data_it_flag */
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#ifdef LOSCFG_SHELL_LK #ifdef LOSCFG_SHELL_LK
typedef enum { typedef enum {//模块等级
MODULE0 = 0, MODULE0 = 0,
MODULE1 = 1, MODULE1 = 1,
MODULE2 = 2, MODULE2 = 2,
...@@ -52,9 +52,9 @@ typedef enum { ...@@ -52,9 +52,9 @@ typedef enum {
} MODULE_FLAG; } MODULE_FLAG;
typedef struct { typedef struct {
INT32 module_level; INT32 module_level;//模块等级
INT32 trace_level; INT32 trace_level;//跟踪等级
FILE *fp; FILE *fp; //文件描述结构体
} Logger; } Logger;
STATIC INT32 g_tracelevel; STATIC INT32 g_tracelevel;
...@@ -119,7 +119,32 @@ FILE *OsLogFpGet(VOID) ...@@ -119,7 +119,32 @@ FILE *OsLogFpGet(VOID)
{ {
return g_logger.fp; return g_logger.fp;
} }
/**************************************************************
log命令用于修改&查询日志配置,即选择打印哪种日志?
该命令依赖于LOSCFG_SHELL_LK,使用时通过menuconfig在配置项中开启"Enable Shell lk":
Debug ---> Enable a Debug Version ---> Enable Shell ---> Enable Shell lK。
log level命令用于配置日志的打印等级,包括6个等级
TRACE_EMG = 0,
TRACE_COMMON = 1,
TRACE_ERROR = 2,
TRACE_WARN = 3,
TRACE_INFO = 4,
TRACE_DEBUG = 5
若level不在有效范围内,会打印提示信息。
若log level命令不加[levelNum]参数,则默认查看当前打印等级,并且提示使用方法。
输入log level 4
***************************************************************/
INT32 CmdLog(INT32 argc, const CHAR **argv) INT32 CmdLog(INT32 argc, const CHAR **argv)
{ {
size_t level; size_t level;
...@@ -166,7 +191,7 @@ INT32 CmdLog(INT32 argc, const CHAR **argv) ...@@ -166,7 +191,7 @@ INT32 CmdLog(INT32 argc, const CHAR **argv)
} }
#ifdef LOSCFG_SHELL_DMESG #ifdef LOSCFG_SHELL_DMESG
STATIC INLINE VOID OsLogCycleRecord(INT32 level) STATIC INLINE VOID OsLogCycleRecord(INT32 level)//日志循环记录
{ {
UINT32 tmpLen; UINT32 tmpLen;
if (level != LOS_COMMON_LEVEL && (level > LOS_EMG_LEVEL && level <= LOS_TRACE_LEVEL)) { if (level != LOS_COMMON_LEVEL && (level > LOS_EMG_LEVEL && level <= LOS_TRACE_LEVEL)) {
...@@ -176,7 +201,7 @@ STATIC INLINE VOID OsLogCycleRecord(INT32 level) ...@@ -176,7 +201,7 @@ STATIC INLINE VOID OsLogCycleRecord(INT32 level)
} }
} }
#endif #endif
//默认打印函数,用于回调函数
VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap) VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, va_list ap)
{ {
if (level > OsLkTraceLvGet()) { if (level > OsLkTraceLvGet()) {
...@@ -193,7 +218,7 @@ VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...@@ -193,7 +218,7 @@ VOID OsLkDefaultFunc(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt,
} }
LkDprintf(fmt, ap); LkDprintf(fmt, ap);
} }
//打印
VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...) VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...)
{ {
va_list ap; va_list ap;
...@@ -203,12 +228,12 @@ VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ... ...@@ -203,12 +228,12 @@ VOID LOS_LkPrint(INT32 level, const CHAR *func, INT32 line, const CHAR *fmt, ...
va_end(ap); va_end(ap);
} }
} }
//设置回调函数
VOID LOS_LkRegHook(LK_FUNC hook) VOID LOS_LkRegHook(LK_FUNC hook)
{ {
g_osLkHook = hook; g_osLkHook = hook;
} }
//内核日志初始化
UINT32 OsLkLoggerInit(VOID) UINT32 OsLkLoggerInit(VOID)
{ {
(VOID)memset_s(&g_logger, sizeof(Logger), 0, sizeof(Logger)); (VOID)memset_s(&g_logger, sizeof(Logger), 0, sizeof(Logger));
...@@ -224,6 +249,6 @@ UINT32 OsLkLoggerInit(VOID) ...@@ -224,6 +249,6 @@ UINT32 OsLkLoggerInit(VOID)
SHELLCMD_ENTRY(log_shellcmd, CMD_TYPE_EX, "log", 1, (CmdCallBackFunc)CmdLog); SHELLCMD_ENTRY(log_shellcmd, CMD_TYPE_EX, "log", 1, (CmdCallBackFunc)CmdLog);
#endif #endif
LOS_MODULE_INIT(OsLkLoggerInit, LOS_INIT_LEVEL_EARLIEST); LOS_MODULE_INIT(OsLkLoggerInit, LOS_INIT_LEVEL_EARLIEST);//日志模块初始化
#endif #endif
...@@ -69,9 +69,9 @@ LITE_OS_SEC_BSS STATIC SPIN_LOCK_INIT(g_dmesgSpin); ...@@ -69,9 +69,9 @@ LITE_OS_SEC_BSS STATIC SPIN_LOCK_INIT(g_dmesgSpin);
STATIC DmesgInfo *g_dmesgInfo = NULL; STATIC DmesgInfo *g_dmesgInfo = NULL;
STATIC UINT32 g_logBufSize = 0; STATIC UINT32 g_logBufSize = 0;
STATIC VOID *g_mallocAddr = NULL; STATIC VOID *g_mallocAddr = NULL;
STATIC UINT32 g_dmesgLogLevel = 3; STATIC UINT32 g_dmesgLogLevel = 3;//日志等级
STATIC UINT32 g_consoleLock = 0; STATIC UINT32 g_consoleLock = 0;//用于关闭和打开控制台
STATIC UINT32 g_uartLock = 0; STATIC UINT32 g_uartLock = 0;//用于关闭和打开串口
STATIC const CHAR *g_levelString[] = { STATIC const CHAR *g_levelString[] = {
"EMG", "EMG",
"COMMON", "COMMON",
...@@ -80,22 +80,22 @@ STATIC const CHAR *g_levelString[] = { ...@@ -80,22 +80,22 @@ STATIC const CHAR *g_levelString[] = {
"INFO", "INFO",
"DEBUG" "DEBUG"
}; };
//关闭控制台
STATIC VOID OsLockConsole(VOID) STATIC VOID OsLockConsole(VOID)
{ {
g_consoleLock = 1; g_consoleLock = 1;
} }
//打开控制台
STATIC VOID OsUnlockConsole(VOID) STATIC VOID OsUnlockConsole(VOID)
{ {
g_consoleLock = 0; g_consoleLock = 0;
} }
//关闭串口
STATIC VOID OsLockUart(VOID) STATIC VOID OsLockUart(VOID)
{ {
g_uartLock = 1; g_uartLock = 1;
} }
//打开串口
STATIC VOID OsUnlockUart(VOID) STATIC VOID OsUnlockUart(VOID)
{ {
g_uartLock = 0; g_uartLock = 0;
...@@ -300,7 +300,7 @@ UINT32 OsCheckUartLock(VOID) ...@@ -300,7 +300,7 @@ UINT32 OsCheckUartLock(VOID)
{ {
return g_uartLock; return g_uartLock;
} }
//初始化 dmesg
UINT32 OsDmesgInit(VOID) UINT32 OsDmesgInit(VOID)
{ {
CHAR* buffer = NULL; CHAR* buffer = NULL;
...@@ -708,7 +708,26 @@ INT32 LOS_DmesgToFile(CHAR *filename) ...@@ -708,7 +708,26 @@ INT32 LOS_DmesgToFile(CHAR *filename)
} }
#endif #endif
}
/*************************************************************
dmesg全称是display message (or display driver),即显示信息。
dmesg命令用于控制内核dmesg缓存区
dmesg命令用于显示开机信息
该命令依赖于LOSCFG_SHELL_DMESG,使用时通过menuconfig在配置项中开启"Enable Shell dmesg":
Debug ---> Enable a Debug Version ---> Enable Shell ---> Enable Shell dmesg
dmesg参数缺省时,默认打印缓存区内容。
各“ - ”选项不能混合使用。
写入文件需确保已挂载文件系统。
关闭串口打印会影响shell使用,建议先连接telnet再尝试关闭串口。
dmesg > /usr/dmesg.log。
**************************************************************/
INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv) INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv)
{ {
if (argc == 1) { if (argc == 1) {
...@@ -720,24 +739,24 @@ INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv) ...@@ -720,24 +739,24 @@ INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv)
goto ERR_OUT; goto ERR_OUT;
} }
if (!strcmp(argv[1], "-c")) { if (!strcmp(argv[1], "-c")) {//打印缓存区内容并清空缓存区
PRINTK("\n"); PRINTK("\n");
OsLogShow(); OsLogShow();//打印缓存区内容
LOS_DmesgClear(); LOS_DmesgClear();
return LOS_OK; return LOS_OK;
} else if (!strcmp(argv[1], "-C")) { } else if (!strcmp(argv[1], "-C")) {//清空缓存区。
LOS_DmesgClear(); LOS_DmesgClear();
return LOS_OK; return LOS_OK;
} else if (!strcmp(argv[1], "-D")) { } else if (!strcmp(argv[1], "-D")) {//关闭控制台打印。
OsLockConsole(); OsLockConsole();
return LOS_OK; return LOS_OK;
} else if (!strcmp(argv[1], "-E")) { } else if (!strcmp(argv[1], "-E")) {///开启控制台打印。
OsUnlockConsole(); OsUnlockConsole();
return LOS_OK; return LOS_OK;
} else if (!strcmp(argv[1], "-L")) { } else if (!strcmp(argv[1], "-L")) {//关闭串口打印
OsLockUart(); OsLockUart();
return LOS_OK; return LOS_OK;
} else if (!strcmp(argv[1], "-U")) { } else if (!strcmp(argv[1], "-U")) {//开启串口打印
OsUnlockUart(); OsUnlockUart();
return LOS_OK; return LOS_OK;
} }
...@@ -746,7 +765,7 @@ INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv) ...@@ -746,7 +765,7 @@ INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv)
goto ERR_OUT; goto ERR_OUT;
} }
if (!strcmp(argv[1], ">")) { if (!strcmp(argv[1], ">")) {//将缓存区内容写入文件
if (LOS_DmesgToFile((CHAR *)argv[2]) < 0) { /* 2:index of parameters */ if (LOS_DmesgToFile((CHAR *)argv[2]) < 0) { /* 2:index of parameters */
PRINTK("Dmesg write log to %s fail \n", argv[2]); /* 2:index of parameters */ PRINTK("Dmesg write log to %s fail \n", argv[2]); /* 2:index of parameters */
return -1; return -1;
...@@ -754,9 +773,9 @@ INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv) ...@@ -754,9 +773,9 @@ INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv)
PRINTK("Dmesg write log to %s success \n", argv[2]); /* 2:index of parameters */ PRINTK("Dmesg write log to %s success \n", argv[2]); /* 2:index of parameters */
return LOS_OK; return LOS_OK;
} }
} else if (!strcmp(argv[1], "-l")) { } else if (!strcmp(argv[1], "-l")) {//设置缓存等级
return OsDmesgLvSet(argv[2]); /* 2:index of parameters */ return OsDmesgLvSet(argv[2]); /* 2:index of parameters */
} else if (!strcmp(argv[1], "-s")) { } else if (!strcmp(argv[1], "-s")) {//设置缓存区大小 size是要设置的大小
return OsDmesgMemSizeSet(argv[2]); /* 2:index of parameters */ return OsDmesgMemSizeSet(argv[2]); /* 2:index of parameters */
} }
} }
...@@ -764,9 +783,8 @@ INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv) ...@@ -764,9 +783,8 @@ INT32 OsShellCmdDmesg(INT32 argc, const CHAR **argv)
ERR_OUT: ERR_OUT:
PRINTK("dmesg: invalid option or parameter.\n"); PRINTK("dmesg: invalid option or parameter.\n");
return -1; return -1;
}
SHELLCMD_ENTRY(dmesg_shellcmd, CMD_TYPE_STD, "dmesg", XARGS, (CmdCallBackFunc)OsShellCmdDmesg); SHELLCMD_ENTRY(dmesg_shellcmd, CMD_TYPE_STD, "dmesg", XARGS, (CmdCallBackFunc)OsShellCmdDmesg);
LOS_MODULE_INIT(OsDmesgInit, LOS_INIT_LEVEL_EARLIEST); LOS_MODULE_INIT(OsDmesgInit, LOS_INIT_LEVEL_EARLIEST);//在非常早期调用
#endif #endif
...@@ -82,7 +82,7 @@ typedef UINT32 (*SyscallFun7)(UINT32, UINT32, UINT32, UINT32, UINT32, UINT32, UI ...@@ -82,7 +82,7 @@ typedef UINT32 (*SyscallFun7)(UINT32, UINT32, UINT32, UINT32, UINT32, UINT32, UI
static UINTPTR g_syscallHandle[SYS_CALL_NUM] = {0}; //系统调用入口函数注册 static UINTPTR g_syscallHandle[SYS_CALL_NUM] = {0}; //系统调用入口函数注册
static UINT8 g_syscallNArgs[(SYS_CALL_NUM + 1) / NARG_PER_BYTE] = {0};//保存系统调用对应的参数数量 static UINT8 g_syscallNArgs[(SYS_CALL_NUM + 1) / NARG_PER_BYTE] = {0};//保存系统调用对应的参数数量
//系统调用初始化,完成对系统调用的注册 //系统调用初始化,完成对系统调用的注册,将系统调用添加到全局变量中 g_syscallHandle,g_syscallNArgs
void OsSyscallHandleInit(void) void OsSyscallHandleInit(void)
{ {
#define SYSCALL_HAND_DEF(id, fun, rType, nArg) \ #define SYSCALL_HAND_DEF(id, fun, rType, nArg) \
...@@ -95,7 +95,7 @@ void OsSyscallHandleInit(void) ...@@ -95,7 +95,7 @@ void OsSyscallHandleInit(void)
#undef SYSCALL_HAND_DEF #undef SYSCALL_HAND_DEF
} }
LOS_MODULE_INIT(OsSyscallHandleInit, LOS_INIT_LEVEL_KMOD_EXTENDED); LOS_MODULE_INIT(OsSyscallHandleInit, LOS_INIT_LEVEL_KMOD_EXTENDED);//注册系统调用模块
/* The SYSCALL ID is in R7 on entry. Parameters follow in R0..R6 */ /* The SYSCALL ID is in R7 on entry. Parameters follow in R0..R6 */
/****************************************************************** /******************************************************************
由汇编调用,见于 los_hw_exc.s / BLX OsArmA32SyscallHandle 由汇编调用,见于 los_hw_exc.s / BLX OsArmA32SyscallHandle
...@@ -125,7 +125,7 @@ VOID OsArmA32SyscallHandle(TaskContext *regs) ...@@ -125,7 +125,7 @@ VOID OsArmA32SyscallHandle(TaskContext *regs)
return; return;
} }
//regs[0-6] 记录系统调用的参数,这也是由R7寄存器保存系统调用号的原因 //regs[0-6] 记录系统调用的参数,这也是由R7寄存器保存系统调用号的原因
OsSigIntLock(); OsSigIntLock();//禁止响应信号
switch (nArgs) {//参数的个数 switch (nArgs) {//参数的个数
case ARG_NUM_0: case ARG_NUM_0:
case ARG_NUM_1: case ARG_NUM_1:
...@@ -143,8 +143,8 @@ VOID OsArmA32SyscallHandle(TaskContext *regs) ...@@ -143,8 +143,8 @@ VOID OsArmA32SyscallHandle(TaskContext *regs)
ret = (*(SyscallFun7)handle)(regs->R0, regs->R1, regs->R2, regs->R3, regs->R4, regs->R5, regs->R6); ret = (*(SyscallFun7)handle)(regs->R0, regs->R1, regs->R2, regs->R3, regs->R4, regs->R5, regs->R6);
} }
regs->R0 = ret; regs->R0 = ret;//系统返回值,保存在R0寄存器
OsSigIntUnlock(); OsSigIntUnlock();//打开响应信号
return; return;
} }
git add -A git add -A
git commit -m '上传linux经典书籍 git commit -m '对 vdso 实现注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码 百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
国内:https://weharmony.21cloudbox.com 国内:https://weharmony.21cloudbox.com
国外:https://weharmony.github.io 国外:https://weharmony.github.io
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册