0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

鸿蒙内核源码分析之中断管理

鸿蒙系统HarmonyOS 来源:my.oschina 作者:鸿蒙内核源码分析 2021-04-25 14:24 次阅读

编译开关

系列篇编译平台为hi3516dv300,整个工程可前往查看. 预编译处理过程会自动生成编译开关menuconfig.h,供编译阶段选择编译,可前往查看.

//....
#define LOSCFG_ARCH_ARM_VER "armv7-a"
#define LOSCFG_ARCH_CPU "cortex-a7"
#define LOSCFG_PLATFORM "hi3516dv300"
#define LOSCFG_PLATFORM_BSP_GIC_V2 1
#define LOSCFG_PLATFORM_ROOTFS 1
#define LOSCFG_KERNEL_CPPSUPPORT 1
#define LOSCFG_HW_RANDOM_ENABLE 1
#define LOSCFG_ARCH_CORTEX_A7 1
#define LOSCFG_DRIVERS_HDF_PLATFORM_RTC 1
#define LOSCFG_DRIVERS_HDF_PLATFORM_UART 1

中断初始化

hi3516dv300中断控制器选择了LOSCFG_PLATFORM_BSP_GIC_V2,对应代码为gic_v2.cGIC(Generic Interrupt Controller)是ARM公司提供的一个通用的中断控制器. 看这种代码因为涉及硬件部分,需要对照ARM中断控制器 gic_v2.pdf文档看.可前往地址下载查看.

//硬件中断初始化
VOID HalIrqInit(VOID)
{
    UINT32 i;

    /* set externel interrupts to be level triggered, active low. */	//将外部中断设置为电平触发,低电平激活
    for (i = 32; i < OS_HWI_MAX_NUM; i += 16) {
        GIC_REG_32(GICD_ICFGR(i / 16)) = 0;
    }

    /* set externel interrupts to CPU 0 */	//将外部中断设置为CPU 0
    for (i = 32; i < OS_HWI_MAX_NUM; i += 4) {
        GIC_REG_32(GICD_ITARGETSR(i / 4)) = 0x01010101;
    }

    /* set priority on all interrupts */	//设置所有中断的优先级
    for (i = 0; i < OS_HWI_MAX_NUM; i += 4) {
        GIC_REG_32(GICD_IPRIORITYR(i / 4)) = GICD_INT_DEF_PRI_X4;
    }

    /* disable all interrupts. */			//禁用所有中断。
    for (i = 0; i < OS_HWI_MAX_NUM; i += 32) {
        GIC_REG_32(GICD_ICENABLER(i / 32)) = ~0;
    }

    HalIrqInitPercpu();//初始化当前CPU中断信息

    /* enable gic distributor control */
    GIC_REG_32(GICD_CTLR) = 1; //使能分发中断寄存器,该寄存器作用是允许给CPU发送中断信号

#if (LOSCFG_KERNEL_SMP == YES)
    /* register inter-processor interrupt *///注册核间中断,啥意思?就是CPU各核直接可以发送中断信号
    //处理器间中断允许一个CPU向系统其他的CPU发送中断信号,处理器间中断(IPI)不是通过IRQ线传输的,而是作为信号直接放在连接所有CPU本地APIC的总线上。
    LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0);//注册唤醒CPU的中断处理函数
    LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0);//注册调度CPU的中断处理函数
    LOS_HwiCreate(LOS_MP_IPI_HALT, 0xa0, 0, OsMpScheduleHandler, 0);//注册停止CPU的中断处理函数
#endif
}
//给每个CPU core初始化硬件中断
VOID HalIrqInitPercpu(VOID)
{
    /* unmask interrupts */	//取消中断屏蔽
    GIC_REG_32(GICC_PMR) = 0xFF;

    /* enable gic cpu interface */	//启用gic cpu接口
    GIC_REG_32(GICC_CTLR) = 1;
}

解读

上来四个循环,是对中断控制器寄存器组的初始化,也就是驱动程序,驱动程序是配置硬件寄存器的过程.寄存器分通用和专用寄存器.下图为 gic_v2 的寄存器功能 ,这里对照代码和datasheet重点说下中断配置寄存器(GICD_ICFGRn)

pIYBAGCFCmaAJFGYAAGKGy09axQ942.png

以下是GICD_ICFGRn的介绍

The GICD_ICFGRs provide a 2-bit Int_config field for each interrupt supported by the GIC. This field identifies whether the corresponding interrupt is edge-triggered or level-sensitive

GICD_ICFGRs为GIC支持的每个中断提供一个2位配置字段。此字段标识相应的中断是边缘触发的还是电平触发的

0xC00 - 0xCFC GICD_ICFGRn RW IMPLEMENTATION DEFINED Interrupt Configuration Registers
#define GICD_ICFGR(n)                   (GICD_OFFSET + 0xc00 + (n) * 4) /* Interrupt Configuration Registers */		//中断配置寄存器

如此一个32位寄存器可以记录16个中断的信息,这也是代码中出现GIC_REG_32(GICD_ICFGR(i / 16))的原因.

GIC-v2支持三种类型的中断

PPI:私有外设中断(Private Peripheral Interrupt),是每个CPU私有的中断。最多支持16个PPI中断,硬件中断号从ID16~ID31。PPI通常会送达到指定的CPU上,应用场景有CPU本地时钟

SPI:公用外设中断(Shared Peripheral Interrupt),最多可以支持988个外设中断,硬件中断号从ID32~ID1019。

SGI:软件触发中断(Software Generated Interrupt)通常用于多核间通讯,最多支持16个SGI中断,硬件中断号从ID0~ID15。SGI通常在内核中被用作 IPI 中断(inter-processor interrupts),并会送达到系统指定的CPU上,函数的最后就注册了三个核间中断的函数.

typedef enum {//核间中断
    LOS_MP_IPI_WAKEUP,	//唤醒CPU
    LOS_MP_IPI_SCHEDULE,//调度CPU
    LOS_MP_IPI_HALT,	//停止CPU
} MP_IPI_TYPE;

中断相关的结构体

size_t g_intCount[LOSCFG_KERNEL_CORE_NUM] = {0};//记录每个CPUcore的中断数量 
HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM];//中断注册表 @note_why 用 form 来表示?有种写 HTML的感觉 :P
STATIC CHAR *g_hwiFormName[OS_HWI_MAX_NUM] = {0};//记录每个硬中断的名称 
STATIC UINT32 g_hwiFormCnt[OS_HWI_MAX_NUM] = {0};//记录每个硬中断的总数量
STATIC UINT32 g_curIrqNum = 0; //记录当前中断号
typedef VOID (*HWI_PROC_FUNC)(VOID); //中断函数指针
typedef struct tagHwiHandleForm {	
    HWI_PROC_FUNC pfnHook;	//中断处理函数
    HWI_ARG_T uwParam;		//中断处理函数参数
    struct tagHwiHandleForm *pstNext;	//节点,指向下一个中断,用于共享中断的情况
} HwiHandleForm;

typedef struct tagIrqParam {	//中断参数
    int swIrq;		//	软件中断
    VOID *pDevId;	//	设备ID
    const CHAR *pName;	//名称
} HwiIrqParam;

注册硬中断

/******************************************************************************
 创建一个硬中断
 中断创建,注册中断号、中断触发模式、中断优先级、中断处理程序。中断被触发时,
 handleIrq会调用该中断处理程序
******************************************************************************/
LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum,	//硬中断句柄编号 默认范围[0-127]
                                           HWI_PRIOR_T hwiPrio,		//硬中断优先级	
                                           HWI_MODE_T hwiMode,		//硬中断模式 共享和非共享
                                           HWI_PROC_FUNC hwiHandler,//硬中断处理函数
                                           HwiIrqParam *irqParam)	//硬中断处理函数参数
{
    UINT32 ret;

    (VOID)hwiPrio;
    if (hwiHandler == NULL) {//中断处理函数不能为NULL
        return OS_ERRNO_HWI_PROC_FUNC_NULL;
    }
    if ((hwiNum > OS_USER_HWI_MAX) || ((INT32)hwiNum < OS_USER_HWI_MIN)) {//中断数区间限制 [32,96]
        return OS_ERRNO_HWI_NUM_INVALID;
    }

#ifdef LOSCFG_NO_SHARED_IRQ	//不支持共享中断
    ret = OsHwiCreateNoShared(hwiNum, hwiMode, hwiHandler, irqParam);
#else
    ret = OsHwiCreateShared(hwiNum, hwiMode, hwiHandler, irqParam);
#endif
    return ret;
}
//创建一个共享硬件中断,共享中断就是一个中断能触发多个响应函数
STATIC UINT32 OsHwiCreateShared(HWI_HANDLE_T hwiNum, HWI_MODE_T hwiMode,
                                HWI_PROC_FUNC hwiHandler, const HwiIrqParam *irqParam)
{
    UINT32 intSave;
    HwiHandleForm *hwiFormNode = NULL;
    HwiHandleForm *hwiForm = NULL;
    HwiIrqParam *hwiParam = NULL;
    HWI_MODE_T modeResult = hwiMode & IRQF_SHARED;

    if (modeResult && ((irqParam == NULL) || (irqParam->pDevId == NULL))) {
        return OS_ERRNO_HWI_SHARED_ERROR;
    }

    HWI_LOCK(intSave);//中断自旋锁

    hwiForm = &g_hwiForm[hwiNum];//获取中断处理项
    if ((hwiForm->pstNext != NULL) && ((modeResult == 0) || (!(hwiForm->uwParam & IRQF_SHARED)))) {
        HWI_UNLOCK(intSave);
        return OS_ERRNO_HWI_SHARED_ERROR;
    }

    while (hwiForm->pstNext != NULL) {//pstNext指向 共享中断的各处理函数节点,此处一直撸到最后一个
        hwiForm = hwiForm->pstNext;//找下一个中断
        hwiParam = (HwiIrqParam *)(hwiForm->uwParam);//获取中断参数,用于检测该设备ID是否已经有中断处理函数
        if (hwiParam->pDevId == irqParam->pDevId) {//设备ID一致时,说明设备对应的中断处理函数已经存在了.
            HWI_UNLOCK(intSave);
            return OS_ERRNO_HWI_ALREADY_CREATED;
        }
    }

    hwiFormNode = (HwiHandleForm *)LOS_MemAlloc(m_aucSysMem0, sizeof(HwiHandleForm));//创建一个中断处理节点
    if (hwiFormNode == NULL) {
        HWI_UNLOCK(intSave);
        return OS_ERRNO_HWI_NO_MEMORY;
    }

    hwiFormNode->uwParam = OsHwiCpIrqParam(irqParam);//获取中断处理函数的参数
    if (hwiFormNode->uwParam == LOS_NOK) {
        HWI_UNLOCK(intSave);
        (VOID)LOS_MemFree(m_aucSysMem0, hwiFormNode);
        return OS_ERRNO_HWI_NO_MEMORY;
    }

    hwiFormNode->pfnHook = hwiHandler;//绑定中断处理函数
    hwiFormNode->pstNext = (struct tagHwiHandleForm *)NULL;//指定下一个中断为NULL,用于后续遍历找到最后一个中断项(见于以上 while (hwiForm->pstNext != NULL)处)
    hwiForm->pstNext = hwiFormNode;//共享中断

    if ((irqParam != NULL) && (irqParam->pName != NULL)) {
        g_hwiFormName[hwiNum] = (CHAR *)irqParam->pName;
    }

    g_hwiForm[hwiNum].uwParam = modeResult;

    HWI_UNLOCK(intSave);
    return LOS_OK;
}

解读

内核将硬中断进行编号,如:

  #define NUM_HAL_INTERRUPT_TIMER0        33
  #define NUM_HAL_INTERRUPT_TIMER1        33
  #define NUM_HAL_INTERRUPT_TIMER2        34
  #define NUM_HAL_INTERRUPT_TIMER3        34
  #define NUM_HAL_INTERRUPT_TIMER4        35
  #define NUM_HAL_INTERRUPT_TIMER5        35
  #define NUM_HAL_INTERRUPT_TIMER6        36
  #define NUM_HAL_INTERRUPT_TIMER7        36
  #define NUM_HAL_INTERRUPT_DMAC          60
  #define NUM_HAL_INTERRUPT_UART0         38
  #define NUM_HAL_INTERRUPT_UART1         39
  #define NUM_HAL_INTERRUPT_UART2         40
  #define NUM_HAL_INTERRUPT_UART3         41
  #define NUM_HAL_INTERRUPT_UART4         42
  #define NUM_HAL_INTERRUPT_TIMER         NUM_HAL_INTERRUPT_TIMER4
例如:时钟节拍处理函数OsTickHandler就是在HalClockInit中注册的
//硬时钟初始化
VOID HalClockInit(VOID)
{
  // ...
  (void)LOS_HwiCreate(NUM_HAL_INTERRUPT_TIMER, 0xa0, 0, OsTickHandler, 0);//注册OsTickHandler到中断向量表 
}
//节拍中断处理函数 ,鸿蒙默认10ms触发一次
  LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
  {
      UINT32 intSave;
      TICK_LOCK(intSave);//tick自旋锁
      g_tickCount[ArchCurrCpuid()]++;// 累加当前CPU核tick数
      TICK_UNLOCK(intSave);
      OsTimesliceCheck();//时间片检查
      OsTaskScan(); /* task timeout scan *///扫描超时任务 例如:delay(300)
      #if (LOSCFG_BASE_CORE_SWTMR == YES)
          OsSwtmrScan();//扫描定时器,查看是否有超时定时器,加入队列
      #endif
  } 

鸿蒙是支持中断共享的,在OsHwiCreateShared中,将函数注册到g_hwiForm中.中断向量完成注册后,就是如何触发和回调的问题.触发在鸿蒙内核源码分析(总目录)中断切换篇中已经讲清楚,触发是从底层汇编向上调用,调用的C函数就是HalIrqHandler

中断怎么触发的?

分两种情况:

通过硬件触发,比如按键,USB的插拔这些中断源向中断控制器发送电信号(高低电平触发或是上升/下降沿触发),中断控制器经过过滤后将信号发给对应的CPU处理,通过硬件改变PC和CPSR寄存值,直接跳转到中断向量(固定地址)执行.

  b   reset_vector            @开机代码
  b   _osExceptUndefInstrHdl 	@异常处理之CPU碰到不认识的指令
  b   _osExceptSwiHdl			@异常处理之:软中断
  b   _osExceptPrefetchAbortHdl	@异常处理之:取指异常
  b   _osExceptDataAbortHdl		@异常处理之:数据异常
  b   _osExceptAddrAbortHdl		@异常处理之:地址异常
  b   OsIrqHandler				@异常处理之:硬中断
  b   _osExceptFiqHdl				@异常处理之:快中断

通过软件触发,常见于核间中断的情况, 核间中断指的是几个CPU之间相互通讯的过程.以下为某一个CPU向其他CPU(可以是多个)发起让这些CPU重新调度LOS_MpSchedule的中断请求信号.最终是写了中断控制器的GICD_SGIR寄存器,这是一个由软件触发中断的寄存器.中断控制器会将请求分发给对应的CPU处理中断,即触发了OsIrqHandler.

//给参数CPU发送调度信号
  VOID LOS_MpSchedule(UINT32 target)//target每位对应CPU core 
  {
      UINT32 cpuid = ArchCurrCpuid();
      target &= ~(1U << cpuid);//获取除了自身之外的其他CPU
      HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE);//向目标CPU发送调度信号,核间中断(Inter-Processor Interrupts),IPI
  }
  //SGI软件触发中断(Software Generated Interrupt)通常用于多核间通讯
  STATIC VOID GicWriteSgi(UINT32 vector, UINT32 cpuMask, UINT32 filter)
  {
      UINT32 val = ((filter & 0x3) << 24) | ((cpuMask & 0xFF) << 16) |
                  (vector & 0xF);

      GIC_REG_32(GICD_SGIR) = val;//写SGI寄存器
  }
  //向指定核发送核间中断
  VOID HalIrqSendIpi(UINT32 target, UINT32 ipi)
  {
      GicWriteSgi(ipi, target, 0);
  }

中断统一处理入口函数 HalIrqHandler

//硬中断统一处理函数,这里由硬件触发,调用见于 ..\arch\arm\arm\src\los_dispatch.S
VOID HalIrqHandler(VOID)
{
    UINT32 iar = GIC_REG_32(GICC_IAR);//从中断确认寄存器获取中断ID号
    UINT32 vector = iar & 0x3FFU;//计算中断向量号
    /*
     * invalid irq number, mainly the spurious interrupts 0x3ff,
     * gicv2 valid irq ranges from 0~1019, we use OS_HWI_MAX_NUM
     * to do the checking.
     */
    if (vector >= OS_HWI_MAX_NUM) {
        return;
    }
    g_curIrqNum = vector;//记录当前中断ID号
    OsInterrupt(vector);//调用上层中断处理函数
    /* use orignal iar to do the EOI */
    GIC_REG_32(GICC_EOIR) = iar;//更新中断结束寄存器
}
VOID OsInterrupt(UINT32 intNum)//中断实际处理函数
{
    HwiHandleForm *hwiForm = NULL;
    UINT32 *intCnt = NULL;

    intCnt = &g_intCount[ArchCurrCpuid()];//当前CPU的中断总数量 ++
    *intCnt = *intCnt + 1;//@note_why 这里没看明白为什么要 +1

#ifdef LOSCFG_CPUP_INCLUDE_IRQ //开启查询系统CPU的占用率的中断
    OsCpupIrqStart();//记录本次中断处理开始时间
#endif

#ifdef LOSCFG_KERNEL_TICKLESS
    OsTicklessUpdate(intNum);
#endif
    hwiForm = (&g_hwiForm[intNum]);//获取对应中断的实体
#ifndef LOSCFG_NO_SHARED_IRQ	//如果没有定义不共享中断 ,意思就是如果是共享中断
    while (hwiForm->pstNext != NULL) { //一直撸到最后
        hwiForm = hwiForm->pstNext;//下一个继续撸
#endif
        if (hwiForm->uwParam) {//有参数的情况
            HWI_PROC_FUNC2 func = (HWI_PROC_FUNC2)hwiForm->pfnHook;//获取回调函数
            if (func != NULL) {
                UINTPTR *param = (UINTPTR *)(hwiForm->uwParam);
                func((INT32)(*param), (VOID *)(*(param + 1)));//运行带参数的回调函数
            }
        } else {//木有参数的情况
            HWI_PROC_FUNC0 func = (HWI_PROC_FUNC0)hwiForm->pfnHook;//获取回调函数
            if (func != NULL) {
                func();//运行回调函数
            }
        }
#ifndef LOSCFG_NO_SHARED_IRQ
    }
#endif
    ++g_hwiFormCnt[intNum];//中断号计数器总数累加

    *intCnt = *intCnt - 1;	//@note_why 这里没看明白为什么要 -1 
#ifdef LOSCFG_CPUP_INCLUDE_IRQ	//开启查询系统CPU的占用率的中断
    OsCpupIrqEnd(intNum);//记录中断处理时间完成时间
#endif
}
解读统一中断处理函数是一个通过一个中断号去找到注册函数的过程,分四步走:

第一步:取号,这号是由中断控制器的GICC_IAR寄存器提供的,这是一个专门保存当前中断号的寄存器.

第二步:从注册表g_hwiForm中查询注册函数,同时取出参数.

第三步:执行函数,也就是回调注册函数,分有参和无参两种情况func(...),在中断共享的情况下,注册函数会指向下一个注册函数pstNext,依次执行回调函数,这是中断共享的实现细节.

typedef struct tagHwiHandleForm {	
      HWI_PROC_FUNC pfnHook;	//中断处理函数
      HWI_ARG_T uwParam;		//中断处理函数参数
      struct tagHwiHandleForm *pstNext;	//节点,指向下一个中断,用于共享中断的情况
} HwiHandleForm;

第四步:销号,本次中断完成了就需要消除记录,中断控制器也有专门的销号寄存器GICC_EOIR

另外的是一些统一数据,每次中断号处理内核都会记录次数,和耗时,以便定位/跟踪/诊断问题.

编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    31

    文章

    5308

    浏览量

    119963
  • 中断控制器
    +关注

    关注

    0

    文章

    59

    浏览量

    9436
  • 鸿蒙系统
    +关注

    关注

    183

    文章

    2634

    浏览量

    66197
收藏 人收藏

    评论

    相关推荐

    【HarmonyOS】鸿蒙内核源码分析(调度机制篇)

    意义上所理解的线程呢。狭义上的后续有 鸿蒙内核源码分析(启动过程篇) 来说明。不知道大家有没有这种体会,学一个东西的过程中要接触很多新概念,尤其像 Java/android 的生态,概
    发表于 10-14 14:00

    鸿蒙内核源码分析:用通俗易懂的语言告诉你鸿蒙内核发生了什么?

    是:鸿蒙内核源码分析(内存概念篇)| 鸿蒙内核源码
    发表于 11-19 10:14

    鸿蒙内核源码分析源码注释篇):给HarmonyOS源码逐行加上中文注释

    都懂的概念去诠释或者映射一个他们从没听过的概念.说别人能听得懂的话这很重要!!! 一个没学过计算机知识的卖菜大妈就不可能知道内核的基本运作了吗? NO!,笔者在系列篇中试图用 鸿蒙源码分析
    发表于 11-19 10:32

    鸿蒙内核源码分析:给HarmonyOS源码逐行加上中文注释

    过计算机知识的卖菜大妈就不可能知道内核的基本运作了吗? NO!,笔者在系列篇中试图用 鸿蒙源码分析系列篇|张大爷系列故事【 CSDN | OSCHINA】 去构建这一层级的认知,希望能
    发表于 11-19 15:06

    鸿蒙源码分析系列(总目录) | 给HarmonyOS源码逐行加上中文注释

    同步更新。鸿蒙源码分析系列篇|- 鸿蒙内核源码分析
    发表于 11-20 11:24

    鸿蒙内核源码分析(内存概念篇) :手眼通天的虚拟内存

    分析(内存管理篇) | 鸿蒙内核源码分析(内存汇编篇) |鸿
    发表于 11-20 13:52

    鸿蒙内核源码分析(内存概念篇) :手眼通天的虚拟内存

    管理篇) | 鸿蒙内核源码分析(内存汇编篇) |鸿蒙内核
    发表于 11-20 16:30

    鸿蒙内核源码分析(必读篇):用故事说内核

    的工作原理!操作系统就是管理场馆和确保工作人员有序工作的系统解决方案商,外面公司只要提供个节目单,就能按节目单把这台戏演好给广大观众观看。有了这个故事垫底,鸿蒙内核源码
    发表于 11-23 10:15

    鸿蒙内核源码分析(调度机制篇):Task是如何被调度执行的

    本文分析任务调度机制源码 详见:代码库建议先阅读阅读之前建议先读本系列其他文章,进入鸿蒙系统源码分析(总目录),以便对本文任务调度机制的理解
    发表于 11-23 10:53

    鸿蒙内核源码分析(必读篇)

    的工作原理!操作系统就是管理场馆和确保工作人员有序工作的系统解决方案商,外面公司只要提供个节目单,就能按节目单把这台戏演好给广大观众观看。有了这个故事垫底,鸿蒙内核源码
    发表于 11-25 09:28

    鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核)

    致敬内核开发者感谢开放原子开源基金会,致敬鸿蒙内核开发者。可以毫不夸张的说鸿蒙内核源码可作为大学
    发表于 07-04 17:16

    鸿蒙内核源码分析鸿蒙内核的每段汇编代码解析

    本篇说清楚CPU的工作模式 读本篇之前建议先读鸿蒙内核源码分析(总目录)其他篇. 正如一个互联网项目的后台管理系统有权限
    的头像 发表于 03-02 09:56 4295次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>内核</b><b class='flag-5'>源码</b><b class='flag-5'>分析</b>:<b class='flag-5'>鸿蒙</b><b class='flag-5'>内核</b>的每段汇编代码解析

    鸿蒙内核源码分析: 虚拟内存和物理内存是怎么管理

    有了上篇鸿蒙内核源码分析(内存概念篇)的基础,本篇讲内存管理部分,本章源码超级多,很烧脑,但笔者
    发表于 11-23 11:45 19次下载
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>内核</b><b class='flag-5'>源码</b><b class='flag-5'>分析</b>: 虚拟内存和物理内存是怎么<b class='flag-5'>管理</b>的

    鸿蒙内核源码分析内核最重要结构体

    为何鸿蒙内核源码分析系列开篇就说 LOS_DL_LIST ? 因为它在鸿蒙 LOS 内核中无处
    发表于 11-24 17:54 35次下载
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>内核</b><b class='flag-5'>源码</b><b class='flag-5'>分析</b> :<b class='flag-5'>内核</b>最重要结构体

    华为鸿蒙系统内核源码分析上册

    鸿蒙內核源码注释中文版【 Gitee仓】给 Harmoηy○S源码逐行加上中文注解,详细阐述设计细节,助你快速精读 Harmonyos内核源码
    发表于 04-09 14:40 17次下载