exynos4412中断处理流程详解(代码片段)

923327iu 923327iu     2023-04-09     652

关键词:

  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】

  __vectors_start:---------------〉在中断向量表被拷贝后,该地址就是0xffff0000.

  ARM( swi SYS_ERROR0 )

  THUMB( svc #0 )

  THUMB( nop )

  W(b) vector_und + stubs_offset

  W(ldr) pc, .LCvswi + stubs_offset

  W(b) vector_pabt + stubs_offset

  W(b) vector_dabt + stubs_offset

  W(b) vector_addrexcptn + stubs_offset

  W(b)vector_irq + stubs_offset----------〉当外部中断产生时,pc直接指向这个地址。

  W(b) vector_fiq + stubs_offset

  .globl __vectors_end

 

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

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

 

 /*

  * Vector stubs.

  *

  * This code is copied to 0xffff0200 so we can use branches in the

  * vectors, rather than ldr‘s. Note that this code must not

  * exceed 0x300 bytes.

  *

  * Common stub entry macro:

  * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC

  *

  * SP points to a minimal amount of processor-private memory, the address

  * of which is copied into r0 for the mode specific abort handler.

  */

  .macro vector_stub, name, mode, correction=0

  .align 5

  vector_
ame:

  .if correction

  sub lr, lr, #correction //因为硬件处理器是将当前指令的下两条指令的地址存储在lr寄存器中,所以这里需要减4,让他指向被中断指令的下一条,这样当中断被恢复时,可以继续被中断的指令继续执行。

  .endif //需要注意的是,这个时候的lr寄存器,已经是irq模式下的私有寄存器了,在中断产生时,硬件处理器已经自动为他赋了值。

  @

  @ Save r0, lr_ (parent PC) and spsr_

  @ (parent CPSR)

  @

  stmia sp, r0, lr @ save r0, lr//保存r0和lr寄存器,即被中断的下一条指令

  mrs lr, spsr

  str lr, [sp, #8] @ save spsr

  @

  @ Prepare for SVC32 mode. IRQs remain disabled.//准备从中断模式切换到管理模式,不同的模式,对应各自不同的堆栈。

  @

  mrs r0, cpsr

  eor r0, r0, #(mode ^ SVC_MODE | PSR_ISETSTATE)

  msr spsr_cxsf, r0

  @

  @ the branch table must immediately follow this code

  @

  and lr, lr, #0x0f //获取被中断前,处理器所处的模式

  THUMB( adr r0, 1f )

  THUMB( ldr lr, [r0, lr, lsl #2] )

  mov r0, sp //让r0寄存器指向中断模式下堆栈的基地址

  ARM( ldr lr, [pc, lr, lsl #2] )

  movs pc, lr @ branch to handler in SVC mode,同时将中断模式下的spsr_irq(irq私有的)赋值给cpsr(该寄存器所有模式共享)

  ENDPROC(vector_
ame)

  从这可以看出 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

 

 __stubs_start:

  /*

  * Interrupt dispatcher

  */

  vector_stub irq, IRQ_MODE, 4 //减去4,确保返回发生中断之后的那条指令

  .long __irq_usr@ 0 (USR_26 / USR_32) //从用户态进入中断的处理函数 base address + 0

  .long __irq_invalid@ 1 (FIQ_26 / FIQ_32)

  .long __irq_invalid@ 2 (IRQ_26 / IRQ_32)

  .long __irq_svc@ 3 (SVC_26 / SVC_32) //从SVC进入中断的处理函数 base address + 12

  .long __irq_invalid@ 4

  .long __irq_invalid@ 5

  .long __irq_invalid@ 6

  .long __irq_invalid@ 7

  .long __irq_invalid@ 8

  .long __irq_invalid@ 9

  .long __irq_invalid@ a

  .long __irq_invalid@ b

  .long __irq_invalid@ c

  .long __irq_invalid@ d

  .long __irq_invalid@ e

  .long __irq_invalid@ f

 

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

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

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

  __irq_usr:

  usr_entry //进行中断前的硬件上下文的保存

  kuser_cmpxchg_check

  irq_handler

  get_thread_info tsk//获取被中断的用户进程或内核线程所对应的内核栈所对应的thread info结构。

  mov why, #0

  b ret_to_user_from_irq//恢复被中断时的上下文,然后继续被中断的进程或线程的执行

  UNWIND(.fnend )

  ENDPROC(__irq_usr)

 

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

  

usr_entry展开如下:

  .macro usr_entry

  UNWIND(.fnstart )

  UNWIND(.cantunwind ) @ dont unwind the user space

  sub sp, sp, #S_FRAME_SIZE // #S_FRAME_SIZE的值为72

  ARM( stmib sp, r1 - r12 ) //尽管当前是处于管理模式,但由于svc和usr的r0-r12是公共的,所以相当于保存用户模式的r1-r12寄存器

  THUMB( stmia sp, r0 - r12 )

  ldmia r0, r3 - r5 //将之前保存在中断模式堆栈中的r0_usr,lr,spsr分别存储到r3-r5中

  add r0, sp, #S_PC @ here for interlock avoidance #S_PC=60

  mov r6, #-1 @ "" "" "" ""

  str r3, [sp] @ save the "real" r0 copied

  @ from the exception stack

  @

  @ We are now ready to fill in the remaining blanks on the stack:

  @

  @ r4 - lr_, already fixed up for correct return/restart

  @ r5 - spsr_

  @ r6 - orig_r0 (see pt_regs definition in ptrace.h)

  @

  @ Also, separately save sp_usr and lr_usr

  @

  stmia r0, r4 - r6

  ARM( stmdb r0, sp, lr^ )//保存用户模式下的sp_usr,lr_usr

  THUMB( store_user_sp_lr r0, r1, S_SP - S_PC )

  @

  @ Enable the alignment trap while in kernel mode

  @

  alignment_trap r0

  @

  @ Clear FP to mark the first stack frame

  @

  zero_fp

  ifdef CONFIG_IRQSOFF_TRACER

  bl trace_hardirqs_off

  endif

  .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的实现过程 archarmkernelentry-armv.S

  .macro irq_handler

  get_irqnr_preamble r5, lr

  @在include/asm/arch-s3c2410/entry-macro.s中定义了宏get_irqnr_preamble为空操作,什么都不做

  1: get_irqnr_and_base r0, r6, r5, lr @判断中断号,通过R0返回,3.5节有实现过程

  movne r1, sp

  @

  @ routine called with r0 = irq number, r1 = struct pt_regs *

  @

  adrne lr, 1b

  bne asm_do_IRQ @进入中断处理。

  ……

  .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

  * asm_do_IRQ is the interface to be used from assembly code.

  */

  asmlinkage void __exception_irq_entry

  asm_do_IRQ(unsigned int irq, struct pt_regs *regs)

  

  handle_IRQ(irq, regs);

  

 

  其中关键一步handle_IRQ(irq, regs)

  2、handle_IRQ(irq, regs)

 

 /*

  * handle_IRQ handles all hardware IRQ‘s. Decoded IRQs should

  * not come via this function. Instead, they should provide their

  * own ‘handler‘. Used by platform code implementing C-based 1st

  * level decoding.

  */

  void handle_IRQ(unsigned int irq, struct pt_regs *regs)

  

  struct pt_regs *old_regs = set_irq_regs(regs);

  irq_enter();

  /*

  * Some hardware gives randomly wrong interrupts. Rather

  * than crashing, do something sensible.

  */

  if (unlikely(irq >= nr_irqs)) 

  if (printk_ratelimit())

  printk(KERN_WARNING "Bad IRQ%u
", irq);

  ack_bad_irq(irq);

   else 

  generic_handle_irq(irq);

  

  irq_exit();

  set_irq_regs(old_regs);

  

  主要调用generic_handle_irq(irq)

 

  3、generic_handle_irq(irq)

 

 include/linux/irq.h

  static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)

  

  #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ

  desc->handle_irq(irq, desc);

  #else

  if (likely(desc->handle_irq))

  desc->handle_irq(irq, desc);

  else

  __do_IRQ(irq);

  #endif

  

  static inline void generic_handle_irq(unsigned int irq)

  

  generic_handle_irq_desc(irq, irq_to_desc(irq));

  

  generic_handle_irq调用前面定义的generic_handle_irq_desc

 

  4、generic_handle_irq_des

 

 static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)

  

  desc->handle_irq(irq, desc);

  

 

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

  5、irq_desc结构体

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

  include/linux/irq.h

  

  .........

  irq_flow_handler_t handle_irq; //当前的中断处理函数入口

  struct irq_chip *chip; //底层的硬件访问

  ..........

  struct irqaction *action; //用户提供的中断处理函数链表

  unsigned int status; //IRQ状态

  ...........

  const char *name; //中断名称

   ____cacheline_internodealigned_in_smp;

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

 

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

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

 

 for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) 

  irqdbf("registering irq %d (ext int)
", irqno);

  set_irq_chip(irqno, &s3c_irq_eint0t4);

  set_irq_handler(irqno, handle_edge_irq);

  set_irq_flags(irqno, IRQF_VALID);

  

 

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

  

kernel/irq/chip.c

  void

  handle_edge_irq(unsigned int irq, struct irq_desc *desc)

  

  spin_lock(&desc->lock); 上锁

  desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);

  /*

  * If we‘re currently running this IRQ, or its disabled,

  * we shouldn‘t process the IRQ. Mark it pending, handle

  * the necessary masking and go out

  */

  if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) || 判断

  !desc->action)) 

  desc->status |= (IRQ_PENDING | IRQ_MASKED);

  mask_ack_irq(desc, irq); 屏蔽并清除中断

  goto out_unlock;

  

  kstat_incr_irqs_this_cpu(irq, desc); 中断统计计数

  /* Start handling the irq */

  if (desc->chip->ack) 应答中断

  desc->chip->ack(irq);

  /* Mark the IRQ currently in progress.*/

  desc->status |= IRQ_INPROGRESS; 标记中断状态

  do 

  struct irqaction *action = desc->action;

  irqreturn_t action_ret;

  if (unlikely(!action)) 

  desc->chip->mask(irq);

  goto out_unlock;

  

  /*

  * When another irq arrived while we were handling

  * one, we could have masked the irq.

  * Renable it, if it was not disabled in meantime.

  */

  if (unlikely((desc->status &

  (IRQ_PENDING | IRQ_MASKED | IRQ_DISABLED)) ==

  (IRQ_PENDING | IRQ_MASKED))) 

  desc->chip->unmask(irq);

  desc->status &= ~IRQ_MASKED;

  

  desc->status &= ~IRQ_PENDING;

  spin_unlock(&desc->lock);

  action_ret = handle_IRQ_event(irq, action); 处理中断,最重要的函数,注意参数,action这个参数将联系到我们的用户中断处理函数

  if (!noirqdebug)

  note_interrupt(irq, desc, action_ret);

  spin_lock(&desc->lock);

   while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);

  desc->status &= ~IRQ_INPROGRESS;

  out_unlock:

  spin_unlock(&desc->lock);

  

  进行追踪handle_IRQ_event()

  kernel/irq/handle.c

  trace_irq_handler_entry(irq, action);

  ret = action->handler(irq, action->dev_id);

  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)

  ————————————————

  可以观看下方视频了解的详细些

  Exynos4412中断

  http://www.makeru.com.cn/live/3512.html?s=45051

  Exynos4412裸机LED驱动开发

  http://www.makeru.com.cn/live/3556.html?s=45051

  uboot添加自定义命令

  http://www.makeru.com.cn/live/1392_815.html?s=45051

  Uboot启劢流程分析

  http://www.makeru.com.cn/live/1392_1107.html?s=45051

  -嵌入式系统移植(主要讲UBOOT移植)

  http://www.makeru.com.cn/live/3483_1629.html?s=45051

  深入讲解uboot

  http://www.makeru.com.cn/live/3483_1534.html?s=45051

  RISC-V嵌入式系统开发

  http://www.makeru.com.cn/course/details/5666?s=45051

  循环链表及线性表的应用

  http://www.makeru.com.cn/course/details/1902?s=45051

exynos4412交叉编译环境搭建(代码片段)

Exynos4412交叉编译环境搭建交叉编译:在PC机(x86平台)上开发程序,在ARM板上运行,提高开发、编译速度。环境:Tiny4412SDK1506开发板需要软件:arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz检测系统是否已经安装有交叉编译环境:#arm-linux-gcc-vba... 查看详情

三星exynos4412四核处理器怎样?

...升,它采用了三星最新的32nmHKMG工艺,据悉,三星Exynos4412处理器已经达到了Exynos双核处理器的两倍性能,但同时其功耗却只有双核Exynos4210的80%左右。这就意味着搭载Exynos4412机型的续航能力和发热状况都会有很大的改善。此外,... 查看详情

三星galaxys3的处理器到底是exynos4212还是exynos4412

...感谢您对三星产品的支持!galaxys3系列手机CPU:1.4GHz四核处理器(三星Exynos4412CPU)希望对您有帮助,祝您愉快!参考技术A这个要从三星galaxys2说起啦。希望不要嫌我回答长啊。其实我研究三星很久了,看了很多预测,各种新闻,... 查看详情

exynos4412从sd卡启动的简单网络文件系统制作(代码片段)

Exynos4412从SD卡启动的简单网络文件系统制作1.简介嵌入式系统能够在开发板上正常运行,需要先进行系统配置,一个完整的嵌入式系统应该包含的几个部分::uboot,kernel,rootfs,appfs。这几部分在ARM板Flash上的位置关系如下图所示... 查看详情

三星exynos4412是arm内核吗

...nos4212/4210并无区别,但其最大的改进除了新增两个Cortex-A9处理核心之外,还采用了与Exynos4212一样的32nm高-K金属栅极(HK/MG)低功耗制程工艺,单核心最高主频可达1.4GHz,并且支持双通道LPDDR21066内存。此外,在图形处理方面,虽然三... 查看详情

三星exynos4412对比高通骁龙snapdragonmsm8528哪个更好???急

...。1.exynos4412采用了三星32nmhkmg工艺,是三星的第一款四核处理器,主频1.4ghz,引入了一个专用图像处理器,可以用来增强手机的拍照画质。2.骁龙800处理器是美国高通公司旗下骁龙移动处理器系列的产品,采用krait400cpu,主频为2.3... 查看详情

i.mx6q和exynos4412哪个好?

...你会发觉I.MX6Q的性价比与适用性会更加好,特别是在图形处理方面比较有优势。I.MX6Q与EXYNOS4412芯片参数对比  I.MX6Q是飞思卡尔生产的cortexA9四核芯片,相对应的同一世代芯片是三星的EXYNOS4412芯片。咋看是EXYNOS4412与I.MX6Q两种芯... 查看详情

exynos4412的补充

...功耗有些低的不可思议,对比一下高通SnapdragonS4“Krait”处理器的GPU功耗,可以看到后者的功耗高达1W(1000mW),达到了Exynos4210的5倍之多,而性能反而稍稍比Exynos4210差一点。如果这个数据是可比的,那么Mali400MP4的功耗性能比真... 查看详情

u-boot启动流程详解-基于itop4412开发板

...oot的作用:CPU上电后,需要设置很多状态,包括CPU状态、中断状态、MMU状态等,其次要做的就是对硬件资源经行板级初始化、代码重定向等,最后若不进入命令行模式,就会将linux内核从flash(NAND,NORFLASH,SD,MMC等)拷贝到DDR中,... 查看详情

cortex-a9uart

...Exynos4412中UART,有4个独立的通道,每个通道都可以工作于中断模式或DMA模式,即UART可以发出中断或DMA请求以便在UART、CPU间传输数据。UART由波特率发生器、发送器、接收器和控制逻辑组成。  使用系统时钟时,Exynos4412的UA... 查看详情

cortex-a9uart

...Exynos4412中UART,有4个独立的通道,每个通道都可以工作于中断模式或DMA模式,即UART可以发出中断或DMA请求以便在UART、CPU间传输数据。UART由波特率发生器、发送器、接收器和控制逻辑组成。  使用系统时钟时,Exynos4412的UA... 查看详情

exynos4412

...求自己安排。 SPL(BL2)  SPL是uboot第一阶段执行的代码。主要负责搬移uboot第二阶段的代码到内存中运行。SPL是由固化在芯片内部的ROM引导的。我们知道很多芯片厂商固化的ROM支持从nandflash,SDCARD等外部介质启动。  所... 查看详情

魅族搭配的三星exynos4210和4412性能差距有多大呢

参考技术A三星Exynos4412采用了32nmHKMG工艺,功耗和性能都非常强大!Tegra3是45nm的,综合性能Exynos4412强多了!魅族MX2四核就是采用Exynos4412,LZ可以考虑 查看详情

tiny4412-1312__uboot移植(代码片段)

开发环境:win1064位 +VMware12+Ubuntu14.0432位工具链:linaro提供的gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi要移植的u-boot版本:u-boot-2016-11Tiny4412开发板硬件版本为:  底板:  Tiny4412SDK1312B  核心板:Tiny4412-1306 ... 查看详情

tiny4412--uboot移植时钟(代码片段)

开发环境:win1064位 +VMware12+Ubuntu14.0432位工具链:linaro提供的gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabi要移植的u-boot版本:u-boot-2016-11Tiny4412开发板硬件版本为:  底板:  Tiny4412SDK1312B  核心板:Tiny4412-1306 ... 查看详情

exynos4412iic总线驱动开发——iic基础概念及驱动架构分析

 关于Exynos4412IIC裸机开发请看:Exynos4412裸机开发——IIC总线 ,下面回顾下IIC基础概念一、IIC基础概念    IIC(Inter-IntegratedCircuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设... 查看详情

两类中断控制器处理流程_链式和层级(代码片段)

两类中断控制器处理流程_链式和层级1.下级中断控制器的类别1.1链式中断控制器(chained)1.2层级中断控制器(hierarchy)2.链式中断控制器的处理流程3.层级中断控制器的处理流程4.处理流程对比参考资料:linuxkernel的中断子系统之&#x... 查看详情

gic驱动程序对中断的处理流程(代码片段)

GIC驱动程序对中断的处理流程1.一级中断控制器处理流程2.多级中断控制器处理流程参考资料:linuxkernel的中断子系统之(七):GIC代码分析使用逐步演进的方法才能形象地理解。1.一级中断控制器处理流程对于irq_d... 查看详情