Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
鸿蒙内核源码分析
注释鸿蒙内核源码
提交
4cf40f80
注释鸿蒙内核源码
项目概览
鸿蒙内核源码分析
/
注释鸿蒙内核源码
通知
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 搜索 >>
提交
4cf40f80
编写于
3月 01, 2021
作者:
鸿蒙内核源码分析
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
硬中断汇编代码注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://weharmony.gitee.io
上级
68e75446
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
56 addition
and
52 deletion
+56
-52
arch/arm/arm/include/arch_config.h
arch/arm/arm/include/arch_config.h
+4
-4
arch/arm/arm/src/los_dispatch.S
arch/arm/arm/src/los_dispatch.S
+37
-37
arch/arm/arm/src/los_exc.c
arch/arm/arm/src/los_exc.c
+1
-1
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
+1
-1
arch/arm/arm/src/startup/reset_vector_mp.S
arch/arm/arm/src/startup/reset_vector_mp.S
+6
-6
kernel/base/sched/sched_sq/los_sched.c
kernel/base/sched/sched_sq/los_sched.c
+5
-1
zzz/git/push.sh
zzz/git/push.sh
+1
-1
未找到文件。
arch/arm/arm/include/arch_config.h
浏览文件 @
4cf40f80
...
...
@@ -77,12 +77,12 @@ MRS{条件} 通用寄存器,程序状态寄存器(CPSR 或SPSR)
MRS R0,SPSR @传送SPSR 的内容到R0
@MRS指令是唯一可以直接读取CPSR和SPSR寄存器的指令
SPSR
程序状态保护寄存器,
每一种模式下都有一个状态寄存器SPSR,用于保存CPSR的状态,
SPSR
(saved program status register)程序状态保存寄存器.
每一种模式下都有一个状态寄存器SPSR,用于保存CPSR的状态,
以便异常返回后恢复异常发生时的工作状态。用户模式和系统模式不是异常状态,
所以没有SPSR,在这两种模式下访问SPSR,将产生不可预知的后果。
1、SPSR 为 CPSR 中断时刻的副本,退出中断后,将SPSR中数据恢复到CPSR中。
2、用户模式和系统模式下SPSR不可用
。
2、用户模式和系统模式下SPSR不可用
,所以SPSR寄存器只有5个
******************************************************************************/
#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 中断
...
...
@@ -99,7 +99,7 @@ SPSR
/* Define exception type ID */
//ARM处理器一共有7种工作模式,除了用户和系统模式其余都叫异常工作模式
#define OS_EXCEPT_RESET 0x00 //重置功能,例如:开机就进入CPSR_SVC_MODE模式
#define OS_EXCEPT_UNDEF_INSTR 0x01 //未定义的异常,就是others
#define OS_EXCEPT_SWI 0x02 //软
件定时器
中断
#define OS_EXCEPT_SWI 0x02 //软中断
#define OS_EXCEPT_PREFETCH_ABORT 0x03 //预取异常(取指异常), 指令三步骤: 取指,译码,执行,
#define OS_EXCEPT_DATA_ABORT 0x04 //数据异常
#define OS_EXCEPT_FIQ 0x05 //快中断异常
...
...
arch/arm/arm/src/los_dispatch.S
浏览文件 @
4cf40f80
...
...
@@ -109,16 +109,16 @@ ARM的指令系统中关于栈指令的内容比较容易引起迷惑,这是
.
global
ArchSpinUnlock
/*
自旋锁解锁
*/
.
global
OsSchedToUserSpinUnlock
/*
尚未实现
*/
/
*
@
note_why
为何要重新定义
OS_TASK_STATUS_RUNNING
?
*/
.
equ
OS_TASK_STATUS_RUNNING
,
0x0010
U
/*
.
equ
用于把常量值设置为可以在文本段中使用的符号
#
define
OS_TASK_STATUS_RUNNING
0x0010
U
*/
.
equ
OS_PERCPU_STRUCT_SIZE
,
0x28
U
.
equ
OS_PERCPU_TASK_LOCK_OFFSET
,
0x14
U
.
equ
OS_TASK_STATUS_RUNNING
,
0x0010
U
/*
.
equ
用于把常量值设置为可以在文本段中使用的符号
#
define
OS_TASK_STATUS_RUNNING
0x0010
U
*/
.
equ
OS_PERCPU_STRUCT_SIZE
,
0x28
U
/*
宏定义
#
define
OS_PERCPU_STRUCT_SIZE
0x28
U
*/
.
equ
OS_PERCPU_TASK_LOCK_OFFSET
,
0x14
U
/*
宏定义
#
define
OS_PERCPU_TASK_LOCK_OFFSET
0x14
U
*/
.
fpu
vfpv4
/*
.
fpu
@
note_why
尚未知这句话的含义
*/
/*
此宏用于对齐和不对齐8字节边界上的堆栈以符合
ABI
*/
/*
macros
to
align
and
unalign
the
stack
on
8
byte
boundary
for
ABI
compliance
*/
.
macro
STACK_ALIGN
,
reg
/*
栈对齐
*/
MOV
\
reg
,
sp
TST
SP
,
#
4
SUBEQ
SP
,
#
4
MOV
\
reg
,
sp
@
reg
=
sp
TST
SP
,
#
4
@
来检查是否设置了特定的位
SUBEQ
SP
,
#
4
@
表示相等时相减
PUSH
{
\
reg
}
.
endm
...
...
@@ -226,13 +226,13 @@ OsTaskContextLoad:
ADD
SP
,
SP
,
#
4
@
sp
=
sp
+
4
#
endif
/
*
R0
=
&
g_taskSpin
.
rawLock
*/
LDR
R0
,
=
g_taskSpin
BL
ArchSpinUnlock
LDR
R2
,
=
g_percpu
MRC
P15
,
0
,
R3
,
C0
,
C0
,
5
UXTB
R3
,
R3
MOV
R1
,
#
OS_PERCPU_STRUCT_SIZE
MLA
R3
,
R1
,
R3
,
R2
LDR
R0
,
=
g_taskSpin
@
R0
=
&
g_taskSpin
.
rawLock
将作为
ArchSpinUnlock
的参数
BL
ArchSpinUnlock
@
释放自旋锁
g_taskSpin
LDR
R2
,
=
g_percpu
MRC
P15
,
0
,
R3
,
C0
,
C0
,
5
@
获取
CPUID
给
R3
UXTB
R3
,
R3
@
字节被无符号扩展到
32
位(高
24
位清
0
)
MOV
R1
,
#
OS_PERCPU_STRUCT_SIZE
@
R1
=
sizeof
(
Percpu
)
MLA
R3
,
R1
,
R3
,
R2
@
R3
=
R1
*
R3
MOV
R2
,
#
0
STR
R2
,
[
R3
,
#
OS_PERCPU_TASK_LOCK_OFFSET
]
#
endif
...
...
@@ -254,18 +254,18 @@ 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
}
@
r0
-
r3
寄存器入栈
SUB
R0
,
SP
,
#(
4
*
4
)
STMFD
SP
,
{
R0
-
R3
}
@
r0
-
r3
寄存器入
irq
栈
SUB
R0
,
SP
,
#(
4
*
4
)
@
r0
=
sp
-
16
MRS
R1
,
SPSR
@
获取程序状态控制寄存器
MOV
R2
,
LR
MOV
R2
,
LR
@
r2
=
lr
/
*
disable
irq
,
switch
to
svc
mode
*/
@
超级用户模式
(
SVC
模式
)
,主要用于
SWI
(
软件中断
)
和
OS
(
操作系统
)
。
CPSID
i
,
#
0x13
@
切换到
SVC
模式
,
此处一切换
,
后续指令将入
SVC
的栈
@
CPSID
i
为关中断指令
,
对应的是
CPSIE
@
CPSID
i
为关中断指令
,
对应的是
CPSIE
/
*
push
spsr
and
pc
in
svc
stack
*/
STMFD
SP
!,
{
R1
,
R2
}
@
实际是将
SPSR
,
和
LR
入栈
,
入栈顺序为
R1
,
R2
,
SP
自增
STMFD
SP
,
{
LR
}
@
LR
再入栈
,
SP
不自增
...
...
@@ -275,14 +275,14 @@ OsIrqHandler: @硬中断处理
BNE
OsIrqFromKernel
@
中断不发生在用户模式下则跳转到
OsIrqFromKernel
/
*
push
user
sp
,
lr
in
svc
stack
*/
STMFD
SP
,
{
R13
,
R14
}^
STMFD
SP
,
{
R13
,
R14
}^
@
sp
和
LR
入
svc
栈
OsIrqFromKernel
:
@从内核发起中断
/
*
from
svc
not
need
save
sp
and
lr
*/
SUB
SP
,
SP
,
#(
2
*
4
)
/
*
from
svc
not
need
save
sp
and
lr
*/
@
svc
模式下发生的中断不需要保存
sp
和
lr
寄存器值
SUB
SP
,
SP
,
#(
2
*
4
)
@
申请
8
个栈空间
/
*
pop
r0
-
r3
f
or
m
irq
stack
*/
LDMFD
R0
,
{
R0
-
R3
}
/
*
pop
r0
-
r3
f
ro
m
irq
stack
*/
LDMFD
R0
,
{
R0
-
R3
}
@
出栈
/
*
push
caller
saved
regs
as
trashed
regs
in
svc
stack
*/
STMFD
SP
!,
{
R0
-
R3
,
R12
}
...
...
@@ -295,34 +295,34 @@ OsIrqFromKernel: @从内核发起中断
*
altered
in
interrupt
handlers
.
*/
PUSH_FPU_REGS
R0
#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK
#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK
@IRQ使用独立栈
PUSH
{
R4
}
MOV
R4
,
SP
EXC_SP_SET
__svc_stack_top
,
OS_EXC_SVC_STACK_SIZE
,
R1
,
R2
#
endif
/*
BLX
带链接和状态切换的跳转
*/
BLX
HalIrqHandler
/*
调用硬中断处理程序
,
无参
*/
BLX
HalIrqHandler
/*
调用硬中断处理程序
*/
#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK
#ifdef LOSCFG_IRQ_USE_STANDALONE_STACK @是否使用了独立的IRQ栈
MOV
SP
,
R4
POP
{
R4
}
#
endif
/
*
process
pending
signals
*/
BL
OsTaskProcSignal
/
*
process
pending
signals
*/
@
处理挂起信号
BL
OsTaskProcSignal
@
跳转至
C
代码
/
*
check
if
needs
to
schedule
*/
CMP
R0
,
#
0
BLNE
OsSchedPreempt
/
*
check
if
needs
to
schedule
*/
@
检查是否需要调度
CMP
R0
,
#
0
@
是否需要调度
,
R0
为参数保存值
BLNE
OsSchedPreempt
@
不相等
,
即
R0
非
0
,
一般是
1
MOV
R0
,
SP
MOV
R1
,
R7
BL
OsSaveSignalContextIrq
MOV
R0
,
SP
@
OsSaveSignalContextIrq
参数
1
来源
MOV
R1
,
R7
@
OsSaveSignalContextIrq
参数
2
来源
BL
OsSaveSignalContextIrq
@
跳转至
C
代码
/
*
restore
fpu
regs
*/
POP_FPU_REGS
R0
POP_FPU_REGS
R0
@
恢复
fpu
寄存器值
ADD
SP
,
SP
,
#
4
ADD
SP
,
SP
,
#
4
@
sp
=
sp
+
4
OsIrqContextRestore
:
@中断环境恢复
LDR
R0
,
[
SP
,
#(
4
*
7
)]
@
读取
SP
+
28
位置数据给
R0
...
...
arch/arm/arm/src/los_exc.c
浏览文件 @
4cf40f80
...
...
@@ -1108,7 +1108,7 @@ __attribute__((noinline)) VOID LOS_Panic(const CHAR *fmt, ...)
va_start
(
ap
,
fmt
);
UartVprintf
(
fmt
,
ap
);
va_end
(
ap
);
__asm__
__volatile__
(
"swi 0"
);
__asm__
__volatile__
(
"swi 0"
);
//触发断异常
}
/* stack protector */
...
...
arch/arm/arm/src/los_hw.c
浏览文件 @
4cf40f80
...
...
@@ -56,7 +56,7 @@ UINT64 g_cpuMap[LOSCFG_KERNEL_CORE_NUM] = {
LITE_OS_SEC_TEXT_INIT
VOID
OsTaskExit
(
VOID
)
{
// swi {cond} <immed_24>
__asm__
__volatile__
(
"swi 0"
);
//处理器产生软中断异常,swi指令的低24位存放的是0
}
//该指令可以产生SWI异常,ARM通过该指令
可以实现用户模式中对操作系统中特权模式的程序的调用,即系统调用实现的基础;
}
//该指令可以产生SWI异常,ARM通过该指令
从用户模式切到SVC模式.
#ifdef LOSCFG_GDB
STATIC
VOID
OsTaskEntrySetupLoopFrame
(
UINT32
)
__attribute__
((
noinline
,
naked
));
...
...
arch/arm/arm/src/los_hw_exc.S
浏览文件 @
4cf40f80
...
...
@@ -211,7 +211,7 @@ _osExceptSwiHdl: @软中断异常处理
LDMFD
SP
!,
{PC}
^
@
Return
to
user
弹出值给
PC
寄存器
OsKernelSVCHandler
:
ADD
R0
,
SP
,
#(
4
*
16
)
ADD
R0
,
SP
,
#(
4
*
16
)
@
R0
=
sp
+
64
MOV
R5
,
R0
STMFD
R0
!,
{
R4
}
@
Store
PC
STMFD
R0
!,
{
R4
}
...
...
arch/arm/arm/src/startup/reset_vector_mp.S
浏览文件 @
4cf40f80
...
...
@@ -100,7 +100,7 @@ __exception_handlers:
*
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
@
所有的异常中断入口组成了
reset
vector
b
reset_vector
@
开机代码
b
_osExceptUndefInstrHdl
@
异常处理之
CPU
碰到不认识的指令
b
_osExceptSwiHdl
@
异常处理之:软中断
b
_osExceptPrefetchAbortHdl
@
异常处理之:取指异常
...
...
@@ -136,7 +136,7 @@ reset_vector:
adr
r4
,
__exception_handlers
/*
r4
:
base
of
load
address
*/
@
r4
获得加载基地址
ldr
r5
,
=
SYS_MEM_BASE
/*
r5
:
base
of
physical
address
*/
@
r5
获得物理基地址
subs
r12
,
r4
,
r5
/*
r12
:
delta
of
load
address
and
physical
address
*/
@
r12
=
r4
-
r5
加载地址和物理地址的增量
beq
reloc_img_to_bottom_done
/*
if
we
load
image
at
the
bottom
of
physical
address
*/
beq
reloc_img_to_bottom_done
/*
if
we
load
image
at
the
bottom
of
physical
address
*/
@
物理地址底部加载镜像
/
*
we
need
to
relocate
image
at
the
bottom
of
physical
address
*/
ldr
r7
,
=
__exception_handlers
/*
r7
:
base
of
linked
address
(
or
vm
address
)
*/
...
...
@@ -229,9 +229,9 @@ warm_reset: @初始化CPU各异常工作模式环境
/
*
set
svc
stack
,
every
cpu
has
OS_EXC_SVC_STACK_SIZE
stack
*//*
设置每一个
SVC
栈
,
每个
CPU
都有独立的
SVC
栈
*/
ldr
r0
,
=
__svc_stack_top
@
栈底位置
,
注意这里虽然使用了
top
,
但实际是栈底
mov
r2
,
#
OS_EXC_SVC_STACK_SIZE
@
栈大小
mul
r2
,
r2
,
r12
@
定位到栈位置
,
CPU
SVC
栈是连在一块的
sub
r0
,
r0
,
r2
@
计算栈顶位置
,
使用
sub
也说明了栈底大于栈顶
mov
sp
,
r0
@
栈顶位置
mul
r2
,
r2
,
r12
@
定位到栈位置
,
CPU
SVC
栈是连在一块的
sub
r0
,
r0
,
r2
@
计算栈顶位置
,
使用
sub
也说明了栈底大于栈顶
mov
sp
,
r0
@
栈顶位置
/
*
enable
fpu
+
neon
*/
#ifndef LOSCFG_TEE_ENABLE
...
...
@@ -479,7 +479,7 @@ init_flag:
*/
.
section
".int_stack"
,
"wa"
,
%
nobits
.
align
3
@
申请对应的内存
空间
@
六种特权模式申请对应的栈运行
空间
__undef_stack
:
.
space
OS_EXC_UNDEF_STACK_SIZE
*
CORE_NUM
__undef_stack_top
:
...
...
kernel/base/sched/sched_sq/los_sched.c
浏览文件 @
4cf40f80
...
...
@@ -147,7 +147,11 @@ VOID OsSchedResched(VOID)
/* do the task context switch */
OsTaskSchedule
(
newTask
,
runTask
);
//切换任务上下文,注意OsTaskSchedule是一个汇编函数 见于 los_dispatch.s
}
//抢占式调度,调用极为频繁的函数
/******************************************************
抢占式调度函数
1.LOS_Schedule会判断是否发生硬件中断
2.硬件中断处理完成后由汇编调用: ..\arch\arm\arm\src\los_dispatch.S
******************************************************/
VOID
OsSchedPreempt
(
VOID
)
{
LosTaskCB
*
runTask
=
NULL
;
...
...
zzz/git/push.sh
浏览文件 @
4cf40f80
git add
-A
git commit
-m
'
开机的第一条汇编指令在哪里? 注解开机汇编代码部分
git commit
-m
'
硬中断汇编代码注解
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://weharmony.gitee.io
'
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录