Exynos4412 中断处理流程详解

Linux 中,当外设触发中断后,大体处理流程如下:

a -- 具体CPU architecture相关的模块会进行现场保护,然后调用machine driver对应的中断处理handler;

b -- machine driver对应的中断处理handler中会根据硬件的信息获取HW interrupt ID,并且通过irq domain模块翻译成IRQ number;

c --  调用该IRQ number 对应的high level irq event handler,在这个high level的handler中,会通过和interupt controller交互,进行中断处理的flow control(处理中断的嵌套、抢占等),当然最终会遍历该中断描述符的IRQ action list,调用外设的specific handler来处理该中断;

d -- 具体CPU architecture相关的模块会进行现场恢复;

总结下来,整个过程可以分为三部分:1、硬件处理部分;2、汇编处理部分;3、C 处理部分;

下面我们来追踪一下代码,了解当中断发生时,Linux 是如何处理的,前面的一些中断初始化部分就不再这里详述了,下面开始具体分析:

一、硬件处理部分

当一切准备好之后,一旦打开处理器的全局中断就可以处理来自外设的各种中断事件了。

当外设(SOC内部或者外部都可以)检测到了中断事件,就会通过interrupt requestion line上的电平或者边沿(上升沿或者下降沿或者both)通知到该外设连接到的那个中断控制器,而中断控制器就会在多个处理器中选择一个,并把该中断通过IRQ(或者FIQ,本文不讨论FIQ的情况)分发给该processor。

ARM处理器感知到了中断事件后,会进行下面一系列的动作(硬件处理部分):

1、切换处理器模式

修改 CPSR 寄存器中的 M[4:0],切换处理器模式位 IRQ Mode(这里M[4:0] 所添值为 10010);

2、保护现场

 保存发生中断时,CPSR值与PC值(为恢复现场做准备);这里要注意,此时中断可能发生在 usr mode (用户空间),也可能发生在 SVC mode(内核空间);

3、mask IRQ exception

关闭IRQ中断,也就是设定CPSR.I = 1;

4、设定PC值为IRQ exception vector

实现向异常向量表的跳转,ARM处理器会跳转到IRQ的exception vector地址,到这硬件所做的工作就结束了,下面就是软件行为了。

 软件处理部分流程如下:

可以看到 Vetor_irq 是汇编部分入口点,而Asm_do_irq 是C 部分入口点,下面分析Vetor_irq 向 Asm_do_irq 跳转过程

二、汇编部分

前面硬件部分结束后,跳转到相应的异常中断处理程序处执行,对于ARMv7向量表普遍是0xFFFF0018 ,而对于低向量PC=0x00000018

假设在用户空间时,产生了外部硬件中断,这个时候的会跳转到异常向量表,向量表(vector table)的代码如下

【arch/arm/kernel/entry-armv.S】

[cpp] view
plain
 copy

  1. __vectors_start:---------------〉在中断向量表被拷贝后,该地址就是0xffff0000.
  2. ARM( swi SYS_ERROR0 )
  3. THUMB( svc #0 )
  4. THUMB( nop )
  5. W(b) vector_und + stubs_offset
  6. W(ldr) pc, .LCvswi + stubs_offset
  7. W(b) vector_pabt + stubs_offset
  8. W(b) vector_dabt + stubs_offset
  9. W(b) vector_addrexcptn + stubs_offset
  10. W(b)vector_irq + stubs_offset----------〉当外部中断产生时,pc直接指向这个地址。
  11. W(b) vector_fiq + stubs_offset
  12. .globl __vectors_end

1、IRQ mode中的处理 (vector table --- > vector_irq )

IRQ mode的处理都在vector_irq中,vector_stub是一个宏,定义如下:

[cpp] view
plain
 copy

  1. /*
  2. * Vector stubs.
  3. *
  4. * This code is copied to 0xffff0200 so we can use branches in the
  5. * vectors, rather than ldr‘s.  Note that this code must not
  6. * exceed 0x300 bytes.
  7. *
  8. * Common stub entry macro:
  9. *   Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
  10. *
  11. * SP points to a minimal amount of processor-private memory, the address
  12. * of which is copied into r0 for the mode specific abort handler.
  13. */
  14. .macro  vector_stub, name, mode, correction=0
  15. .align  5
  16. vector_\name:
  17. .if \correction
  18. sub lr, lr, #\correction  //因为硬件处理器是将当前指令的下两条指令的地址存储在lr寄存器中,所以这里需要减4,让他指向被中断指令的下一条,这样当中断被恢复时,可以继续被中断的指令继续执行。
  19. .endif    //需要注意的是,这个时候的lr寄存器,已经是irq模式下的私有寄存器了,在中断产生时,硬件处理器已经自动为他赋了值。
  20. @
  21. @ Save r0, lr_<exception> (parent PC) and spsr_<exception>
  22. @ (parent CPSR)
  23. @
  24. stmia   sp, {r0, lr}        @ save r0, lr//保存r0和lr寄存器,即被中断的下一条指令
  25. mrs lr, spsr
  26. str lr, [sp, #8]        @ save spsr
  27. @
  28. @ Prepare for SVC32 mode.  IRQs remain disabled.//准备从中断模式切换到管理模式,不同的模式,对应各自不同的堆栈。
  29. @
  30. mrs r0, cpsr
  31. eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)
  32. msr spsr_cxsf, r0
  33. @
  34. @ the branch table must immediately follow this code
  35. @
  36. and lr, lr, #0x0f           //获取被中断前,处理器所处的模式
  37. THUMB( adr r0, 1f          )
  38. THUMB( ldr lr, [r0, lr, lsl #2]    )
  39. mov r0, sp  //让r0寄存器指向中断模式下堆栈的基地址
  40. ARM(   ldr lr, [pc, lr, lsl #2]    )
  41. movs    pc, lr          @ branch to handler in SVC mode,同时将中断模式下的spsr_irq(irq私有的)赋值给cpsr(该寄存器所有模式共享)
  42. ENDPROC(vector_\name)

从这可以看出 vector_stub 的使用方法:

 vector_stub, name, mode, correction=0

上面这段究竟做了些什么呢?

(1)我们期望在栈上保存发生中断时候的硬件现场(HW context),这里就包括ARM的core register。上一章我们已经了解到,当发生IRQ中断的时候,lr中保存了发生中断的PC+4,如果减去4的话,得到的就是发生中断那一点的PC值。

(2)当前是IRQ mode,SP_irq在初始化的时候已经设定(12个字节)。在irq mode的stack上,依次保存了发生中断那一点的r0值、PC值以及CPSR值(具体操作是通过spsr进行的,其实硬件已经帮我们保存了CPSR到SPSR中了)。为何要保存r0值?因为随后的代码要使用r0寄存器,因此我们要把r0放到栈上,只有这样才能完完全全恢复硬件现场。

(3)可怜的IRQ mode稍纵即逝,这段代码就是准备将ARM推送到SVC mode。如何准备?其实就是修改SPSR的值,SPSR不是CPSR,不会引起processor mode的切换(毕竟这一步只是准备而已)。

(4)很多异常处理的代码返回的时候都是使用了stack相关的操作,这里没有。“movs pc, lr ”指令除了字面上意思(把lr的值付给pc),还有一个

隐含的操作(movs中‘s’的含义):把SPSR copy到CPSR,从而实现了模式的切换

这里有个问题:中断为什么必须进入svc模式

一个最重要原因是:如果一个中断模式(例如从usr进入irq模式,在irq模式中)中重新允许了中断,并且在这个中断例程中使用了BL指令调用子程序,BL指令会自动将子程序返回地址保存到当前模式的sp(即r14_irq)中,这个地址随后会被在当前模式下产生的中断所破坏,因为产生中断时CPU会将当前模式的PC保存到r14_irq,这样就把刚刚保存的子程序返回地址冲掉。为了避免这种情况,中断例程应该切换到SVC或者系统模式,这样的话,BL指令可以使用r14_svc来保存子程序的返回地址。

2、vector table --- > vector_irq  ---> vector _stub

对于IRQ Mode 则 vector_stub, irq, IRQ_MODE, 4   

[cpp] view
plain
 copy

  1. __stubs_start:
  2. /*
  3. * Interrupt dispatcher
  4. */
  5. vector_stub irq, IRQ_MODE, 4  //减去4,确保返回发生中断之后的那条指令
  6. .long [email protected]  0  (USR_26 / USR_32)  //从用户态进入中断的处理函数 base address + 0
  7. .long [email protected]  1  (FIQ_26 / FIQ_32)
  8. .long [email protected]  2  (IRQ_26 / IRQ_32)
  9. .long [email protected]  3  (SVC_26 / SVC_32)  //从SVC进入中断的处理函数 base address + 12
  10. .long [email protected]  4
  11. .long [email protected]  5
  12. .long [email protected]  6
  13. .long [email protected]  7
  14. .long [email protected]  8
  15. .long [email protected]  9
  16. .long [email protected]  a
  17. .long [email protected]  b
  18. .long [email protected]  c
  19. .long [email protected]  d
  20. .long [email protected]  e
  21. .long [email protected]  f

这里根据被中断时,处理器模式的不同,分别跳转到__irq_usr和__irq_svc两个分支。

3、vector table --- > vector_irq  ---> vector _stub ---> __irq_usr

在这里我们以__irq_usr为例来说明:

[cpp] view
plain
 copy

  1. __irq_usr:
  2. usr_entry       //进行中断前的硬件上下文的保存
  3. kuser_cmpxchg_check
  4. irq_handler
  5. get_thread_info tsk//获取被中断的用户进程或内核线程所对应的内核栈所对应的thread info结构。
  6. mov why, #0
  7. b   ret_to_user_from_irq//恢复被中断时的上下文,然后继续被中断的进程或线程的执行
  8. UNWIND(.fnend      )
  9. ENDPROC(__irq_usr)

4、vector table --- > vector_irq  ---> vector _stub ---> __irq_usr ---> usr_entry

usr_entry展开如下:

[cpp] view
plain
 copy

  1. .macro  usr_entry
  2. UNWIND(.fnstart )
  3. UNWIND(.cantunwind  )   @ don‘t unwind the user space
  4. sub sp, sp, #S_FRAME_SIZE   // #S_FRAME_SIZE的值为72
  5. ARM(    stmib   sp, {r1 - r12}  )      //尽管当前是处于管理模式,但由于svc和usr的r0-r12是公共的,所以相当于保存用户模式的r1-r12寄存器
  6. THUMB(  stmia   sp, {r0 - r12}  )
  7. ldmia   r0, {r3 - r5}          //将之前保存在中断模式堆栈中的r0_usr,lr,spsr分别存储到r3-r5中
  8. add r0, sp, #S_PC       @ here for interlock avoidance #S_PC=60
  9. mov r6, #-1         @  ""  ""     ""        ""
  10. str r3, [sp]        @ save the "real" r0 copied
  11. @ from the exception stack
  12. @
  13. @ We are now ready to fill in the remaining blanks on the stack:
  14. @
  15. @  r4 - lr_<exception>, already fixed up for correct return/restart
  16. @  r5 - spsr_<exception>
  17. @  r6 - orig_r0 (see pt_regs definition in ptrace.h)
  18. @
  19. @ Also, separately save sp_usr and lr_usr
  20. @
  21. stmia   r0, {r4 - r6}
  22. ARM(    stmdb   r0, {sp, lr}^           )//保存用户模式下的sp_usr,lr_usr
  23. THUMB(  store_user_sp_lr r0, r1, S_SP - S_PC    )
  24. @
  25. @ Enable the alignment trap while in kernel mode
  26. @
  27. alignment_trap r0
  28. @
  29. @ Clear FP to mark the first stack frame
  30. @
  31. zero_fp
  32. ifdef CONFIG_IRQSOFF_TRACER
  33. bl  trace_hardirqs_off
  34. endif
  35. .endm

代码执行到这里的时候,ARM处理已经切换到了【SVC mode】。一旦进入SVC mode,ARM处理器看到的寄存器已经发生变化,这里的sp已经变成了sp_svc了。因此,后续的压栈操作都是压入了发生中断那一刻的进程的(或者内核线程)内核栈(svc mode栈)。

此时的管理模式的内核栈分布如下:

需要说明的是:上图中的lr_irq即为用户模式下被中断指令的下一条指令,spsr_irq即为用户模式下被中断时的cpsr寄存器。

5、vector table --- > vector_irq  ---> vector _stub ---> __irq_usr ---> (usr_entry  ---> irq_handler )

       usr_entry 结束后,会执行 irq_handler

irq_handler的实现过程 arch\arm\kernel\entry-armv.S

[cpp] view
plain
 copy

  1. .macro irq_handler
  2. get_irqnr_preamble r5, lr
  3. @在include/asm/arch-s3c2410/entry-macro.s中定义了宏get_irqnr_preamble为空操作,什么都不做
  4. 1: get_irqnr_and_base r0, r6, r5, lr @判断中断号,通过R0返回,3.5节有实现过程
  5. movne r1, sp
  6. @
  7. @ routine called with r0 = irq number, r1 = struct pt_regs *
  8. @
  9. adrne lr, 1b
  10. bne asm_do_IRQ @进入中断处理。
  11. ……
  12. .endm

可以看到 bne asm_do_IRQ @进入中断处理  泪奔~~o(>_<)o ~~ 终于到了asm_do_IRQ

可以看到整个跳转过程:

vector table --- > vector_irq  --->vector_stub, irq, IRQ_MODE, 4 ---> __irq_usr ---> usr_entry
 ---> irq_handler --->asm_do_IRQ 

三、C语言处理部分

1、 asm_do_IRQ

asm_do_IRQ实现过程,arch/arm/kernel/irq.c

[cpp] view
plain
 copy

  1. * asm_do_IRQ is the interface to be used from assembly code.
  2. */
  3. asmlinkage void __exception_irq_entry
  4. asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
  5. {
  6. handle_IRQ(irq, regs);
  7. }

[cpp] view
plain
 copy

  1. <span style="font-family: Arial, Helvetica, sans-serif;">其中关键一步handle_IRQ(irq, regs)</span>

2、handle_IRQ(irq, regs)

[cpp] view
plain
 copy

  1. /*
  2. * handle_IRQ handles all hardware IRQ‘s.  Decoded IRQs should
  3. * not come via this function.  Instead, they should provide their
  4. * own ‘handler‘.  Used by platform code implementing C-based 1st
  5. * level decoding.
  6. */
  7. void handle_IRQ(unsigned int irq, struct pt_regs *regs)
  8. {
  9. struct pt_regs *old_regs = set_irq_regs(regs);
  10. irq_enter();
  11. /*
  12. * Some hardware gives randomly wrong interrupts.  Rather
  13. * than crashing, do something sensible.
  14. */
  15. if (unlikely(irq >= nr_irqs)) {
  16. if (printk_ratelimit())
  17. printk(KERN_WARNING "Bad IRQ%u\n", irq);
  18. ack_bad_irq(irq);
  19. } else {
  20. generic_handle_irq(irq);
  21. }
  22. irq_exit();
  23. set_irq_regs(old_regs);
  24. }

主要调用generic_handle_irq(irq)

3、generic_handle_irq(irq)

[cpp] view
plain
 copy

  1. include/linux/irq.h
  2. static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)
  3. {
  4. #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
  5. desc->handle_irq(irq, desc);
  6. #else
  7. if (likely(desc->handle_irq))
  8. desc->handle_irq(irq, desc);
  9. else
  10. __do_IRQ(irq);
  11. #endif
  12. }
  13. static inline void generic_handle_irq(unsigned int irq)
  14. {
  15. generic_handle_irq_desc(irq, irq_to_desc(irq));
  16. }

generic_handle_irq调用前面定义的generic_handle_irq_desc

4、generic_handle_irq_des

[cpp] view
plain
 copy

  1. static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)
  2. desc->handle_irq(irq, desc);

而 generic_handle_irq_desc也没做什么,调用desc——>handle_irq</strong>,这个函数就是irq_desc中的成员

5、irq_desc结构体   

Linux内核将所有中断统一编号,使用irq_desc结构来描述中断:每个数组项对应一个中断(也可能是一组中断,它们使用共同的中断号),里面记录了中断的名称,中断状态,中断标记,并提供硬件访问函数(清除,屏蔽,使能中断),提供了这个中断的处理函数的入口,通过它可以调用用户注册的中断处理函数

[cpp] view
plain
 copy

  1. include/linux/irq.h
  2. {
  3. .........
  4. irq_flow_handler_t handle_irq;   //当前的中断处理函数入口
  5. struct irq_chip *chip;       //底层的硬件访问
  6. ..........
  7. struct irqaction *action; //用户提供的中断处理函数链表
  8. unsigned int status; //IRQ状态
  9. ...........
  10. const char *name;     //中断名称
  11. } ____cacheline_internodealigned_in_smp;

Handle_irq是这个或者这组中断的处理函数入口

这里调用desc->handle_irq分为俩种情况,一是单独的中断号的,一是共享中断号的,俩者的区别在于后者需要先判断是共享中断的中的哪一个然后再真正的去调用handle_irq,所以我这里分析一下单独中断号的处理流程,共享中断也是一样可以分析。

我们分析一个具体的,以外部中断为例

[cpp] view
plain
 copy

  1. for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
  2. irqdbf("registering irq %d (ext int)\n", irqno);
  3. set_irq_chip(irqno, &s3c_irq_eint0t4);
  4. set_irq_handler(irqno, handle_edge_irq);
  5. set_irq_flags(irqno, IRQF_VALID);
  6. }

上面代码我们看到,set_irq_handler的值是handler_edge_irq ,这里是处理边沿触发的中断函数,当然还有电平触发方式的中断(handler_level_irq),继续看代码

[cpp] view
plain
 copy

  1. kernel/irq/chip.c
  2. void
  3. handle_edge_irq(unsigned int irq, struct irq_desc *desc)
  4. {
  5. spin_lock(&desc->lock);         上锁
  6. desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
  7. /*
  8. * If we‘re currently running this IRQ, or its disabled,
  9. * we shouldn‘t process the IRQ. Mark it pending, handle
  10. * the necessary masking and go out
  11. */
  12. if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||   判断
  13. !desc->action)) {
  14. desc->status |= (IRQ_PENDING | IRQ_MASKED);
  15. mask_ack_irq(desc, irq);   屏蔽并清除中断
  16. goto out_unlock;
  17. }
  18. kstat_incr_irqs_this_cpu(irq, desc); 中断统计计数
  19. /* Start handling the irq */
  20. if (desc->chip->ack)      应答中断
  21. desc->chip->ack(irq);
  22. /* Mark the IRQ currently in progress.*/
  23. desc->status |= IRQ_INPROGRESS;   标记中断状态
  24. do {
  25. struct irqaction *action = desc->action;
  26. irqreturn_t action_ret;
  27. if (unlikely(!action)) {
  28. desc->chip->mask(irq);
  29. goto out_unlock;
  30. }
  31. /*
  32. * When another irq arrived while we were handling
  33. * one, we could have masked the irq.
  34. * Renable it, if it was not disabled in meantime.
  35. */
  36. if (unlikely((desc->status &
  37. (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==
  38. (IRQ_PENDING | IRQ_MASKED))) {
  39. desc->chip->unmask(irq);
  40. desc->status &= ~IRQ_MASKED;
  41. }
  42. desc->status &= ~IRQ_PENDING;
  43. spin_unlock(&desc->lock);
  44. action_ret = handle_IRQ_event(irq, action);  处理中断,最重要的函数,注意参数,action这个参数将联系到我们的用户中断处理函数
  45. if (!noirqdebug)
  46. note_interrupt(irq, desc, action_ret);
  47. spin_lock(&desc->lock);
  48. } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
  49. desc->status &= ~IRQ_INPROGRESS;
  50. out_unlock:
  51. spin_unlock(&desc->lock);
  52. }

进行追踪handle_IRQ_event()

[cpp] view
plain
 copy

  1. kernel/irq/handle.c
  2. trace_irq_handler_entry(irq, action);
  3. ret = action->handler(irq, action->dev_id);
  4. trace_irq_handler_exit(irq, action, ret);

调用action中的handler,我们注册中断的时候注意任务就是构造一个irqaction结构并添加到irq_desc中的irqaction链表中的指针action下面。现在处理中断中我们就看到了调用了我们自己的中断处理函数来处理中断了。至此中断处理流程就结束了

总结软件部分:

asm_do_IRQ --> handle_IRQ(irq, regs)--> generic_handle_irq(irq) --> generic_handle_irq_desc --> (desc—>handle_irq ) -->handle_level_irq --> handle_irq_event---> action->handler(irq, action->dev_id)

时间: 2024-10-07 06:46:47

Exynos4412 中断处理流程详解的相关文章

linux中断流程详解

异常体系比较复杂,但是linux已经准备了很多的函数和框架,但是因为中断是和具体的开发板相关,所以中断需要我们自己来处理一些方面,但是这也是很少的一部分,很多公用的处理函数内核已经实现,linux内核搭建了一个非常容易扩充的中断处理体系. 中 断系统结构涉及的方面很多,而且分布在很多的函数中,这里我主要理清一些结构和流程顺序已经在哪些函数中实现,我不知道其他人怎么样?但是我自己一开始怎 是找不到linux内核是怎么把GPIO设置成中断的,我找了很久都找不到,还有我们很多的设置,初始化等等东西好像

unity3d-配置Android环境,打包发布Apk流程详解

31:unity3d-配置Android环境,打包发布Apk流程详解 作者 阿西纳尼 关注 2016.08.28 22:52 字数 498 阅读 1806评论 0喜欢 5 Unity配置Android环境,打包发布安卓流程 一:SDK与JDK下载地址:http://pan.baidu.com/s/1mhVaXHe下载完成后,解压文件 SDK文件 二.安装 JDK 运行安装程序jdk-7u67-windows-x64 Java-JDK 分别点击下一步进行安装. 安装中 在安装过程中先后会出现两次选

CentOS 5,6 系统启动流程详解

一.linux 组成介绍 1.linux 组成: Linux: kernel+rootfs(根文件系统) kernel: 进程管理.内存管理.网络管理.驱动程序.文件系统.安全功能 rootfs: 程序和glibc 库:函数集合, function, 调用接口(头文件负责描述) 过程调用: procedure,无返回值 函数调用: function 程序:二进制执行文件 2.内核设计流派: 单内核(monolithic kernel): Linux 把所有功能集成于同一个程序 微内核(micro

Android4.0 input事件输入流程详解(中间层到应用层)

在Android系统中,类似于键盘按键.触摸屏等事件是由WindowManagerService服务来管理的,然后再以消息的形式来分发给应用程序进行处理.系统启动时,窗口管理服务也会启动,该服务启动过程中,会通过系统输入管理器InputManager来负责监控键盘消息.当某一个Activity激活时,会在该Service下注册一个接收消息的通道,表明可以处理具体的消息,然后当有消息时,InputManager就会分发给当前处于激活状态下的Activity进行处理. InputManager的启动

ssl协议工作流程详解

SSL 协议 (HTTPS) 握手.工作流程详解 (双向 HTTPS 流程 )SSL 协议的工作流程:服务器认证阶段: 1)客户端向服务器发送一个开始信息"Hello"以便开始一个新的会话连接; 2)服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器在响应客户的"Hello"信息时将包含生成主密钥所需的信息; 3)客户根据收到的服务器响应信息,产生一个主密钥,并用服务器的公开密钥加密后传给服务器; 4)服务器恢复该主密钥,并返回给客户一个用主密钥认证的信

[nRF51822] 5、 霸屏了——详解nRF51 SDK中的GPIOTE(从GPIO电平变化到产生中断事件的流程详解)

:由于在大多数情况下GPIO的状态变化都会触发应用程序执行一些动作.为了方便nRF51官方把该流程封装成了GPIOTE,全称:The GPIO Tasks and Events (GPIOTE) . 从GPIO电平变化到产生中断事件的流程详解  1.GPIOTE概览 nRF51上面有32个GPIO,由于在大多数情况下GPIO的状态变化都会触发应用程序执行一些动作.为了方便nRF51官方把该流程封装成了GPIOTE,全称:The GPIO Tasks and Events (GPIOTE) .GP

CentOS开机流程详解

CentOS开机流程详解 一.linux开机流程: BIOS:(Basic Input Output System)基本输入输出系统,它是一组固化到计算机内主板上一个ROM芯片 上的程序,保存着计算机最重要的基本输入输出的程序.开机后自检程序和系统自启动程序,可从CMOS中读写系统设置的具体信息. MBR:Master Boot Record,主要引导记录区. Boot Loader:启动引导程序. 二.详细流程 第一步:加载BIOS 打开计算机电源,计算机硬件会自动加载BIOS,读取BIOS内

Linux启动流程详解【转载】

在BIOS阶段,计算机的行为基本上被写死了,可以做的事情并不多:一般就是通电.BIOS.主引导记录.操作系统这四步.所以我们一般认为加载内核是linux启动流程的第一步. 第一步.加载内核 操作系统接管硬件以后,首先读入 /boot 目录下的内核文件. 我们查看一下,/boot 目录下面大概是这样一些文件: 第二步.启动初始化进程 内核文件加载以后,就开始运行第一个程序 /sbin/init,它的作用是初始化系统环境. 由于init是第一个运行的程序,它的进程编号(pid)就是1.其他所有进程都

IMS AKA鉴权及应用流程详解

IMS AKA鉴权及应用流程详解 @auth doubleRabbit @date 2017-03-14 目的 了解鉴权及通信类业务相关鉴权算法的概念原理 了解IMS注册流程 了解IMS鉴权流程应用 鉴权含义 鉴权是指用户访问系统的权利,是提升系统安全性的一种方式,传统鉴权方法就是用户名与密码. 鉴权与授权的区别联系.逻辑上授权过程发生在鉴权之后,而实际中有时鉴权与授权对于用户来说体现为同一过程.例如在EPC附着过程中,先发生AIA鉴权过程,再发生ULR位置更新过程(授权). 接下来讲的是针对通