提交 5088fcb3 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析

任务和CP15协处理器寄存器代码注释,讲透 shell kill命令

鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki
项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.
上级 ef89a922
......@@ -82,54 +82,54 @@ extern "C" {
#define CP14_REG(CRn, Op1, CRm, Op2) "p14, "#Op1", %0, "#CRn","#CRm","#Op2
#define CP15_REG(CRn, Op1, CRm, Op2) "p15, "#Op1", %0, "#CRn","#CRm","#Op2
#define CP15_REG64(CRn, Op1) "p15, "#Op1", %0, %H0,"#CRn
//CP15 协处理器各寄存器信息
/*
* Identification registers (c0)
* Identification registers (c0) //c0 - 身份寄存器
*/
#define MIDR CP15_REG(c0, 0, c0, 0) /* Main ID Register */
#define MIDR CP15_REG(c0, 0, c0, 0) /* Main ID Register */ //主ID寄存器
#define MPIDR CP15_REG(c0, 0, c0, 5) /* Multiprocessor Affinity Register *///多处理器关联寄存器给每个CPU制定一个逻辑地址
#define CCSIDR CP15_REG(c0, 1, c0, 0) /* Cache Size ID Registers */
#define CLIDR CP15_REG(c0, 1, c0, 1) /* Cache Level ID Register */
#define VPIDR CP15_REG(c0, 4, c0, 0) /* Virtualization Processor ID Register */
#define VMPIDR CP15_REG(c0, 4, c0, 5) /* Virtualization Multiprocessor ID Register */
#define CCSIDR CP15_REG(c0, 1, c0, 0) /* Cache Size ID Registers */ //缓存大小ID寄存器
#define CLIDR CP15_REG(c0, 1, c0, 1) /* Cache Level ID Register */ //缓存登记ID寄存器
#define VPIDR CP15_REG(c0, 4, c0, 0) /* Virtualization Processor ID Register */ //虚拟化处理器ID寄存器
#define VMPIDR CP15_REG(c0, 4, c0, 5) /* Virtualization Multiprocessor ID Register */ //虚拟化多处理器ID寄存器
/*
* System control registers (c1)
* System control registers (c1) //c1 - 系统控制寄存器 各种控制位(可读写)
*/
#define SCTLR CP15_REG(c1, 0, c0, 0) /* System Control Register */
#define ACTLR CP15_REG(c1, 0, c0, 1) /* Auxiliary Control Register */
#define CPACR CP15_REG(c1, 0, c0, 2) /* Coprocessor Access Control Register */
#define SCTLR CP15_REG(c1, 0, c0, 0) /* System Control Register */ //系统控制寄存器
#define ACTLR CP15_REG(c1, 0, c0, 1) /* Auxiliary Control Register */ //辅助控制寄存器
#define CPACR CP15_REG(c1, 0, c0, 2) /* Coprocessor Access Control Register */ //协处理器访问控制寄存器
/*
* Memory protection and control registers (c2 & c3)
* Memory protection and control registers (c2 & c3) //c2 - 传说中的TTB寄存器,主要是给MMU使用 c3 - 域访问控制位
*/
#define TTBR0 CP15_REG(c2, 0, c0, 0) /* Translation Table Base Register 0 */
#define TTBR1 CP15_REG(c2, 0, c0, 1) /* Translation Table Base Register 1 */
#define TTBCR CP15_REG(c2, 0, c0, 2) /* Translation Table Base Control Register */
#define DACR CP15_REG(c3, 0, c0, 0) /* Domain Access Control Register */
#define TTBR0 CP15_REG(c2, 0, c0, 0) /* Translation Table Base Register 0 */ //转换表基地址寄存器0
#define TTBR1 CP15_REG(c2, 0, c0, 1) /* Translation Table Base Register 1 */ //转换表基地址寄存器1
#define TTBCR CP15_REG(c2, 0, c0, 2) /* Translation Table Base Control Register */ ////转换表基地址控制寄存器
#define DACR CP15_REG(c3, 0, c0, 0) /* Domain Access Control Register */ //域访问控制寄存器
/*
* Memory system fault registers (c5 & c6)
* Memory system fault registers (c5 & c6) //c5 - 内存失效状态 c6 - 内存失效地址
*/
#define DFSR CP15_REG(c5, 0, c0, 0) /* Data Fault Status Register */
#define IFSR CP15_REG(c5, 0, c0, 1) /* Instruction Fault Status Register */
#define DFAR CP15_REG(c6, 0, c0, 0) /* Data Fault Address Register */
#define IFAR CP15_REG(c6, 0, c0, 2) /* Instruction Fault Address Register */
#define DFSR CP15_REG(c5, 0, c0, 0) /* Data Fault Status Register */ //数据故障状态寄存器
#define IFSR CP15_REG(c5, 0, c0, 1) /* Instruction Fault Status Register */ //指令故障状态寄存器
#define DFAR CP15_REG(c6, 0, c0, 0) /* Data Fault Address Register */ //数据故障地址寄存器
#define IFAR CP15_REG(c6, 0, c0, 2) /* Instruction Fault Address Register */ //指令错误地址寄存器
/*
* Process, context and thread ID registers (c13)
* Process, context and thread ID registers (c13) //c13 - 进程标识符
*/
#define FCSEIDR CP15_REG(c13, 0, c0, 0) /* FCSE Process ID Register */
#define CONTEXTIDR CP15_REG(c13, 0, c0, 1) /* Context ID Register */
#define TPIDRURW CP15_REG(c13, 0, c0, 2) /* User Read/Write Thread ID Register */
#define TPIDRURO CP15_REG(c13, 0, c0, 3) /* User Read-Only Thread ID Register */
#define TPIDRPRW CP15_REG(c13, 0, c0, 4) /* PL1 only Thread ID Register */
#define FCSEIDR CP15_REG(c13, 0, c0, 0) /* FCSE Process ID Register */ //FCSE(Fast Context Switch Extension,快速上下文切换)进程ID寄存器 位于CPU和MMU之间
#define CONTEXTIDR CP15_REG(c13, 0, c0, 1) /* Context ID Register */ //上下文ID寄存器
#define TPIDRURW CP15_REG(c13, 0, c0, 2) /* User Read/Write Thread ID Register */ //用户读/写线程ID寄存器
#define TPIDRURO CP15_REG(c13, 0, c0, 3) /* User Read-Only Thread ID Register */ //用户只读写线程ID寄存器
#define TPIDRPRW CP15_REG(c13, 0, c0, 4) /* PL1 only Thread ID Register */ //仅PL1线程ID寄存器
#define MPIDR_CPUID_MASK (0xffU)
//获取当前task
STATIC INLINE VOID *ArchCurrTaskGet(VOID)
{
return (VOID *)(UINTPTR)ARM_SYSREG_READ(TPIDRPRW);
return (VOID *)(UINTPTR)ARM_SYSREG_READ(TPIDRPRW);//读c13寄存器
}
STATIC INLINE VOID ArchCurrTaskSet(VOID *val)
......
......@@ -1127,9 +1127,9 @@ LITE_OS_SEC_TEXT VOID OsWaitSignalToWakeProcess(LosProcessCB *processCB)
return;
}
if (!LOS_ListEmpty(&processCB->waitList)) {//进程保存waitLits以支持wait/waitpid
taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&processCB->waitList));
OsWaitWakeTask(taskCB, OS_INVALID_VALUE);
if (!LOS_ListEmpty(&processCB->waitList)) {//waitList链表不为空
taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&processCB->waitList));//从链表上摘下第一个task,通过节点获取task主体
OsWaitWakeTask(taskCB, OS_INVALID_VALUE);//唤醒这个task
}
return;
......
......@@ -1351,7 +1351,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio)
* taskStatus --- task status
* timeOut --- Expiry time
* Return : LOS_OK on success or LOS_NOK on failure
*///任务等待
*///任务等待,将当前任务挂到参数 list上
UINT32 OsTaskWait(LOS_DL_LIST *list, UINT32 timeout, BOOL needSched)
{
LosTaskCB *runTask = NULL;
......
......@@ -102,7 +102,7 @@ typedef struct ProcessCB {
priority hash table */ //进程的线程组调度优先级哈希表
volatile UINT32 threadNumber; /**< Number of threads alive under this process */ //此进程下的活动线程数
UINT32 threadCount; /**< Total number of threads created under this process */ //在此进程下创建的线程总数
LOS_DL_LIST waitList; /**< The process holds the waitLits to support wait/waitpid */
LOS_DL_LIST waitList; /**< The process holds the waitLits to support wait/waitpid *///进程持有等待链表以支持wait/waitpid
#if (LOSCFG_KERNEL_SMP == YES)
UINT32 timerCpu; /**< CPU core number of this task is delayed or pended */
#endif
......
......@@ -53,8 +53,8 @@ extern "C" {
#define OS_SYSCALL_GET_CPSR(regs) (*((unsigned long *)((UINTPTR)(regs) - 4)))
#define SIG_STOP_VISIT 1
#define OS_KERNEL_KILL_PERMISSION 0U
#define OS_USER_KILL_PERMISSION 3U
#define OS_KERNEL_KILL_PERMISSION 0U //内核级 kill 权限
#define OS_USER_KILL_PERMISSION 3U //用户级 kill 权限
#define OS_RETURN_IF(expr, errcode) \
if ((expr)) { \
......@@ -94,8 +94,8 @@ typedef void (*sa_sighandler_t)(int);
typedef void (*sa_siginfoaction_t)(int, siginfo_t *, void *);
#define SIGNO2SET(s) ((sigset_t)1ULL << (s))
#define NULL_SIGNAL_SET ((sigset_t)0ULL)
#define FULL_SIGNAL_SET ((sigset_t)~0ULL)
#define NULL_SIGNAL_SET ((sigset_t)0ULL) //设置成没有信号
#define FULL_SIGNAL_SET ((sigset_t)~0ULL) //设置成满格信号
static inline int GOOD_SIGNO(unsigned int sig)
{
......@@ -156,14 +156,14 @@ typedef struct {
unsigned int count;
} sig_switch_context;
typedef struct {
typedef struct {//信号控制块(描述符)
sigset_t sigFlag;
sigset_t sigPendFlag;
sigset_t sigprocmask; /* Signals that are blocked */
sigset_t sigprocmask; /* Signals that are blocked */ //信号屏蔽
sq_queue_t sigactionq;
LOS_DL_LIST waitList;
sigset_t sigwaitmask; /* Waiting for pending signals */
siginfo_t sigunbinfo; /* Signal info when task unblocked */
LOS_DL_LIST waitList; //等待链表
sigset_t sigwaitmask; /* Waiting for pending signals */ //等待挂起的信号
siginfo_t sigunbinfo; /* Signal info when task unblocked */ //任务解除阻止时的信号信息
sig_switch_context context;
} sig_cb;
......
......@@ -301,7 +301,7 @@ typedef struct {
UINT16 timeSlice; /**< Remaining time slice *///剩余时间片
UINT32 stackSize; /**< Task stack size */ //非用户模式下栈大小
UINTPTR topOfStack; /**< Task stack top */ //非用户模式下的栈顶
UINT32 taskID; /**< Task ID */
UINT32 taskID; /**< Task ID */ //任务ID,任务池本质是一个大数组,ID就是数组的索引,默认 < 128
TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */ //任务执行入口函数
VOID *joinRetval; /**< pthread adaption */
VOID *taskSem; /**< Task-held semaphore */ //task在等哪个信号量
......@@ -310,38 +310,38 @@ typedef struct {
UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 */ //入口函数的参数 例如 main (int argc,char *argv[])
CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */
LOS_DL_LIST pendList; /**< Task pend node */ //如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时
LOS_DL_LIST threadList; /**< thread list */
SortLinkList sortList; /**< Task sortlink node */
UINT32 eventMask; /**< Event mask */
UINT32 eventMode; /**< Event mode */
UINT32 priBitMap; /**< BitMap for recording the change of task priority,
the priority can not be greater than 31 */
LOS_DL_LIST threadList; /**< thread list */ //挂到所属进程的线程链表上
SortLinkList sortList; /**< Task sortlink node */ //挂到cpu core 的任务执行链表上
UINT32 eventMask; /**< Event mask */ //事件屏蔽
UINT32 eventMode; /**< Event mode */ //事件模式
UINT32 priBitMap; /**< BitMap for recording the change of task priority, //任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化
the priority can not be greater than 31 */ //过的优先级,例如 ..01001011 曾经有过 0,1,3,6 优先级
INT32 errorNo; /**< Error Num */
UINT32 signal; /**< Task signal */
sig_cb sig; //信号控制块
UINT32 signal; /**< Task signal */ //任务信号 注意这个信号和 下面的sig是完全不一样的两个东东。
sig_cb sig; //信号控制块,和上面的signal是两个东西,独立使用。鸿蒙这样放在一块会误导开发者!
#if (LOSCFG_KERNEL_SMP == YES)
UINT16 currCpu; /**< CPU core number of this task is running on */
UINT16 lastCpu; /**< CPU core number of this task is running on last time */
UINT16 cpuAffiMask; /**< CPU affinity mask, support up to 16 cores */
UINT32 timerCpu; /**< CPU core number of this task is delayed or pended */
UINT16 currCpu; /**< CPU core number of this task is running on */ //正在运行此任务的CPU内核号
UINT16 lastCpu; /**< CPU core number of this task is running on last time */ //上次运行此任务的CPU内核号
UINT16 cpuAffiMask; /**< CPU affinity mask, support up to 16 cores */ //CPU亲和力掩码,最多支持16核,亲和力很重要,多核情况下尽量一个任务在一个CPU核上运行,提高效率
UINT32 timerCpu; /**< CPU core number of this task is delayed or pended */ //此任务的CPU内核号被延迟或挂起
#if (LOSCFG_KERNEL_SMP_TASK_SYNC == YES)
UINT32 syncSignal; /**< Synchronization for signal handling */
UINT32 syncSignal; /**< Synchronization for signal handling */ //信号同步处理
#endif
#if (LOSCFG_KERNEL_SMP_LOCKDEP == YES)
LockDep lockDep;
#endif
#if (LOSCFG_KERNEL_SCHED_STATISTICS == YES)
SchedStat schedStat; /**< Schedule statistics */
SchedStat schedStat; /**< Schedule statistics */ //调度统计
#endif
#endif
UINTPTR userArea; //使用区域,由运行时划定,根据运行态不同而不同
UINTPTR userMapBase; //用户模式下的栈底位置
UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */
UINT32 processID; /**< Which belong process */
FutexNode futex;
LOS_DL_LIST joinList; /**< join list */
LOS_DL_LIST lockList; /**< Hold the lock list */
UINT32 waitID; /**< Wait for the PID or GID of the child process */
FutexNode futex; //实现快锁功能
LOS_DL_LIST joinList; /**< join list */ //联结链表,允许任务之间相互释放彼此
LOS_DL_LIST lockList; /**< Hold the lock list */ //拿到了哪些锁链表
UINT32 waitID; /**< Wait for the PID or GID of the child process */ //等待孩子的PID或GID进程
UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent,
a specific child process, or any child process */
#if (LOSCFG_KERNEL_LITEIPC == YES)
......@@ -350,19 +350,19 @@ typedef struct {
BOOL accessMap[LOSCFG_BASE_CORE_TSK_LIMIT];//访问图,指的是task之间是否能访问的标识,LOSCFG_BASE_CORE_TSK_LIMIT 为任务池总数
#endif
} LosTaskCB;
typedef struct {
//LosTask结构体是给外部用的
typedef struct {// 可见于..\vendor_hisi_hi3861_hi3861\hi3861\platform\os\Huawei_LiteOS\kernel\base\include\los_task_pri.h
LosTaskCB *runTask;
LosTaskCB *newTask;
} LosTask;
//typedef struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t;
//见于 ..\vendor_hisi_hi3861_hi3861\hi3861\platform\os\Huawei_LiteOS\components\lib\libc\musl\include\bits\alltypes.h
struct ProcessSignalInfo {//进程信号信息
siginfo_t *sigInfo; /**< Signal to be dispatched */ //发送信号
siginfo_t *sigInfo; /**< Signal to be dispatched */ //要发送的信号 例如 9 代表 kill process信号
LosTaskCB *defaultTcb; /**< Default TCB */ //默认task,指的是信号的发送方
LosTaskCB *unblockedTcb; /**< The signal unblock on this TCB*/ //这个task发解除阻塞信号
LosTaskCB *awakenedTcb; /**< This TCB was awakened */ //被唤醒task
LosTaskCB *receivedTcb; /**< This TCB received the signal */ //信号接收方task
LosTaskCB *unblockedTcb; /**< The signal unblock on this TCB*/ //解除阻塞这个task的信号
LosTaskCB *awakenedTcb; /**< This TCB was awakened */ //指定task要被唤醒的信号
LosTaskCB *receivedTcb; /**< This TCB received the signal */ //指定task接收信号
};
typedef int (*ForEachTaskCB)(LosTaskCB *tcb, void *arg);//函数指针
......@@ -372,7 +372,7 @@ typedef int (*ForEachTaskCB)(LosTaskCB *tcb, void *arg);//函数指针
* Maximum number of tasks.
*
*/
extern UINT32 g_taskMaxNum;
extern UINT32 g_taskMaxNum;//任务最大数量 默认128个
/**
......@@ -380,98 +380,98 @@ extern UINT32 g_taskMaxNum;
* Starting address of a task.
*
*/
extern LosTaskCB *g_taskCBArray;
extern LosTaskCB *g_taskCBArray;//外部变量 任务池 默认128个
/**
* @ingroup los_task
* Time slice structure.
*/
typedef struct {
LosTaskCB *task; /**< Current running task */
UINT16 time; /**< Expiration time point */
UINT16 timeout; /**< Expiration duration */
typedef struct {//时间片结构体,任务轮询
LosTaskCB *task; /**< Current running task */ //当前运行着的任务
UINT16 time; /**< Expiration time point */ //过期时间点
UINT16 timeout; /**< Expiration duration */ //有效期
} OsTaskRobin;
//获取当前CPU core运行的任务
STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID)
{
return (LosTaskCB *)ArchCurrTaskGet();
}
//设置当前CPUcore运行任务
STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task)
{
ArchCurrTaskSet(task);
}
//用户模式下设置当前Cpucore运行任务,参数为线程
STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread)
{
ArchCurrUserTaskSet(thread);
}
//通过任务ID获取任务实体,task由任务池分配,本质是个数组,彼此都挨在一块
STATIC INLINE LosTaskCB *OsGetTaskCB(UINT32 taskID)
{
return OS_TCB_FROM_TID(taskID);
}
//任务是否在使用
STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB)
{
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//在freelist中的任务都是 OS_TASK_STATUS_UNUSED 状态
return TRUE;
}
return FALSE;
}
//任务是否在运行
STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB)
{
if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {//一个CPU core 只能有一个 OS_TASK_STATUS_RUNNING task
return TRUE;
}
return FALSE;
}
//任务是否不再活动
STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB)
{
if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) {
if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) {//三个标签有一个代表不在活动
return TRUE;
}
return FALSE;
}
#define OS_TID_CHECK_INVALID(taskID) ((UINT32)(taskID) >= g_taskMaxNum)
#define OS_TID_CHECK_INVALID(taskID) ((UINT32)(taskID) >= g_taskMaxNum)//是否有无效的任务 > 128
/* get task info */
#define OS_ALL_TASK_MASK 0xFFFFFFFF
//进程就绪队列大小
#define OS_PROCESS_PRI_QUEUE_SIZE(processCB) OsPriQueueProcessSize(g_priQueueList, (processCB)->priority)
//默认是从尾入进程的任务就绪队列
#define OS_TASK_PRI_QUEUE_ENQUEUE(processCB, taskCB) \
OsPriQueueEnqueue((processCB)->threadPriQueueList, &((processCB)->threadScheduleMap), \
&((taskCB)->pendList), (taskCB)->priority)
//从头部入进程的任务就绪队列
#define OS_TASK_PRI_QUEUE_ENQUEUE_HEAD(processCB, taskCB) \
OsPriQueueEnqueueHead((processCB)->threadPriQueueList, &((processCB)->threadScheduleMap), \
&((taskCB)->pendList), (taskCB)->priority)
//从进程的任务就绪队列的头部摘除
#define OS_TASK_PRI_QUEUE_DEQUEUE(processCB, taskCB) \
OsPriQueueDequeue((processCB)->threadPriQueueList, &((processCB)->threadScheduleMap), &((taskCB)->pendList))
//入和出 任务调度就绪队列
#define OS_TASK_SCHED_QUEUE_ENQUEUE(taskCB, status) OsTaskSchedQueueEnqueue(taskCB, status)
#define OS_TASK_SCHED_QUEUE_DEQUEUE(taskCB, status) OsTaskSchedQueueDequeue(taskCB, status)
#define OS_PROCESS_PRI_QUEUE_ENQUEUE(processCB) \
//入和出 进程的就绪队列 ,还提供了从头部入队列的方法
#define OS_PROCESS_PRI_QUEUE_ENQUEUE(processCB) \
OsPriQueueEnqueue(g_priQueueList, &g_priQueueBitmap, &((processCB)->pendList), (processCB)->priority)
#define OS_PROCESS_PRI_QUEUE_ENQUEUE_HEAD(processCB) \
OsPriQueueEnqueueHead(g_priQueueList, &g_priQueueBitmap, &((processCB)->pendList), (processCB)->priority)
#define OS_PROCESS_PRI_QUEUE_DEQUEUE(processCB) OsPriQueueProcessDequeue(&((processCB)->pendList))
//任务就绪队列的大小 和 获取进程中一个优先级最高的任务
#define OS_TASK_PRI_QUEUE_SIZE(processCB, taskCB) OsPriQueueSize((processCB)->threadPriQueueList, (taskCB)->priority)
#define OS_TASK_GET_NEW(processCB) LOS_DL_LIST_ENTRY(OsPriQueueTop((processCB)->threadPriQueueList, \
&((processCB)->threadScheduleMap)), \
LosTaskCB, pendList)
//获取一个优先级最高的进程
#define OS_PROCESS_GET_NEW() \
LOS_DL_LIST_ENTRY(OsPriQueueTop(g_priQueueList, &g_priQueueBitmap), LosProcessCB, pendList)
......
......@@ -54,7 +54,7 @@ int raise(int sig)
#define GETUNMASKSET(procmask, pendFlag) ((~(procmask)) & (sigset_t)(pendFlag))
#define UINT64_BIT_SIZE 64
//信号是否为数字
int OsSigIsMember(const sigset_t *set, int signo)
{
int ret = LOS_NOK;
......@@ -170,7 +170,7 @@ int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldset)
}
return ret;
}
//给进程的每一个task发送信号
//让进程的每一个task执行参数函数
int OsSigProcessForeachChild(LosProcessCB *spcb, ForEachTaskCB handler, void *arg)
{
int ret;
......@@ -178,7 +178,7 @@ int OsSigProcessForeachChild(LosProcessCB *spcb, ForEachTaskCB handler, void *ar
/* Visit the main thread last (if present) */ //最后访问主线程(如果有)
LosTaskCB *taskCB = NULL;//遍历进程的 threadList 链表,里面存放的都是task节点
LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &(spcb->threadSiblingList), LosTaskCB, threadList) {
ret = handler(taskCB, arg);//这里是个回调函数,给每个任务发信号,异步发信号
ret = handler(taskCB, arg);//这里是个参数函数,执行这个参数函数
OS_RETURN_IF(ret != 0, ret);//这个宏的意思就是只有ret = 0时,啥也不处理.其余就返回 ret
}
return LOS_OK;
......@@ -228,21 +228,21 @@ static int SigProcessSignalHandler(LosTaskCB *tcb, void *arg)
}
return 0; /* Keep searching */
}
//唤醒task 信号
//干掉 task 的信号
static int SigProcessKillSigHandler(LosTaskCB *tcb, void *arg)
{
struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg;
if ((tcb != NULL) && (info != NULL) && (info->sigInfo != NULL)) {
if ((tcb != NULL) && (info != NULL) && (info->sigInfo != NULL)) {//进程有信号
sig_cb *sigcb = &tcb->sig;
if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, info->sigInfo->si_signo)) {
OsTaskWake(tcb);
OsSigEmptySet(&sigcb->sigwaitmask);
if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, info->sigInfo->si_signo)) {//waitlist 不为空 且 有信号
OsTaskWake(tcb);//唤醒这个任务,加入进程的就绪队列
OsSigEmptySet(&sigcb->sigwaitmask);//清空信号
}
}
return 0;
}
//进程加载task控制块信号
static void SigProcessLoadTcb(struct ProcessSignalInfo *info, siginfo_t *sigInfo)
{
LosTaskCB *tcb = NULL;
......@@ -259,7 +259,7 @@ static void SigProcessLoadTcb(struct ProcessSignalInfo *info, siginfo_t *sigInfo
(void)OsTcbDispatch(tcb, sigInfo);
}
}
//给参数进程发送参数信号
int OsSigProcessSend(LosProcessCB *spcb, siginfo_t *sigInfo)
{
int ret;
......@@ -271,14 +271,14 @@ int OsSigProcessSend(LosProcessCB *spcb, siginfo_t *sigInfo)
.receivedTcb = NULL
};
/* visit all taskcb and dispatch signal */
if ((info.sigInfo != NULL) && (info.sigInfo->si_signo == SIGKILL)) {
(void)OsSigProcessForeachChild(spcb, SigProcessKillSigHandler, &info);
/* visit all taskcb and dispatch signal */ //访问所有任务和分发信号
if ((info.sigInfo != NULL) && (info.sigInfo->si_signo == SIGKILL)) {//需要干掉进程时 SIGKILL = 9, #linux kill 9 14
(void)OsSigProcessForeachChild(spcb, SigProcessKillSigHandler, &info);//给进程的所有task发送信号
OsSigAddSet(&spcb->sigShare, info.sigInfo->si_signo);
OsWaitSignalToWakeProcess(spcb);
OsWaitSignalToWakeProcess(spcb);//等待信号唤醒进程
return 0;
} else {
ret = OsSigProcessForeachChild(spcb, SigProcessSignalHandler, &info);
ret = OsSigProcessForeachChild(spcb, SigProcessSignalHandler, &info);//给进程所有task发送信号
}
if (ret < 0) {
return ret;
......@@ -286,42 +286,42 @@ int OsSigProcessSend(LosProcessCB *spcb, siginfo_t *sigInfo)
SigProcessLoadTcb(&info, sigInfo);
return 0;
}
//清空信号
int OsSigEmptySet(sigset_t *set)
{
*set = NULL_SIGNAL_SET;
return 0;
}
/* Privilege process can't send to kernel and privilege process */
/* Privilege process can't send to kernel and privilege process */ //特权进程无法发送到内核和特权进程
static int OsSignalPermissionToCheck(const LosProcessCB *spcb)
{
UINT32 gid = spcb->group->groupID;
if (gid == OS_KERNEL_PROCESS_GROUP) {
if (gid == OS_KERNEL_PROCESS_GROUP) {//内核进程组
return -EPERM;
} else if (gid == OS_USER_PRIVILEGE_PROCESS_GROUP) {
} else if (gid == OS_USER_PRIVILEGE_PROCESS_GROUP) {//用户特权进程组
return -EPERM;
}
return 0;
}
//发送信号
int OsDispatch(pid_t pid, siginfo_t *info, int permission)
{
LosProcessCB *spcb = OS_PCB_FROM_PID(pid);
LosProcessCB *spcb = OS_PCB_FROM_PID(pid);//找到这个进程
if (OsProcessIsUnused(spcb)) {
return -ESRCH;
}
#ifdef LOSCFG_SECURITY_CAPABILITY
LosProcessCB *current = OsCurrProcessGet();
#ifdef LOSCFG_SECURITY_CAPABILITY //启用安全模式
LosProcessCB *current = OsCurrProcessGet();//获取当前进程
/* If the process you want to kill had been inactive, but still exist. should return LOS_OK */
if (OsProcessIsInactive(spcb)) {
if (OsProcessIsInactive(spcb)) {//如果要终止的进程处于非活动状态,但仍然存在,应该返回OK
return LOS_OK;
}
/* Kernel process always has kill permission and user process should check permission */
/* Kernel process always has kill permission and user process should check permission *///内核进程总是有kill权限,用户进程应该检查权限
if (OsProcessIsUserMode(current) && !(current->processStatus & OS_PROCESS_FLAG_EXIT)) {
if ((current != spcb) && (!IsCapPermit(CAP_KILL)) && (current->user->userID != spcb->user->userID)) {
return -EPERM;
......@@ -331,29 +331,29 @@ int OsDispatch(pid_t pid, siginfo_t *info, int permission)
if ((permission == OS_USER_KILL_PERMISSION) && (OsSignalPermissionToCheck(spcb) < 0)) {
return -EPERM;
}
return OsSigProcessSend(spcb, info);
return OsSigProcessSend(spcb, info);//发送信号
}
//发送信号14(SIGALRM默认行为为进程终止)给7号进程:kill 14 7(kill -14 7效果相同),
int OsKill(pid_t pid, int sig, int permission)
{
siginfo_t info;
int ret;
/* Make sure that the para is valid */
if (!GOOD_SIGNO(sig) || pid < 0) {
if (!GOOD_SIGNO(sig) || pid < 0) {//有效信号
return -EINVAL;
}
if (OsProcessIDUserCheckInvalid(pid)) {
if (OsProcessIDUserCheckInvalid(pid)) {//检查参数
return -ESRCH;
}
/* Create the siginfo structure */
info.si_signo = sig;
info.si_code = SI_USER;
/* Create the siginfo structure */ //创建信号结构体
info.si_signo = sig; //信号编号
info.si_code = SI_USER; //表示用户信号
info.si_value.sival_ptr = NULL;
/* Send the signal */
ret = OsDispatch(pid, &info, permission);
ret = OsDispatch(pid, &info, permission);//发送信号
return ret;
}
......@@ -454,7 +454,7 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout)
sigcb = &task->sig;
if (sigcb->waitList.pstNext == NULL) {
LOS_ListInit(&sigcb->waitList);
LOS_ListInit(&sigcb->waitList);//初始化信号等待链表
}
/* If pendingflag & set > 0, shound clear pending flag */
sigset_t clear = sigcb->sigPendFlag & *set;
......@@ -466,7 +466,7 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout)
OsSigAddSet(set, SIGSTOP);
sigcb->sigwaitmask |= *set;
ret = OsTaskWait(&sigcb->waitList, timeout, TRUE);
ret = OsTaskWait(&sigcb->waitList, timeout, TRUE);//将当前任务挂到waitlist上
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
ret = -EAGAIN;
}
......@@ -477,7 +477,7 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout)
}
return ret;
}
//
int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout)
{
int ret;
......
......@@ -45,7 +45,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsPrintKillUsage(VOID)
{
PRINTK("\nkill: usage: kill [sigspec] [pid]\n");
}
// shell kill 命令用于发送特定信号给指定进程。kill [signo | -signo] [pid]
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdKill(INT32 argc, const CHAR **argv)
{
#define ARG_NUM 2
......@@ -67,7 +67,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdKill(INT32 argc, const CHAR **argv)
goto ERROR;
}
ret = OsKill(pidNo, abs(sigNo), OS_USER_KILL_PERMISSION);
ret = OsKill(pidNo, abs(sigNo), OS_USER_KILL_PERMISSION);// OS_USER_KILL_PERMISSION 干掉用户进程
HILOG_INFO(LOG_CORE, "Send signal(%d) to pidNo = %d!\n", abs(sigNo), pidNo);
if (ret == -1) {
HILOG_ERROR(LOG_CORE, "Kill fail ret = %d! Operation not permitted\n", ret);
......@@ -83,7 +83,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdKill(INT32 argc, const CHAR **argv)
}
return 0;
ERROR:
OsPrintKillUsage();
OsPrintKillUsage();//失败时 打印 kill 的用法
return 0;
}
......
git add -A
git commit -m 'shell 定时器,任务,系统信息 代码注释,Shell的本质是向外界提供一个窗口窥视内核.
git commit -m '任务和CP15协处理器寄存器代码注释,讲透 shell kill命令
鸿蒙内核源码分析系列 【 CSDN | OSCHINA | WIKI 】
鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓 】四大仓库每日同步更新代码和wiki
项目给鸿蒙内核源码逐行加上中文注解,详细阐述框架和代码细节, 精读 HarmonyOS 内核源码, 将迅速拔高对计算机整体理解,从此高屋建瓴看问题.'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册