Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
鸿蒙内核源码分析
注释鸿蒙内核源码
提交
7ea1ebee
注释鸿蒙内核源码
项目概览
鸿蒙内核源码分析
/
注释鸿蒙内核源码
通知
270
Star
29
Fork
11
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
106
Wiki
分析
仓库
DevOps
项目成员
Pages
注释鸿蒙内核源码
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
106
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
7ea1ebee
编写于
4月 09, 2021
作者:
鸿蒙内核源码分析
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
注解0号进程是如何创建的?
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://my.oschina.net/weharmony
上级
eaafbccc
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
72 addition
and
65 deletion
+72
-65
arch/arm/arm/include/arch_config.h
arch/arm/arm/include/arch_config.h
+1
-1
arch/arm/arm/include/los_hw_cpu.h
arch/arm/arm/include/los_hw_cpu.h
+8
-5
arch/arm/arm/src/include/los_hw_pri.h
arch/arm/arm/src/include/los_hw_pri.h
+2
-2
arch/arm/arm/src/los_exc.c
arch/arm/arm/src/los_exc.c
+6
-6
arch/arm/arm/src/los_hw.c
arch/arm/arm/src/los_hw.c
+1
-1
arch/arm/arm/src/los_hw_exc.S
arch/arm/arm/src/los_hw_exc.S
+3
-3
kernel/base/core/los_process.c
kernel/base/core/los_process.c
+22
-18
kernel/base/core/los_task.c
kernel/base/core/los_task.c
+5
-5
kernel/base/include/los_process_pri.h
kernel/base/include/los_process_pri.h
+1
-1
kernel/base/include/los_task_pri.h
kernel/base/include/los_task_pri.h
+7
-7
kernel/base/sched/sched_sq/los_sched.c
kernel/base/sched/sched_sq/los_sched.c
+3
-3
kernel/common/los_config.c
kernel/common/los_config.c
+3
-3
kernel/extended/dynload/include/los_load_elf.h
kernel/extended/dynload/include/los_load_elf.h
+4
-4
syscall/los_syscall.c
syscall/los_syscall.c
+5
-5
zzz/git/push.sh
zzz/git/push.sh
+1
-1
未找到文件。
arch/arm/arm/include/arch_config.h
浏览文件 @
7ea1ebee
...
...
@@ -86,7 +86,7 @@ SPSR(saved program status register)程序状态保存寄存器.
******************************************************************************/
#define CPSR_INT_DISABLE 0xC0
/* Disable both FIQ and IRQ */
//禁止IRQ和FIQ中断,因为0xC0 = 0x80 + 0x40
#define CPSR_IRQ_DISABLE 0x80
/* IRQ disabled when =1 */
//禁止IRQ 中断
#define CPSR_FIQ_DISABLE 0x40
/* FIQ disabled when =1 */
//禁止
FIQ中断
#define CPSR_FIQ_DISABLE 0x40
/* FIQ disabled when =1 */
//禁止FIQ中断
#define CPSR_THUMB_ENABLE 0x20
/* Thumb mode when =1 */
//使能Thumb模式 1:CPU处于Thumb状态, 0:CPU处于ARM状态
#define CPSR_USER_MODE 0x10 //用户模式,除了用户模式,其余模式也叫特权模式,特权模式中除了系统模式以外的其余5种模式称为异常模式;
#define CPSR_FIQ_MODE 0x11 //快中断模式 用于高速数据传输或通道处理
...
...
arch/arm/arm/include/los_hw_cpu.h
浏览文件 @
7ea1ebee
...
...
@@ -131,17 +131,20 @@ STATIC INLINE VOID *ArchCurrTaskGet(VOID)
{
return
(
VOID
*
)(
UINTPTR
)
ARM_SYSREG_READ
(
TPIDRPRW
);
//读c13寄存器
}
//设置当前task ID
STATIC
INLINE
VOID
ArchCurrTaskSet
(
VOID
*
val
)
{
ARM_SYSREG_WRITE
(
TPIDRPRW
,
(
UINT32
)(
UINTPTR
)
val
);
}
//向协处理器写入用户态任务ID TPIDRURO 仅用于用户态
STATIC
INLINE
VOID
ArchCurrUserTaskSet
(
UINTPTR
val
)
{
ARM_SYSREG_WRITE
(
TPIDRURO
,
(
UINT32
)
val
);
}
//https://www.keil.com/pack/doc/cmsis/Core_A/html/group__CMSIS__MPIDR.html
/*
* https://www.keil.com/pack/doc/cmsis/Core_A/html/group__CMSIS__MPIDR.html
* 在多处理器系统中,MPIDR为调度目的提供额外的处理器标识机制,并指示实现是否包括多处理器扩展。
*/
STATIC
INLINE
UINT32
ArchCurrCpuid
(
VOID
)
{
#if (LOSCFG_KERNEL_SMP == YES)//CPU多核情况
...
...
@@ -163,7 +166,7 @@ STATIC INLINE UINT32 OsMainIDGet(VOID)
/* CPU interrupt mask handle implementation */
//CPU中断掩码句柄实现
#if LOSCFG_ARM_ARCH >= 6
//禁止中断
STATIC
INLINE
UINT32
ArchIntLock
(
VOID
)
{
UINT32
intSave
;
...
...
@@ -175,7 +178,7 @@ STATIC INLINE UINT32 ArchIntLock(VOID)
:
"memory"
);
return
intSave
;
}
//恢复中断
STATIC
INLINE
UINT32
ArchIntUnlock
(
VOID
)
{
UINT32
intSave
;
...
...
arch/arm/arm/src/include/los_hw_pri.h
浏览文件 @
7ea1ebee
...
...
@@ -59,8 +59,8 @@ typedef struct { //参考OsTaskSchedule来理解
UINT32
resved
;
/* It's stack 8 aligned */
UINT32
regPSR
;
UINT32
R
[
GEN_REGS_NUM
];
/* R0-R12 */
UINT32
SP
;
/* R13 */
UINT32
LR
;
/* R14 */
UINT32
SP
;
/* R13 */
//保存用户空间SP
UINT32
LR
;
/* R14 */
//保存用户空间LR
UINT32
PC
;
/* R15 */
}
TaskContext
;
...
...
arch/arm/arm/src/los_exc.c
浏览文件 @
7ea1ebee
...
...
@@ -623,8 +623,8 @@ STATIC INLINE BOOL FindSuitableStack(UINTPTR regFP, UINTPTR *start, UINTPTR *end
if
(
g_excFromUserMode
[
ArchCurrCpuid
()]
==
TRUE
)
{
//当前CPU在用户态执行发生异常
taskCB
=
OsCurrTaskGet
();
stackStart
=
taskCB
->
userMapBase
;
stackEnd
=
taskCB
->
userMapBase
+
taskCB
->
userMapSize
;
stackStart
=
taskCB
->
userMapBase
;
//用户态栈基地址,即用户态栈顶
stackEnd
=
taskCB
->
userMapBase
+
taskCB
->
userMapSize
;
//用户态栈结束地址
if
(
IsValidFP
(
regFP
,
stackStart
,
stackEnd
,
&
kvaddr
)
==
TRUE
)
{
found
=
TRUE
;
goto
FOUND
;
...
...
@@ -632,22 +632,22 @@ STATIC INLINE BOOL FindSuitableStack(UINTPTR regFP, UINTPTR *start, UINTPTR *end
return
found
;
}
/* Search in the task stacks */
/* Search in the task stacks */
//找任务的内核态栈
for
(
index
=
0
;
index
<
g_taskMaxNum
;
index
++
)
{
taskCB
=
&
g_taskCBArray
[
index
];
if
(
OsTaskIsUnused
(
taskCB
))
{
continue
;
}
stackStart
=
taskCB
->
topOfStack
;
stackEnd
=
taskCB
->
topOfStack
+
taskCB
->
stackSize
;
stackStart
=
taskCB
->
topOfStack
;
//内核态栈顶
stackEnd
=
taskCB
->
topOfStack
+
taskCB
->
stackSize
;
//内核态栈底
if
(
IsValidFP
(
regFP
,
stackStart
,
stackEnd
,
&
kvaddr
)
==
TRUE
)
{
found
=
TRUE
;
goto
FOUND
;
}
}
/* Search in the exc stacks */
/* Search in the exc stacks */
//从异常栈中找
for
(
index
=
0
;
index
<
sizeof
(
g_excStack
)
/
sizeof
(
StackInfo
);
index
++
)
{
stack
=
&
g_excStack
[
index
];
stackStart
=
(
UINTPTR
)
stack
->
stackTop
;
...
...
arch/arm/arm/src/los_hw.c
浏览文件 @
7ea1ebee
...
...
@@ -141,7 +141,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_F
#else
context
->
regPSR
=
PSR_MODE_USR_ARM
;
//工作模式:用户模式 + 工作状态:arm
#endif
context
->
R
[
0
]
=
stack
;
//
因为要回到用户态空间运行,所以要作为参数传回SP值
context
->
R
[
0
]
=
stack
;
//
将用户态栈指针保存到上下文R0处
context
->
SP
=
TRUNCATE
(
stack
,
LOSCFG_STACK_POINT_ALIGN_SIZE
);
//改变 上下文的SP值,指向用户栈空间
context
->
LR
=
0
;
//保存子程序返回地址 例如 a call b ,在b中保存 a地址
context
->
PC
=
(
UINTPTR
)
taskEntry
;
//入口函数,由外部传入,由上层应用指定,固然每个都不一样.
...
...
arch/arm/arm/src/los_hw_exc.S
浏览文件 @
7ea1ebee
...
...
@@ -178,9 +178,9 @@ STMDA(完成操作而后地址递减)、STMED(空递减堆栈)。
*/
@
Description
:
Software
interrupt
exception
handler
_osExceptSwiHdl
:
@软中断异常处理
_osExceptSwiHdl
:
@软中断异常处理
,注意此时已在内核栈运行
@保存任务上下文(
TaskContext
)
开始
...
一定要对照
TaskContext
来理解
SUB
SP
,
SP
,
#(
4
*
16
)
@
先申请
16
个栈空间用于处理本次软中断
SUB
SP
,
SP
,
#(
4
*
16
)
@
先申请
16
个栈空间
单元
用于处理本次软中断
STMIA
SP
,
{
R0
-
R12
}
@
TaskContext
.
R
[
GEN_REGS_NUM
]
STMIA
从左到右执行
,
先放
R0
..
R12
MRS
R3
,
SPSR
@
读取本模式下的
SPSR
值
MOV
R4
,
LR
@
保存回跳寄存器
LR
...
...
@@ -201,7 +201,7 @@ _osExceptSwiHdl: @软中断异常处理
@保存任务上下文(
TaskContext
)
结束
MOV
FP
,
#
0
@
Init
frame
pointer
CPSIE
I
@
开中断
,
表明在系统调用期间可响应中断
BLX
OsArmA32SyscallHandle
/*
交给
C
语言处理系统调用
*/
BLX
OsArmA32SyscallHandle
/*
交给
C
语言处理系统调用
,
参数为
R0
,
指向
TaskContext
的开始位置
*/
CPSID
I
@
执行后续指令前必须先关中断
@恢复任务上下文(
TaskContext
)
开始
POP_FPU_REGS
R1
@
弹出
FP
值给
R1
...
...
kernel/base/core/los_process.c
浏览文件 @
7ea1ebee
...
...
@@ -525,16 +525,19 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsProcessInit(VOID)
LOS_ListInit
(
&
g_processRecyleList
);
//进程回收链表初始化,回收完成后进入g_freeProcess等待再次被申请使用
for
(
index
=
0
;
index
<
g_processMaxNum
;
index
++
)
{
//进程池循环创建
g_processCBArray
[
index
].
processID
=
index
;
//进程ID[0-g_processMaxNum]赋值
g_processCBArray
[
index
].
processID
=
index
;
//进程ID[0-g_processMaxNum
-1
]赋值
g_processCBArray
[
index
].
processStatus
=
OS_PROCESS_FLAG_UNUSED
;
// 默认都是白纸一张,贴上未使用标签
LOS_ListTailInsert
(
&
g_freeProcess
,
&
g_processCBArray
[
index
].
pendList
);
//注意g_freeProcess挂的是pendList节点,所以使用要通过OS_PCB_FROM_PENDLIST找到进程实体.
}
g_userInitProcess
=
1
;
/* 1: The root process ID of the user-mode process is fixed at 1 */
//用户态的根进程
LOS_ListDelete
(
&
g_processCBArray
[
g_userInitProcess
].
pendList
);
//
清空g_userInitProcess pend链表
LOS_ListDelete
(
&
g_processCBArray
[
g_userInitProcess
].
pendList
);
//
将1号进程从空闲链表上摘出去
g_kernelInitProcess
=
2
;
/* 2: The root process ID of the kernel-mode process is fixed at 2 */
//内核态的根进程
LOS_ListDelete
(
&
g_processCBArray
[
g_kernelInitProcess
].
pendList
);
// 清空g_kernelInitProcess pend链表
LOS_ListDelete
(
&
g_processCBArray
[
g_kernelInitProcess
].
pendList
);
// 将2号进程从空闲链表上摘出去
//注意:这波骚操作之后,g_freeProcess链表上还有,0,3,4,...g_processMaxNum-1号进程.创建进程是从g_freeProcess上申请
//即下次申请到的将是0号进程,而 OsCreateIdleProcess 将占有0号进程.
return
LOS_OK
;
}
...
...
@@ -553,10 +556,10 @@ STATIC UINT32 OsCreateIdleProcess(VOID)
}
//创建一个名叫"KIdle"的进程,并创建一个idle task,CPU空闲的时候就待在 idle task中等待被唤醒
ret
=
LOS_Fork
(
CLONE_FILES
,
"KIdle"
,
(
TSK_ENTRY_FUNC
)
OsIdleTask
,
LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
//内核进程的fork并不会一次调用,返回两次,此子进程执行的开始位置是参数OsIdleTask
return
LOS_NOK
;
}
g_kernelIdleProcess
=
(
UINT32
)
ret
;
//返回
进程ID
g_kernelIdleProcess
=
(
UINT32
)
ret
;
//返回
0号进程
idleProcess
=
OS_PCB_FROM_PID
(
g_kernelIdleProcess
);
//通过ID拿到进程实体
*
idleTaskID
=
idleProcess
->
threadGroupID
;
//绑定CPU的IdleTask,或者说改变CPU现有的idle任务
...
...
@@ -619,14 +622,14 @@ STATIC LosProcessCB *OsGetFreePCB(VOID)
UINT32
intSave
;
SCHEDULER_LOCK
(
intSave
);
if
(
LOS_ListEmpty
(
&
g_freeProcess
))
{
//空闲池里还有未分配的
task
?
if
(
LOS_ListEmpty
(
&
g_freeProcess
))
{
//空闲池里还有未分配的
进程
?
SCHEDULER_UNLOCK
(
intSave
);
PRINT_ERR
(
"No idle PCB in the system!
\n
"
);
return
NULL
;
}
processCB
=
OS_PCB_FROM_PENDLIST
(
LOS_DL_LIST_FIRST
(
&
g_freeProcess
));
//拿到PCB,通过OS_PCB_FROM_PENDLIST是因为通过pendlist 节点挂在 freelist链表上.
LOS_ListDelete
(
&
processCB
->
pendList
);
//
分配出来了就要在freelist将自己
摘除
LOS_ListDelete
(
&
processCB
->
pendList
);
//
将自己从g_freeProcess链表
摘除
SCHEDULER_UNLOCK
(
intSave
);
return
processCB
;
...
...
@@ -907,7 +910,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsKernelInitProcess(VOID)
processCB
->
processStatus
&=
~
OS_PROCESS_STATUS_INIT
;
// 进程初始化位 置1
g_processGroup
=
processCB
->
group
;
//全局进程组指向了KProcess所在的进程组
LOS_ListInit
(
&
g_processGroup
->
groupList
);
// 进程组链表初始化
OsCurrProcessSet
(
processCB
);
// 设置为当前进程
OsCurrProcessSet
(
processCB
);
//
将KProcess
设置为当前进程
return
OsCreateIdleProcess
();
// 创建一个空闲状态的进程
}
...
...
@@ -1547,7 +1550,7 @@ LITE_OS_SEC_TEXT UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR
LOS_VmSpaceFree
(
oldSpace
);
//ELF已经接管了进程,进程的原有虚拟空间要被释放掉
return
LOS_OK
;
}
//
进程层面的开始执行
, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小
//
执行用户态任务
, entry为入口函数 ,其中 创建好task,task上下文 等待调度真正执行, sp:栈指针 mapBase:栈底 mapSize:栈大小
LITE_OS_SEC_TEXT
UINT32
OsExecStart
(
const
TSK_ENTRY_FUNC
entry
,
UINTPTR
sp
,
UINTPTR
mapBase
,
UINT32
mapSize
)
{
LosProcessCB
*
processCB
=
NULL
;
...
...
@@ -1572,12 +1575,13 @@ LITE_OS_SEC_TEXT UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINT
taskCB
=
OsCurrTaskGet
();
//获取当前任务
processCB
->
threadGroupID
=
taskCB
->
taskID
;
//threadGroupID是进程的主线程ID,也就是应用程序 main函数线程
taskCB
->
userMapBase
=
mapBase
;
//
任务用户态栈底地址
taskCB
->
userMapSize
=
mapSize
;
//
任务
用户态栈大小
taskCB
->
userMapBase
=
mapBase
;
//
用户态栈顶
taskCB
->
userMapSize
=
mapSize
;
//用户态栈大小
taskCB
->
taskEntry
=
(
TSK_ENTRY_FUNC
)
entry
;
//任务的入口函数
taskContext
=
(
TaskContext
*
)
OsTaskStackInit
(
taskCB
->
taskID
,
taskCB
->
stackSize
,
(
VOID
*
)
taskCB
->
topOfStack
,
FALSE
);
//创建任务上下文
OsUserTaskStackInit
(
taskContext
,
taskCB
->
taskEntry
,
sp
);
//用户进程任务栈初始化
taskContext
=
(
TaskContext
*
)
OsTaskStackInit
(
taskCB
->
taskID
,
taskCB
->
stackSize
,
(
VOID
*
)
taskCB
->
topOfStack
,
FALSE
);
//在内核栈中创建任务上下文
OsUserTaskStackInit
(
taskContext
,
taskCB
->
taskEntry
,
sp
);
//初始化用户栈,将内核栈中上下文的 context->R[0] = sp ,context->sp = sp
//这样做的目的是将用户栈SP保存到内核栈中,
SCHEDULER_UNLOCK
(
intSave
);
//解锁
return
LOS_OK
;
}
...
...
@@ -1641,7 +1645,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID)
(
VOID
)
memset_s
((
VOID
*
)((
UINTPTR
)
userText
+
userInitBssStart
-
userInitTextStart
),
initBssSize
,
0
,
initBssSize
);
// 除了代码段,其余都清0
stack
=
OsUserInitStackAlloc
(
g_userInitProcess
,
&
size
);
//分配任务在用户态下的运行栈,大小为1M,注意此内存来自
进程空间,而非内核
空间.
stack
=
OsUserInitStackAlloc
(
g_userInitProcess
,
&
size
);
//分配任务在用户态下的运行栈,大小为1M,注意此内存来自
用户
空间.
if
(
stack
==
NULL
)
{
PRINTK
(
"user init process malloc user stack failed!
\n
"
);
ret
=
LOS_NOK
;
...
...
@@ -1696,7 +1700,7 @@ STATIC VOID OsInitCopyTaskParam(LosProcessCB *childProcessCB, const CHAR *name,
childPara
->
userParam
.
userArea
=
mainThread
->
userArea
;
//用户态栈区栈顶位置
childPara
->
userParam
.
userMapBase
=
mainThread
->
userMapBase
;
//用户态栈底
childPara
->
userParam
.
userMapSize
=
mainThread
->
userMapSize
;
//用户态栈大小
}
else
{
}
else
{
//注意内核态进程创建任务的入口由外界指定,例如 OsCreateIdleProcess 指定了OsIdleTask
childPara
->
pfnTaskEntry
=
(
TSK_ENTRY_FUNC
)
entry
;
//参数(sp)为内核态入口地址
childPara
->
uwStackSize
=
size
;
//参数(size)为内核态栈大小
}
...
...
@@ -1987,17 +1991,17 @@ LITE_OS_SEC_TEXT VOID LOS_Exit(INT32 status)
OsTaskExitGroup
((
UINT32
)
status
);
OsProcessExit
(
OsCurrTaskGet
(),
(
UINT32
)
status
);
}
//获取用户进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的
//获取用户
态
进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的
LITE_OS_SEC_TEXT
UINT32
OsGetUserInitProcessID
(
VOID
)
{
return
g_userInitProcess
;
}
//获取Idel进程,CPU
不公正
时待的地方,等待被事件唤醒
//获取Idel进程,CPU
休息
时待的地方,等待被事件唤醒
LITE_OS_SEC_TEXT
UINT32
OsGetIdleProcessID
(
VOID
)
{
return
g_kernelIdleProcess
;
}
//获取内核进程的根进程,所有内核进程都是g_processCBArray[g_kernelInitProcess] fork来的,包括g_processCBArray[g_kernelIdleProcess]进程
//获取内核
态
进程的根进程,所有内核进程都是g_processCBArray[g_kernelInitProcess] fork来的,包括g_processCBArray[g_kernelIdleProcess]进程
LITE_OS_SEC_TEXT
UINT32
OsGetKernelInitProcessID
(
VOID
)
{
return
g_kernelInitProcess
;
...
...
kernel/base/core/los_task.c
浏览文件 @
7ea1ebee
...
...
@@ -767,7 +767,7 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB,
taskCB
->
args
[
1
]
=
initParam
->
auwArgs
[
1
];
taskCB
->
args
[
2
]
=
initParam
->
auwArgs
[
2
];
taskCB
->
args
[
3
]
=
initParam
->
auwArgs
[
3
];
taskCB
->
topOfStack
=
(
UINTPTR
)
topStack
;
//内核态栈
起始位置
taskCB
->
topOfStack
=
(
UINTPTR
)
topStack
;
//内核态栈
顶
taskCB
->
stackSize
=
initParam
->
uwStackSize
;
//
taskCB
->
priority
=
initParam
->
usTaskPrio
;
taskCB
->
taskEntry
=
initParam
->
pfnTaskEntry
;
...
...
@@ -805,7 +805,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_IN
LosProcessCB
*
processCB
=
NULL
;
OsTaskCBInitBase
(
taskCB
,
stackPtr
,
topStack
,
initParam
);
//初始化任务的基本信息,
//taskCB->stackPointer
= stackPtr ,用户态时将改写taskCB->stackPointer指向
//taskCB->stackPointer
指向内核态栈 sp位置,该位置存着 任务初始上下文
SCHEDULER_LOCK
(
intSave
);
processCB
=
OS_PCB_FROM_PID
(
initParam
->
processID
);
//通过ID获取PCB ,单核进程数最多64个
...
...
@@ -817,7 +817,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_IN
taskCB
->
userMapBase
=
initParam
->
userParam
.
userMapBase
;
taskCB
->
userMapSize
=
initParam
->
userParam
.
userMapSize
;
OsUserTaskStackInit
(
taskCB
->
stackPointer
,
taskCB
->
taskEntry
,
initParam
->
userParam
.
userSP
);
//初始化用户态任务栈
//这里要注意,任务的上下文是始终保存在内核栈空间,
但用户态时运行是在用户态的栈空间.(因为SP指向了用户态
空间)
//这里要注意,任务的上下文是始终保存在内核栈空间,
而用户态时运行在用户态栈空间.(context->SP = userSP 指向了用户态栈
空间)
}
if
(
!
processCB
->
threadNumber
)
{
//进程线程数量为0时,
...
...
@@ -1584,8 +1584,8 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf
taskInfo
->
usTaskStatus
=
taskCB
->
taskStatus
;
taskInfo
->
usTaskPrio
=
taskCB
->
priority
;
taskInfo
->
uwStackSize
=
taskCB
->
stackSize
;
taskInfo
->
uwTopOfStack
=
taskCB
->
topOfStack
;
taskInfo
->
uwStackSize
=
taskCB
->
stackSize
;
//内核态栈大小
taskInfo
->
uwTopOfStack
=
taskCB
->
topOfStack
;
//内核态栈顶位置
taskInfo
->
uwEventMask
=
taskCB
->
eventMask
;
taskInfo
->
taskEvent
=
taskCB
->
taskEvent
;
taskInfo
->
pTaskSem
=
taskCB
->
taskSem
;
...
...
kernel/base/include/los_process_pri.h
浏览文件 @
7ea1ebee
...
...
@@ -386,7 +386,7 @@ STATIC INLINE LosProcessCB *OsCurrProcessGet(VOID)
LOS_IntRestore
(
intSave
);
//恢复硬件中断
return
runProcess
;
}
//设置当前进程,加入g_runProcess中
//设置
使用CPU的
当前进程,加入g_runProcess中
STATIC
INLINE
VOID
OsCurrProcessSet
(
const
LosProcessCB
*
process
)
{
g_runProcess
[
ArchCurrCpuid
()]
=
(
LosProcessCB
*
)
process
;
...
...
kernel/base/include/los_task_pri.h
浏览文件 @
7ea1ebee
...
...
@@ -294,13 +294,13 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁
#define OS_TCB_NAME_LEN 32
typedef
struct
{
VOID
*
stackPointer
;
/**< Task stack pointer */
//
栈指针,SP位置,切换任务时先保存上下文并指向TaskContext位置
.
VOID
*
stackPointer
;
/**< Task stack pointer */
//
内核栈指针位置,内核栈默认保存了初始的上下文信息
.
UINT16
taskStatus
;
/**< Task status */
//各种状态标签,可以拥有多种标签,按位标识
UINT16
priority
;
/**< Task priority */
//任务优先级[0:31],默认是31级
UINT16
policy
;
//任务的调度方式(三种 .. LOS_SCHED_RR )
UINT16
timeSlice
;
/**< Remaining time slice */
//剩余时间片
UINT32
stackSize
;
/**< Task stack size */
//栈大小,内存来自内核空间
UINTPTR
topOfStack
;
/**< Task stack top */
//
栈顶 bottom = top + size,内存来自内核空间
UINT32
stackSize
;
/**< Task stack size */
//
内核态
栈大小,内存来自内核空间
UINTPTR
topOfStack
;
/**< Task stack top */
//
内核态栈顶 bottom = top + size
UINT32
taskID
;
/**< Task ID */
//任务ID,任务池本质是一个大数组,ID就是数组的索引,默认 < 128
TSK_ENTRY_FUNC
taskEntry
;
/**< Task entrance function */
//任务执行入口函数
VOID
*
joinRetval
;
/**< pthread adaption */
//用来存储join线程的返回值
...
...
@@ -334,8 +334,8 @@ typedef struct {
SchedStat
schedStat
;
/**< Schedule statistics */
//调度统计
#endif
#endif
UINTPTR
userArea
;
//用户
区域
,由运行时划定,根据运行态不同而不同
UINTPTR
userMapBase
;
//
内存来自进程空间,用户态下的栈底位置
,和topOfStack有本质的区别.
UINTPTR
userArea
;
//用户
空间
,由运行时划定,根据运行态不同而不同
UINTPTR
userMapBase
;
//
用户态栈基地址,内存来自用户空间
,和topOfStack有本质的区别.
UINT32
userMapSize
;
/**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */
UINT32
processID
;
/**< Which belong process */
//所属进程ID
FutexNode
futex
;
//实现快锁功能
...
...
@@ -395,12 +395,12 @@ 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
);
...
...
kernel/base/sched/sched_sq/los_sched.c
浏览文件 @
7ea1ebee
...
...
@@ -130,10 +130,10 @@ VOID OsSchedResched(VOID)
newTask
->
timeSlice
=
LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT
;
//给新任务时间片 默认 20ms
}
OsCurrTaskSet
((
VOID
*
)
newTask
);
//设置新的task为
CPU核的
当前任务
OsCurrTaskSet
((
VOID
*
)
newTask
);
//设置新的task为当前任务
if
(
OsProcessIsUserMode
(
newProcess
))
{
//用户
模式需自带栈空间
OsCurrUserTaskSet
(
newTask
->
userArea
);
//
设置task栈空间
if
(
OsProcessIsUserMode
(
newProcess
))
{
//用户
态进程
OsCurrUserTaskSet
(
newTask
->
userArea
);
//
向CP15 (c13, 0, c0, 3) 设置当前线程ID
}
PRINT_TRACE
(
"cpu%d run process name: (%s) pid: %d status: %x threadMap: %x task name: (%s) tid: %d status: %x ->
\n
"
...
...
kernel/common/los_config.c
浏览文件 @
7ea1ebee
...
...
@@ -296,7 +296,7 @@ LITE_OS_SEC_TEXT_INIT INT32 OsMain(VOID)
}
#endif
ret
=
OsKernelInitProcess
();
//
完成内核进程的初始化
ret
=
OsKernelInitProcess
();
//
初始化内核态根进程
if
(
ret
!=
LOS_OK
)
{
return
ret
;
}
...
...
@@ -387,7 +387,7 @@ STATIC UINT32 OsSystemInitTaskCreate(VOID)
TSK_INIT_PARAM_S
sysTask
;
(
VOID
)
memset_s
(
&
sysTask
,
sizeof
(
TSK_INIT_PARAM_S
),
0
,
sizeof
(
TSK_INIT_PARAM_S
));
sysTask
.
pfnTaskEntry
=
(
TSK_ENTRY_FUNC
)
SystemInit
;
//任务的入口函数,这个任务由外部提供
比如..\vendor\hi3516dv300\module_init\src\system_init.c
sysTask
.
pfnTaskEntry
=
(
TSK_ENTRY_FUNC
)
SystemInit
;
//任务的入口函数,这个任务由外部提供比如..\vendor\hi3516dv300\module_init\src\system_init.c
sysTask
.
uwStackSize
=
LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE
;
//16K
sysTask
.
pcName
=
"SystemInit"
;
//任务的名称
sysTask
.
usTaskPrio
=
LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO
;
// 内核默认优先级为10
...
...
@@ -423,7 +423,7 @@ UINT32 OsSystemInit(VOID)
#ifdef LOSCFG_COMPAT_LINUXKPI
g_pstSystemWq
=
create_workqueue
(
"system_wq"
);
#endif
ret
=
OsSystemInitTaskCreate
();
//创建 "SystemInit" 任务
ret
=
OsSystemInitTaskCreate
();
//创建 "SystemInit" 任务
,用户创建用户态根进程
if
(
ret
!=
LOS_OK
)
{
return
ret
;
}
...
...
kernel/extended/dynload/include/los_load_elf.h
浏览文件 @
7ea1ebee
...
...
@@ -92,11 +92,11 @@ typedef struct {
INT32
envc
;
CHAR
*
const
*
argv
;
CHAR
*
const
*
envp
;
UINTPTR
stackTop
;
UINTPTR
stackTopMax
;
UINTPTR
stackBase
;
UINTPTR
stackTop
;
//当前栈顶
UINTPTR
stackTopMax
;
//栈顶最大值,其实必 stackTopMax < stackTop
UINTPTR
stackBase
;
//栈底
UINTPTR
stackParamBase
;
UINT32
stackSize
;
UINT32
stackSize
;
//栈大小
INT32
stackProt
;
UINTPTR
loadAddr
;
UINTPTR
elfEntry
;
//入口函数位置
...
...
syscall/los_syscall.c
浏览文件 @
7ea1ebee
...
...
@@ -94,7 +94,7 @@ void SyscallHandleInit(void)
/* The SYSCALL ID is in R7 on entry. Parameters follow in R0..R6 */
/******************************************************************
由汇编调用,见于 los_hw_exc.s
第197行 BLX
OsArmA32SyscallHandle
由汇编调用,见于 los_hw_exc.s
/ BLX
OsArmA32SyscallHandle
SYSCALL是产生系统调用时触发的信号,R7寄存器存放具体的系统调用ID,也叫系统调用号
regs:参数就是所有寄存器
注意:本函数在用户态和内核态下都可能被调用到
...
...
@@ -112,8 +112,8 @@ LITE_OS_SEC_TEXT UINT32 *OsArmA32SyscallHandle(UINT32 *regs)
return
regs
;
}
if
(
cmd
==
__NR_sigreturn
)
{
//
此时运行在内核栈,程序返回的调用,从内核态返回用户态时触发
OsRestorSignalContext
(
regs
);
//恢复信号上下文
,执行完函数后,切到了用户栈
if
(
cmd
==
__NR_sigreturn
)
{
//
收到 __NR_sigreturn 信号
OsRestorSignalContext
(
regs
);
//恢复信号上下文
return
regs
;
}
...
...
@@ -131,7 +131,7 @@ LITE_OS_SEC_TEXT UINT32 *OsArmA32SyscallHandle(UINT32 *regs)
case
ARG_NUM_1
:
ret
=
(
*
(
SyscallFun1
)
handle
)(
regs
[
REG_R0
]);
//执行系统调用,类似 SysUnlink(pathname);
break
;
case
ARG_NUM_2
:
//
@note_thinking 如何是两个参数的系统调用,这里传的确是三个参数,任务栈中会出现怎样的情况呢?
case
ARG_NUM_2
:
//
如何是两个参数的系统调用,这里传三个参数也没有问题,因被调用函数不会去取用R2值
case
ARG_NUM_3
:
ret
=
(
*
(
SyscallFun3
)
handle
)(
regs
[
REG_R0
],
regs
[
REG_R1
],
regs
[
REG_R2
]);
//类似 SysExecve(fileName, argv, envp);
break
;
...
...
@@ -146,7 +146,7 @@ LITE_OS_SEC_TEXT UINT32 *OsArmA32SyscallHandle(UINT32 *regs)
}
regs
[
REG_R0
]
=
ret
;
//R0保存系统调用返回值
OsSaveSignalContext
(
regs
);
//保存
用户栈
现场
OsSaveSignalContext
(
regs
);
//保存
信号上下文
现场
/* Return the last value of curent_regs. This supports context switches on return from the exception.
* That capability is only used with theSYS_context_switch system call.
...
...
zzz/git/push.sh
浏览文件 @
7ea1ebee
git add
-A
git commit
-m
'
用户态,内核态代码注解
git commit
-m
'
注解0号进程是如何创建的?
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://my.oschina.net/weharmony
'
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录