码迷,mamicode.com
首页 > 系统相关 > 详细

linux驱动系列之arm汇编

时间:2016-08-06 21:54:15      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:

     在arm平台学习linux时,会遇到arm汇编指令,arm汇编指令与8086汇编指令很多地方都不同,在此记下来以免后面忘了,同时在学习了汇编指令之后分析一些汇编指令编写的代码。

一、相对跳转指令b、bl

       b、bl指令都实现短跳转,bl指令执行后会在链接寄存器r14中保存下一条指令的地址。

二、数据传送指令mov

  mov指令会把一个寄存器的数赋值给另一个寄存器,或者把一个常数传递给另一个寄存器。

  如:mov  r0,r1  //将r1中的值传递给r0,mov r0,#0xff //将常数0xff传递给r0寄存器。

  mov指令传递的常数必须能够用立即数表示,当不知道一个数是否能够用“立即数传递”时,可以用ldr指令进行传递。

  如:ldr r0,=0xff。

三、内存访问指令str、ldr、ldm、stm

  ldr指令从内存中读取数到寄存器中,str指令将寄存器中的数传递到内存中,ldr、str指令操作的数都是32位的。ldm、stm是批量内存访问指令,用一个指令就能访问多个数据。下面是从s3c2440 datasheet上面的截图

技术分享

  {cond}表示指令的执行条件

  Rn中保存内存地址,如果后面有!指令执行后会更新为下一个内存单元的地址

  <Rlist>寄存器列表对于ldm指令相当于将内存的数据取出放入列表中的寄存器中,stm指令相当于将列表中的寄存器中的值放入内存中。

  {^}有两种含义:如果<Rlist>有PC寄存器时,它表示指令执行后,spsr寄存器的值会自动复制cpsr寄存器中,这个常用于从中断处理函数中返回。如果<Rlist>中没有PC寄存器时,{^}表示操作的是用户模式下的寄存器,不是特权模式下的寄存器。

  指令中列表中的寄存器与内存对应关系为:编号底的寄存器对应低地址内存单元,编号搞的对应高地址内存单元。

四、加减指令add、sub

   如:add r0,r1,#0xff //r0=r1+0xff  sub r0,r1,#0xff  //表示r0=r1-0xff

五、程序状态寄存器访问指令msr、mrs

     arm有个程序状态寄存器cpsr,它用来控制处理器的工作模式和设置中断的总开关。

  msr cpsr,r0  //复制r0到cpsr中

  mrs r0,cpsr //复制cpsr到r0中

六、伪指令

  .gloabl  _start

  _start:

  .text

  .extern main

  .gloabl将本文件中的某个程序定义为全局的

  .extern 将某个变量或者函数引用到本文件中

  .text 表示下面的语句都属于代码段

八、uboot启动过程分析

   在看了韦东山老师的书和视频后,对汇编指令及bootloader的工作流程有了一个新的认识,我们接触比较的bootloader就是电脑的bios了,bootloader就是一段将我们硬盘上的代码搬运到内存中指定位置运行的程序。

  在说硬盘内存这些概念时我们首先要对s3c24xx或者其他的微处理器的存储空间有一个大致的了解。我做实验主要用的是2440,下面也就2440进行说明。在2440中我们一般使用三种存储设备:SDRAM、Nandflash、Norflash。这三个存储设备相对于我们平常的PC就是:SDRAM====>内存条,(Nandflash、Norflash)====>硬盘,对于Nandflash和Norflash的区别主要是前者不能直接运行代码,后者代码可以直接运行但是不能进行写数据,所以我们常常将Nandflash 存放程序,Norflash存放数据。

  对于存储空间2440有一个专门的存储控制器,

 技术分享

  一般我们把Norflash、Nandflash都与nGCS0相连,然后通过选择OM0、OM1选择哪种启动方式,如果选择Norflash我们的代码就会从Norflash的0地址开始执行,如果选择Nandflash我们的代码会被处理器将Nandflash的前4k拷贝到芯片内部的4k RAM中,然后程序在内部4k RAM中开始执行,这个拷贝过程是一个硬件过程,芯片内部自动完成。由于只有4k大小如果我们的程序小于4k,我们就直接让其在芯片内部RAM中执行,如果我们的代码大于4k,一般我们会用4k大小的程序将Nandflash里面的其余部分程序直接拷贝到SDRAM(0x3000 0000)中执行。

  我们的bootloader肯定是大于4k的,说以如果在Nandflash中运行我们就必须在4k 大小的代码中将bootloader拷贝到SDRAM,然后在SDRAM中将Nandflash 中的Kernerl拷贝到SDRAM中完成内核的启动,大的流程就如前面所说,但是具体在实现的过程中有很多的小细节。

8.1 bootloader启动前的准备

  1、关看门狗

  2、设置时钟

  3、初始化SDRAM

  4、重定位将bootloader的代码从Nandflash中拷贝到SDRAM中

  5、执行main

      ====》在main函数中所做的工作

          1、初始化串口(因为要加载内核需要打印一些信息,内核没有串口初始化的代码所以需要在内核启动前进行初始化)

          2、

  

linux驱动系列之arm汇编

标签:

原文地址:http://www.cnblogs.com/qiuheng/p/5539241.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!