Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
鸿蒙内核源码分析
注释鸿蒙内核源码
提交
f5946584
注释鸿蒙内核源码
项目概览
鸿蒙内核源码分析
/
注释鸿蒙内核源码
通知
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 搜索 >>
提交
f5946584
编写于
2月 24, 2021
作者:
鸿蒙内核源码分析
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
系统调用由软中断实现,对其汇编代码注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://weharmony.gitee.io
上级
d011b438
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
64 addition
and
63 deletion
+64
-63
arch/arm/arm/src/los_dispatch.S
arch/arm/arm/src/los_dispatch.S
+14
-14
arch/arm/arm/src/los_hw_exc.S
arch/arm/arm/src/los_hw_exc.S
+26
-26
arch/arm/arm/src/los_hwi.c
arch/arm/arm/src/los_hwi.c
+3
-3
arch/arm/arm/src/startup/reset_vector_mp.S
arch/arm/arm/src/startup/reset_vector_mp.S
+2
-2
kernel/base/core/los_task.c
kernel/base/core/los_task.c
+15
-15
kernel/base/include/los_process_pri.h
kernel/base/include/los_process_pri.h
+1
-1
zzz/git/push.sh
zzz/git/push.sh
+3
-2
未找到文件。
arch/arm/arm/src/los_dispatch.S
浏览文件 @
f5946584
...
...
@@ -254,23 +254,23 @@ OsKernelTaskLoad: @内核任务的加载
ADD
SP
,
SP
,
#
4
@
sp
=
SP
+
4
LDMFD
SP
!,
{
LR
,
PC
}^
@
返回地址赋给
pc
指针
OsIrqHandler
:
@中断处理
OsIrqHandler
:
@
硬
中断处理
SUB
LR
,
LR
,
#
4
/
*
push
r0
-
r3
to
irq
stack
*/
STMFD
SP
,
{
R0
-
R3
}
STMFD
SP
,
{
R0
-
R3
}
@
r0
-
r3
寄存器入栈
SUB
R0
,
SP
,
#(
4
*
4
)
MRS
R1
,
SPSR
@
获取程序状态控制寄存器
MOV
R2
,
LR
/
*
disable
irq
,
switch
to
svc
mode
*/
CPSID
i
,
#
0x13
@
禁止中断
,
切换到
SVC
模式
/
*
disable
irq
,
switch
to
svc
mode
*/
@
超级用户模式
(
SVC
模式
)
,主要用于
SWI
(
软件中断
)
和
OS
(
操作系统
)
。
CPSID
i
,
#
0x13
@
切换到
SVC
模式
,
此处一切换
,
后续指令将入
SVC
的栈
@
CPSID
i
为关中断指令
,
对应的是
CPSIE
/
*
push
spsr
and
pc
in
svc
stack
*/
STMFD
SP
!,
{
R1
,
R2
}
STMFD
SP
,
{
LR
}
STMFD
SP
!,
{
R1
,
R2
}
@
实际是将
SPSR
,
和
LR
入栈
,
入栈顺序为
R1
,
R2
,
SP
自增
STMFD
SP
,
{
LR
}
@
LR
再入栈
,
SP
不自增
AND
R3
,
R1
,
#
CPSR_MASK_MODE
AND
R3
,
R1
,
#
CPSR_MASK_MODE
@
获取
CPU
的运行模式
CMP
R3
,
#
CPSR_USER_MODE
@
中断是否发生在用户模式
BNE
OsIrqFromKernel
@
中断不发生在用户模式下则跳转到
OsIrqFromKernel
...
...
@@ -324,15 +324,15 @@ OsIrqFromKernel: @从内核发起中断
ADD
SP
,
SP
,
#
4
OsIrqContextRestore
:
LDR
R0
,
[
SP
,
#(
4
*
7
)]
MSR
SPSR_cxsf
,
R0
OsIrqContextRestore
:
@中断环境恢复
LDR
R0
,
[
SP
,
#(
4
*
7
)]
@
读取
SP
+
28
位置数据给
R0
MSR
SPSR_cxsf
,
R0
@
恢复
spsr
AND
R0
,
R0
,
#
CPSR_MASK_MODE
CMP
R0
,
#
CPSR_USER_MODE
CMP
R0
,
#
CPSR_USER_MODE
@
LDMFD
SP
!,
{
R0
-
R3
,
R12
}
LDMFD
SP
!,
{
R0
-
R3
,
R12
}
@
BNE
OsIrqContextRestoreToKernel
BNE
OsIrqContextRestoreToKernel
@
CPU
工作在非用户模式
/
*
load
user
sp
and
lr
,
and
jump
cpsr
*/
LDMFD
SP
,
{
R13
,
R14
}^
...
...
arch/arm/arm/src/los_hw_exc.S
浏览文件 @
f5946584
...
...
@@ -158,7 +158,7 @@ __stack_chk_guard_setup:
POP
{
FP
,
PC
}
@
Description
:
Undefined
instruction
exception
handler
_osExceptUndefInstrHdl
:
_osExceptUndefInstrHdl
:
@出现未定义的指令处理
#ifdef LOSCFG_GDB
GDB_HANDLE
OsUndefIncExcHandleEntry
#
else
...
...
@@ -172,43 +172,43 @@ _osExceptUndefInstrHdl:
#
endif
@
Description
:
Software
interrupt
exception
handler
_osExceptSwiHdl
:
SUB
SP
,
SP
,
#(
4
*
16
)
STMIA
SP
,
{
R0
-
R12
}
MRS
R3
,
SPSR
MOV
R4
,
LR
AND
R1
,
R3
,
#
CPSR_MASK_MODE
@
Interrupted
mode
CMP
R1
,
#
CPSR_USER_MODE
@
User
mode
BNE
OsKernelSVCHandler
@
Branch
if
not
user
mode
_osExceptSwiHdl
:
@软中断异常处理
SUB
SP
,
SP
,
#(
4
*
16
)
@
先申请
16
个栈空间用于处理本次软中断
STMIA
SP
,
{
R0
-
R12
}
@
保存
R0
-
R12
寄存器值
MRS
R3
,
SPSR
@
读取本模式下的
SPSR
值
MOV
R4
,
LR
@
保存回跳寄存器
LR
AND
R1
,
R3
,
#
CPSR_MASK_MODE
@
Interrupted
mode
获取中断模式
CMP
R1
,
#
CPSR_USER_MODE
@
User
mode
是否为用户模式
BNE
OsKernelSVCHandler
@
Branch
if
not
user
mode
非用户模式下跳转
@
当为用户模式时
,
获取
SP
和
LR
寄出去值
@
we
enter
from
user
mode
,
we
need
get
the
values
of
USER
mode
r13
(
sp
)
and
r14
(
lr
)
.
@
stmia
with
^
will
return
the
user
mode
registers
(
provided
that
r15
is
not
in
the
register
list
)
.
MOV
R0
,
SP
STMFD
SP
!,
{
R3
}
@
Save
the
CPSR
ADD
R3
,
SP
,
#(
4
*
17
)
@
Offset
to
pc
/
cpsr
storage
STMFD
R3
!,
{
R4
}
@
Save
the
CPSR
and
r15
(
pc
)
STMFD
R3
,
{
R13
,
R14
}^
@
Save
user
mode
r13
(
sp
)
and
r14
(
lr
)
MOV
R0
,
SP
@
获取
SP
值
,
R0
将作为
OsArmA32SyscallHandle
的参数
STMFD
SP
!,
{
R3
}
@
Save
the
CPSR
入栈保存
CPSR
值
ADD
R3
,
SP
,
#(
4
*
17
)
@
Offset
to
pc
/
cpsr
storage
跳到
PC
/
CPSR
存储位置
STMFD
R3
!,
{
R4
}
@
Save
the
CPSR
and
r15
(
pc
)
保存
LR
寄存器
STMFD
R3
,
{
R13
,
R14
}^
@
Save
user
mode
r13
(
sp
)
and
r14
(
lr
)
保存用户模式下的
SP
和
LR
寄存器
SUB
SP
,
SP
,
#
4
PUSH_FPU_REGS
R1
MOV
FP
,
#
0
@
Init
frame
pointer
CPSIE
I
CPSIE
I
@
开中断
,
表明在系统调用期间可响应中断
BLX
OsArmA32SyscallHandle
/*
处理系统调用
*/
CPSID
I
CPSID
I
@
执行后续指令前必须先关中断
POP_FPU_REGS
R1
ADD
SP
,
SP
,#
4
LDMFD
SP
!,
{
R3
}
@
Fetch
the
return
SPSR
MSR
SPSR_cxsf
,
R3
@
Set
the
return
mode
SPSR
POP_FPU_REGS
R1
@
弹出
FP
值给
R1
ADD
SP
,
SP
,#
4
@
定位到保存旧
SPSR
值的位置
LDMFD
SP
!,
{
R3
}
@
Fetch
the
return
SPSR
弹出旧
SPSR
值
MSR
SPSR_cxsf
,
R3
@
Set
the
return
mode
SPSR
恢复该模式下的
SPSR
值
@
we
are
leaving
to
user
mode
,
we
need
to
restore
the
values
of
USER
mode
r13
(
sp
)
and
r14
(
lr
)
.
@
ldmia
with
^
will
return
the
user
mode
registers
(
provided
that
r15
is
not
in
the
register
list
)
LDMFD
SP
!,
{
R0
-
R12
}
LDMFD
SP
,
{
R13
,
R14
}^
@
Restore
user
mode
R13
/
R14
ADD
SP
,
SP
,
#(
2
*
4
)
LDMFD
SP
!,
{PC}
^
@
Return
to
user
LDMFD
SP
!,
{
R0
-
R12
}
@
恢复
R0
-
R12
寄存器
LDMFD
SP
,
{
R13
,
R14
}^
@
Restore
user
mode
R13
/
R14
恢复用户模式的
R13
/
R14
寄存器
ADD
SP
,
SP
,
#(
2
*
4
)
@
定位到保存旧
PC
值的位置
LDMFD
SP
!,
{PC}
^
@
Return
to
user
弹出值给
PC
寄存器
OsKernelSVCHandler
:
ADD
R0
,
SP
,
#(
4
*
16
)
...
...
arch/arm/arm/src/los_hwi.c
浏览文件 @
f5946584
...
...
@@ -215,14 +215,14 @@ STATIC UINT32 OsHwiDelNoShared(HWI_HANDLE_T hwiNum)
{
UINT32
intSave
;
HWI_LOCK
(
intSave
);
HWI_LOCK
(
intSave
);
//申请硬中断自旋锁
g_hwiForm
[
hwiNum
].
pfnHook
=
NULL
;
//回调函数直接NULL
if
(
g_hwiForm
[
hwiNum
].
uwParam
)
{
//如有参数
(
VOID
)
LOS_MemFree
(
m_aucSysMem0
,
(
VOID
*
)
g_hwiForm
[
hwiNum
].
uwParam
);
//释放内存
}
g_hwiForm
[
hwiNum
].
uwParam
=
0
;
//NULL
HWI_UNLOCK
(
intSave
);
HWI_UNLOCK
(
intSave
);
//释放硬中断自旋锁
return
LOS_OK
;
}
//创建一个不支持共享的中断
...
...
@@ -258,7 +258,7 @@ STATIC UINT32 OsHwiDelShared(HWI_HANDLE_T hwiNum, const HwiIrqParam *irqParam)
UINT32
intSave
;
HWI_LOCK
(
intSave
);
hwiForm
=
&
g_hwiForm
[
hwiNum
];
hwiForm
=
&
g_hwiForm
[
hwiNum
];
//从全局注册的中断向量表中获取中断项
hwiFormtmp
=
hwiForm
;
if
((
hwiForm
->
uwParam
&
IRQF_SHARED
)
&&
((
irqParam
==
NULL
)
||
(
irqParam
->
pDevId
==
NULL
)))
{
...
...
arch/arm/arm/src/startup/reset_vector_mp.S
浏览文件 @
f5946584
...
...
@@ -96,10 +96,10 @@
.
global
__exception_handlers
__exception_handlers
:
/*
/
*
//
假设:
ROM
代码在硬件重置地址有这些向量
*
Assumption
:
ROM
code
has
these
vectors
at
the
hardware
reset
address
.
*
A
simple
jump
removes
any
address
-
space
dependencies
[
i
.
e
.
safer
]
*/
*/
//一个简单的跳转将删除任何地址空间依赖关系
b
reset_vector
b
_osExceptUndefInstrHdl
b
_osExceptSwiHdl
...
...
kernel/base/core/los_task.c
浏览文件 @
f5946584
...
...
@@ -436,7 +436,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
UINT32
ret
;
TSK_INIT_PARAM_S
taskInitParam
;
Percpu
*
perCpu
=
OsPercpuGet
();
//获取CPU信息
UINT32
*
idleTaskID
=
&
perCpu
->
idleTaskID
;
UINT32
*
idleTaskID
=
&
perCpu
->
idleTaskID
;
//指定CPU的空闲任务
(
VOID
)
memset_s
((
VOID
*
)(
&
taskInitParam
),
sizeof
(
TSK_INIT_PARAM_S
),
0
,
sizeof
(
TSK_INIT_PARAM_S
));
//任务初始参数清0
taskInitParam
.
pfnTaskEntry
=
(
TSK_ENTRY_FUNC
)
OsIdleTask
;
//入口函数指定idle
...
...
@@ -449,7 +449,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
#endif
ret
=
LOS_TaskCreate
(
idleTaskID
,
&
taskInitParam
);
//创建task并申请调度,
OS_TCB_FROM_TID
(
*
idleTaskID
)
->
taskStatus
|=
OS_TASK_FLAG_SYSTEM_TASK
;
//设置task状态为系统任务,系统任务运行在内核态.
//这里说下系统任务有哪些?比如: idle,swtmr(软时钟)等等
//这里说下系统任务有哪些?比如: idle,swtmr(软时钟)
,资源回收
等等
return
ret
;
}
...
...
@@ -457,7 +457,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
* Description : get id of current running task.
* Return : task id
*/
LITE_OS_SEC_TEXT
UINT32
LOS_CurTaskIDGet
(
VOID
)
LITE_OS_SEC_TEXT
UINT32
LOS_CurTaskIDGet
(
VOID
)
//获取当前任务的ID
{
LosTaskCB
*
runTask
=
OsCurrTaskGet
();
...
...
@@ -506,10 +506,10 @@ LITE_OS_SEC_TEXT VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status)
LosProcessCB
*
runProcess
=
NULL
;
LosTaskCB
*
mainTask
=
NULL
;
SCHEDULER_LOCK
(
intSave
);
SCHEDULER_LOCK
(
intSave
);
//禁止调度
runProcess
=
OS_PCB_FROM_PID
(
taskCB
->
processID
);
//通过任务ID拿到进程实体
mainTask
=
OS_TCB_FROM_TID
(
runProcess
->
threadGroupID
);
//通过线程组ID拿到主任务实体,threadGroupID就是等于mainTask的taskId
SCHEDULER_UNLOCK
(
intSave
);
//这个是在线程组创建的时候指定的.
mainTask
=
OS_TCB_FROM_TID
(
runProcess
->
threadGroupID
);
//通过线程组ID拿到主任务实体,threadGroupID就是等于mainTask的taskId
,这个是在线程组创建的时候指定的.
SCHEDULER_UNLOCK
(
intSave
);
//恢复调度
if
(
mainTask
==
taskCB
)
{
//如果参数任务就是主任务
OsTaskExitGroup
(
status
);
//task退出线程组
}
...
...
@@ -521,8 +521,8 @@ LITE_OS_SEC_TEXT VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status)
return
;
}
if
(
taskCB
->
taskStatus
&
OS_TASK_FLAG_DETACHED
)
{
//任务
贴有分离的
标签
(
VOID
)
OsTaskDeleteUnsafe
(
taskCB
,
status
,
intSave
);
//任务要over了,
走起释放占用的资源的流程
if
(
taskCB
->
taskStatus
&
OS_TASK_FLAG_DETACHED
)
{
//任务
状态是否有分离
标签
(
VOID
)
OsTaskDeleteUnsafe
(
taskCB
,
status
,
intSave
);
//任务要over了,
释放占用的资源
}
OsTaskJoinPostUnsafe
(
taskCB
);
//退出前唤醒跟自己绑在一块的任务
...
...
@@ -546,8 +546,8 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
* from interrupt and other cores. release task spinlock and enable
* interrupt in sequence at the task entry.
*/
LOS_SpinUnlock
(
&
g_taskSpin
);
(
VOID
)
LOS_IntUnLock
();
LOS_SpinUnlock
(
&
g_taskSpin
);
//释放任务自旋锁
(
VOID
)
LOS_IntUnLock
();
//恢复中断
taskCB
=
OS_TCB_FROM_TID
(
taskID
);
taskCB
->
joinRetval
=
taskCB
->
taskEntry
(
taskCB
->
args
[
0
],
taskCB
->
args
[
1
],
//调用任务的入口函数
...
...
@@ -782,17 +782,17 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB,
LOS_ListInit
(
&
(
taskCB
->
msgListHead
));
//初始化 liteipc的消息链表
(
VOID
)
memset_s
(
taskCB
->
accessMap
,
sizeof
(
taskCB
->
accessMap
),
0
,
sizeof
(
taskCB
->
accessMap
));
#endif
taskCB
->
policy
=
(
initParam
->
policy
==
LOS_SCHED_FIFO
)
?
LOS_SCHED_FIFO
:
LOS_SCHED_RR
;
taskCB
->
taskStatus
=
OS_TASK_STATUS_INIT
;
taskCB
->
policy
=
(
initParam
->
policy
==
LOS_SCHED_FIFO
)
?
LOS_SCHED_FIFO
:
LOS_SCHED_RR
;
//调度模式
taskCB
->
taskStatus
=
OS_TASK_STATUS_INIT
;
//任务初始状态
if
(
initParam
->
uwResved
&
OS_TASK_FLAG_DETACHED
)
{
//分离模式 代表任务与其他任务的关系
taskCB
->
taskStatus
|=
OS_TASK_FLAG_DETACHED
;
taskCB
->
taskStatus
|=
OS_TASK_FLAG_DETACHED
;
//任务状态贴上分离标签
}
else
{
//参与模式
LOS_ListInit
(
&
taskCB
->
joinList
);
taskCB
->
taskStatus
|=
OS_TASK_FLAG_PTHREAD_JOIN
;
taskCB
->
taskStatus
|=
OS_TASK_FLAG_PTHREAD_JOIN
;
//任务状态贴上联合标签
}
taskCB
->
futex
.
index
=
OS_INVALID_VALUE
;
LOS_ListInit
(
&
taskCB
->
lockList
);
LOS_ListInit
(
&
taskCB
->
lockList
);
//初始化互斥锁链表
}
//任务初始化
LITE_OS_SEC_TEXT_INIT
STATIC
UINT32
OsTaskCBInit
(
LosTaskCB
*
taskCB
,
const
TSK_INIT_PARAM_S
*
initParam
,
...
...
kernel/base/include/los_process_pri.h
浏览文件 @
f5946584
...
...
@@ -80,7 +80,7 @@ typedef struct ProcessCB {
CHAR
processName
[
OS_PCB_NAME_LEN
];
/**< Process name */
//进程名称
UINT32
processID
;
/**< process ID = leader thread ID */
//进程ID,由进程池分配,范围[0,64]
UINT16
processStatus
;
/**< [15:4] process Status; [3:0] The number of threads currently
running in the process */
//这里设计很巧妙.用一个
16
表示了两层逻辑 数量和状态,点赞!
running in the process */
//这里设计很巧妙.用一个
变量
表示了两层逻辑 数量和状态,点赞!
UINT16
priority
;
/**< process priority */
//进程优先级
UINT16
policy
;
/**< process policy */
//进程的调度方式,默认抢占式
UINT16
timeSlice
;
/**< Remaining time slice */
//进程时间片,默认2个tick
...
...
zzz/git/push.sh
浏览文件 @
f5946584
git add
-A
git commit
-m
'硬中断代码注释
百万汉字注解 + 百篇博客分析 -> 挖透鸿蒙内核源码
git commit
-m
'系统调用由软中断实现,对其汇编代码注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://weharmony.gitee.io
'
git push origin master
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录