IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 鸿蒙微内核 LiteOS -A 汇编代码 -> 正文阅读

[系统运维]鸿蒙微内核 LiteOS -A 汇编代码

流程图地址:?https://gitee.com/lwleen/liteos

水平有限, 仅供参考? ? 一定要以实际的开源代码为准.

系统调用(软中断?SVC管理模式)

概述:将runtask寄存器完整的保存下来  系统调用处理   跳转到信号处理函数
     示例: sys_call3(__NR_execve, "/bin/init", 0, 0)  -------引发一个SVC异常
           传入参数----- R7中是调用号__NR_execve    R0 R1 R2 R3是参数

_osExceptSwiHdl:    @此函数是内核函数, SVC管理模式异常,使用内核堆栈---SVC堆栈
  SRSFD #CPSR_SVC_MODE!          @ CPSR_SVC_MODE = 0x13  保存 CPSR PC 入SVC的堆栈
  STMFD SP!, {R0-R3, R12, LR}    @将R0-R3 R12和 LR 入栈
  STMFD SP, {R13, R14}^          @入栈用户应用的R13 R14(ULR USP)
  SUB   SP, SP, #(4 * 4)         @修改位置,SP指向 -> reserved2
  STR   R7, [SP, #0]             @将R7中调用号保存到reserved2
@--------- TaskContext 结构体填充一半了----------------------

#ifdef LOSCFG_KERNEL_SYSCALL
   LDR  R3, [SP, #(11 * 4)]     @赋值R3 = regCPSR值
   AND  R1, R3, #CPSR_MASK_MODE @R3与后,值存到R1
   CMP  R1, #CPSR_USER_MODE     
   BNE  _osKernelSVCHandler     @(ARM处于特权模式)跳转 sp->reserved2
   @判断 此时 ARM 处于USER用户模式
   CMP  R7, #119                @ 119 == 系统调用号 __NR_sigreturn     
   BNE  _osIsSyscall            @R7中的调用号 != 119  sp->reserved2
   MOV  R0, SP
   @-------传参数 R0 = SP    sp->reserved2
   BLX  OsRestorSignalContext   @@@@@
   @-------返回参数 R0 = OsCurrTaskGet()->sig.sigContext
   MOV  SP, R0                  @堆栈 SP -> sig.sigContext
   B    _osSyscallReturn

_osIsSyscall:                  @R7中的调用号不是119  sp->reserved2
   STMFD SP!, {R4-R11}         @入栈R4-R11
   PUSH_FPU_REGS R1            @保存浮点寄存器FPU
@--------- TaskContext 结构体填充完成----------------------
   MOV   R0, SP                @R0指向结构体TaskContext地址
   MOV   FP, #0
   CPSIE   I                   @开中断
   @--------传参R0指向结构体TaskContext地址
   BLX     OsArmA32SyscallHandle       @系统调用入口
   @--------传参R0里保存有系统调用返回值 
   CPSID   I                      @关中断
   POP_FPU_REGS R1                @弹出浮点寄存器
   LDMFD   SP!, {R4-R11}          @出栈恢复R4-R11寄存器
   MOV     R0, SP                 @赋值R0 = SP ->reserved2
   SUB     SP, SP, #(12 * 4)      @栈顶增加空间sizeof(TaskContext)/2
   MOV     R1, SP                 @ R1 = new SP
   @----传参 R0 =SP ->reserved2   R1 =new SP ------------
   BLX     OsSaveSignalContext    @@@@@
   @-------返回参数 R0 = new SP 里面PC = sigHandler 信号处理函数
   MOV     SP, R0                 @堆栈 SP -> new SP

_osSyscallReturn:  @系统调用结束,下面是堆栈 SP -> new SP 的情况
   LDR     R7, [SP, #0]           @赋值R7 = [SP->reserved2]里调用号 
   ADD     SP, SP, #(2 * 4)       @SP + 2
   LDMFD   SP, {R13, R14}^        @恢复用户的 R13 R14(USP ULR) 
   ADD     SP, SP, #(2 * 4)       @SP + 2
   LDMFD   SP!, {R0-R3, R12, LR}  @恢复 R0-R3 R12 LR
   RFEIA   SP!          @弹出恢复PC CPSR  返回运行的是信号处理函数sigHandle
                        @信号处理完成后 再次发起系统调用 __NR_sigreturn
                        @这个系统调用__NR_sigreturn会恢复原应用运行
_osKernelSVCHandler:    
#endif               @ARM处于特权模式 sp->reserved2
    MOV     R0, #0               @ R0 = 0
    STR     R0, [SP, #0]         @ sp->reserved2 赋值 0
    STR     R0, [SP, #4]         @ sp->reserved1 赋值 0
    STMFD   SP!, {R4-R11}        @入栈保存R4-R11
    MOV     R0, #OS_EXCEPT_SWI   @ R0 放入参数 OS_EXCEPT_SWI   
    @传参数 R0 = OS_EXCEPT_SWI   
    B       _osExceptDispatch    @程序跳转   
            @调用 OsExcHandleEntry() 异常模式处理 打印系统信息

系统信号相关函数

信号处理函数  在当前进程中 UINTPTR sigHandler = OsCurrProcessGet()->sigHandler()
信号控制块    在当前线程中 sig_cb *sigcb = OsCurrTaskGet()->sig


@-----传入参数  sp->reserved2
//这个函数由系统调用为__NR_sigreturn 时执行一次
VOID *OsRestorSignalContext(VOID *sp){  @@@@@       
   如果 sigcb->count == 1  否则就错误
   sigcb->count = 0
   process->sigShare = 0
   return sigcb->sigContext  
   //用R0返回参数 = OsCurrTaskGet()->sig.sigContext
}   



@----传入参数 R0 =SP ->reserved2   R1 =new SP
VOID *OsSaveSignalContext(VOID *sp, VOID *newSp){  @@@@@
    如果 sigcb->count == 0   否则退出
    sigcb->sigContext = sp        //保存 SP
    OsInitSignalContext(){
        复制 SP内容 到 new SP
        如图所示
    }
    sigcb->count++
    //用R0返回参数 = new SP
}


通用中断(IRQ 切换到?SVC)

概述: 调用中断处理函数  处理任务停止信号  处理核间调度 
      示例: 核间中断
OsIrqHandler:           @此函数由中断异常模式执行
  SUB    LR, LR, #4     @记录译码指令地址,以防切换过程丢失指令
  SRSFD  #0x13!         @保存 CPSR PC 入SVC的堆栈
  CPSID  i, #0x13                @关中断  切换到SVC 模式
  STMFD  SP!, {R0-R3, R12, LR}   @将R0-R3 R12和 LR 入栈
  STMFD  SP, {R13, R14}^         @入栈用户应用的R13 R14(ULR USP)
  SUB    SP, SP, #(4 * 4)        @修改位置,SP指向 ->reserved2
  STR    R4, [SP, #0]            @R4中的值保存到reserved2
@---- IrqContext 结构体填充完成--保存runtask的寄存器-------
   PUSH_FPU_REGS   R0            @保存浮点寄存器
   MOV    R4, SP                 @保存SP->IrqContex 指针到R4  
   @下条指令处理多核CPU
   EXC_SP_SET __svc_stack_top,OS_EXC_SVC_STACK_SIZE,R1,R2
   BLX    HalIrqHandler          @通用中断处理入口
   MOV    SP, R4                 @从R4恢复 SP->IrqContex 指针

   BLX   OsTaskProcSignal
   BLX   OsSchedIrqEndCheckNeedSched
   POP_FPU_REGS R0               @恢复浮点寄存器
   LDR   R4, [SP, #0]          @赋值R4=[SP->reserved2]里的值

#ifdef LOSCFG_KERNEL_VM
    LDR     R3, [SP, #(11 * 4)]   @赋值R3 = regCPSR里的值
    AND     R1, R3, #CPSR_MASK_MODE
    CMP     R1, #CPSR_USER_MODE   @判断是否是用户模式
    BNE     1f                    @特权模式跳转 堆栈sp->reserved2
    @判断 这里 (ARM处于用户模式)
    MOV     R0, SP                @赋值 R0 = SP 指针
    STR     R7, [SP, #0]          @将 R7 里的值保存到 [SP->reserved2]
    SUB     SP, SP, #(12 * 4)     @栈顶增加空间 sizeof(IrqContext) 
    MOV     R1, SP          
    @----传入参数 R0 =SP ->reserved2   R1 =new SP
    BLX     OsSaveSignalContext  @@@@
    @-------返回参数 R0 = new SP 里面PC = sigHandler 信号处理函数
    MOV     SP, R0                @堆栈 SP -> new SP       
1:
#endif       @下面是 堆栈 SP -> new SP 的情况                    
    ADD     SP, SP, #(2 * 4)      @ SP +2
    LDMFD   SP, {R13, R14}^       @恢复用户的 R13 R14(USP ULR)
    ADD     SP, SP, #(2 * 4)      @ SP +2
    LDMFD   SP!, {R0-R3, R12, LR} @恢复 R0-R3 R12 LR
    RFEIA   SP!       @弹出恢复PC CPSR  返回运行的是信号处理函数sigHandle
                      @信号处理完成后 再次发起系统调用 __NR_sigreturn
                      @这个系统调用__NR_sigreturn会恢复原应用运行

滴答中断(IRQ)----核间中断-----调度----相关函数

触发调度过程:
滴答中断处理函数OsTickHandler , 检查 OsPercpuGet()->taskSortLink 如果有到时的任务到时, 调用
LOS_MpSchedule(OS_MP_CPU_ALL){
    HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE){
       写gic控制器的 GICD_SGIR 寄存器 
       触发核间中断 LOS_MP_IPI_SCHEDULE = 1 为中断号
    }
}
----------------------------------
核间中断处理过程
----------------------------------
进入中断异常总入口 OsIrqHandler:  

1 HalIrqHandler查询向量表g_hwiForm[]找到LOS_MP_IPI_SCHEDULE的处理函数, 调用
VOID OsMpScheduleHandler(VOID){
   OsPercpuGet()->schedFlag = INT_PEND_RESCH; //CPU私有变量调度标志
}

2 调用
VOID OsTaskProcSignal(VOID){
    LosTaskCB *runTask = OsCurrTaskGet();
    检查 runTask->signal  标志
            SIGNAL_KILL      结束当前运行任务
            SIGNAL_SUSPEND   要求任务挂起停止
            SIGNAL_AFFI      更换CPU  亲和度 
}

3 调用 (处理核间调度)
VOID OsSchedIrqEndCheckNeedSched(VOID){
     处理当前任务的时间片 LosTaskCB *runTask = OsCurrTaskGet()      
    
     如果 OsPercpuGet()->schedFlag == INT_PEND_RESCH
           将runTask 加入调度器里的就绪链表
           查找最高优先级任务 LosTaskCB *newTask = OsGetTopTask()
     
     如果 runTask != newTask
     OsSchedTaskSwicth(){
          OsTaskSchedule(newTask,runTask) 汇编代码:切换任务上下文  
     }
}



调度---切换任务堆栈

概述: 将runtask的寄存器其压入堆栈. 弹出恢复newtask堆栈值后运行

LosTaskCB 结构体定义时, 第一个成员就是堆栈指针 VOID *stackPointer
传入参数为LosTaskCB ---- R0 = newtask  R1 = runtask    每个寄存器值4字节

OsTaskSchedule:         
    MRS      R2, CPSR     @将CPSR内容存入 R2
    STMFD    SP!, {R2}    @将CPSR压入 run task 的栈堆
    STMFD    SP!, {LR}    @将LR压入 
    STMFD    SP!, {LR}    @将LR压入 
    STMFD    SP!, {R12}   @将R12压入
    SUB      SP, SP, #(8 * 4)  @栈顶增加8个寄存器空间 SP -8 
    STMFD    SP!, {R4-R11}     @将R4-R11入栈
    PUSH_FPU_REGS   R2    @入栈fpu寄存器
@---- TaskContext 结构体填充完成--保存runtask的寄存器-------------------
    STR     SP, [R1]      @保存堆栈指针 SP 到 runtask ->stackPointer

OsTaskContextLoad:        @切换到新任务  下面开始加载新SP 并弹出内容
    CLREX                 @清除ldrex指令的标记
    LDR     SP, [R0]      @加载堆栈 SP = new task ->stackPointer
    POP_FPU_REGS    R2    @恢复 new task 的fpu浮点寄存器
    LDMFD   SP!, {R4-R11}         @恢复 new task 的R4 - R11
    LDR     R3, [SP, #(11 * 4)]   @赋值R3 =  new task堆栈中的CPSR
    AND     R0, R3, #CPSR_MASK_MODE 
    CMP     R0, #CPSR_USER_MODE
    BNE     OsKernelTaskLoad    @判断new task为内核任务 此时SP->reserved2 
    @判断 新任务newtask 是用户模式(ARM处于USER模式) 
    @下面为 new task 为新任务  此时SP->reserved2
    MVN     R2, #CPSR_INT_DISABLE @取反后放入R2
    @此时R3 = new task堆栈中的CPSR
    AND     R3, R3, R2            @R3中为CPSR ,与操作后放入R3
    STR     R3, [SP, #(11 * 4)]   @处理后的CPSR值重新保存到 new task 堆栈
#ifdef LOSCFG_KERNEL_SMP
    BL      OsSchedToUserReleaseLock  @调用C函数
#endif                            @此时SP->reserved2
    ADD     SP, SP, #(2 * 4)      @SP跳过 reserved 这两个寄存器
    LDMFD   SP, {R13, R14}^    @恢复USP ULR但SP指针未改变(带!才会改变指针)
    ADD     SP, SP, #(2 * 4)      @SP跳过 R13 R14 (USP ULR)这两个寄存器
    LDMFD   SP!, {R0-R3, R12, LR} @弹出恢复 R0-R3 R12 LR
    RFEIA   SP!                   @弹出恢复PC CPSR  即返回运行(new task)
    @ 上面 new task 所有寄存器已从新堆栈中弹出恢复

OsKernelTaskLoad:     @判断 new task 为内核任务(ARM处于特权模式)此时SP->reserved2
    ADD     SP, SP, #(4 * 4)      @跳过堆栈顶4个寄存器
    LDMFD   SP!, {R0-R3, R12, LR} @恢复 R0-R3 R12 LR
    RFEIA   SP!                   @弹出恢复PC CPSR  即返回运行(new task)

流程图内容

?

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 11:10:24  更:2021-08-02 11:11:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/5 4:21:10-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码