凡走过必留下痕迹,学点什么都会有用的。

本系列博文总结了自己在学习嵌入式Linux编程过程中的收获,若有错误,恳请指正,谢谢!

——参考教材韦东山系列教材


bootloader 是一个用于启动linux内核的C程序,为了达到最终启动内核的目的需要完成以下几个步骤:

step1:硬件相关初始化,为启动内核准备硬件平台;

step2:将内核从NAND FLASH读取到SDRAM;

step3:设置需要传递给内核的启动参数;

step4:跳转到SDRAM,运行内核;

下面将详细讲述各个步骤细节:


第一步:硬件相关初始化,为启动内核准备硬件平台

基本流程见下图1

(1)禁看门狗

     ldr r0, =0x53000000  //WTCON : WATCHDOG TIMER CONTROL REGISTER  Address = 0x53000000
mov r1, # //bit 0 = 0 : Disable the reset function of the watchdog timer.
str r1, [r0] //将r1中的值存到r0所指定的地址中

(2)设置系统时钟

配置时钟之前先参考下芯片手册  S3C2440A_UserManual_Rev13,需要操作两个寄存器:

  1. MPLLCON 设置MPLL锁相环倍频因子;

MPLL计算公式 : Mpll = (2 * m * Fin) / (p * 2S)   ;   m = (MDIV + 8), p = (PDIV + 2), s = SDIV ;Fin取决于外部晶振频率,JZ2440开发板的 [OM2:OM3] 设置为 [0:0] ,因此

main clock和USB clock 依赖外部12MHZ 晶振。

2. CLKDIVN 设置 HCLK , FCLK,PCLK比例关系;

FCLK, HCLK, and PCLK
         FCLK is used by ARM920T.
         HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, the interrupt controller, the LCD controller, the DMA and USB host block.
         PCLK is used for APB bus, which is used by the peripherals such as WDT, IIS, I2C, PWM timer, MMC interface,ADC, UART, GPIO, RTC and SPI.

    #define S3C2440_MPLL_200MHZ     ((0x5c<<12)|(0x01<<4)|(0x02))

    /* 2. 设置时钟 */     //先设置各个时钟的比例对CLKDIVN赋值,之后设置系统时钟对MPLLCON赋值
ldr r0, =0x4c000014 //CLKDIVN : CLOCK DIVIDER CONTROL REGISTER  Address = 0x4c000014
mov r1, #0x03 //FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1 FCLK=200MHZ HCLK=100MHZ PCLK=50MHZ
str r1, [r0] //将r1中的值存到r0所指定的地址中 /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */
mrc p15, , r1, c1, c0, /* 读出控制寄存器 */
orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */
mcr p15, , r1, c1, c0, /* 写入控制寄存器 */ /* MPLLCON = S3C2440_MPLL_200MHZ */
ldr r0, =0x4c000004 //MPLLCON Address = 0x4c000004
ldr r1, =S3C2440_MPLL_200MHZ // S3C2440_MPLL_200MHZ值比较复杂,使用ldr伪汇编
str r1, [r0]

(3)初始化SDRAM

在使用SDRAM之前,有必要了解下什么是SDRAM。请参阅《高手进阶_终极内存技术指南——完整》,这篇文章解释了SDRAM的基本原理。系统上电需要对SDRAM进行初始化,完成对模式寄存器(MR,Mode Register)的配置。主要设置操作模式、CAS潜伏期时间、突发传输方式和突发长度,完成配置后可以根据地址读写SDRAM。本文操作的SDRAM型号是K4S561632N,S3C2440提供标准的总线接口(BANK6),用于操作SDRAM,因此建立了硬件连接之后,操作S3C2440相应的控制寄存器即可完成对SDRAM的配置和读写,具体操作参阅《[嵌入式Linux应用开发完全手册]》第6章 存储控制器。

 /* 3. 初始化SDRAM */
ldr r0, =MEM_CTL_BASE //SDRAM控制器寄存器首地址,总计需要对13个寄存器配置完成SDRAM的初始化工作
adr r1, sdram_config //读取sdram_config的当前地址到r1,此地址取决于当前PC值,是相对跳转
add r3, r0, #(*) //r3=r0+52 r3值代表了全部控制寄存器所占地址空间大小,总计52字节
:
ldr r2, [r1], # //从r1所指的地方加载指存入r2,之后r1=r1+4,地址加4字节,32位
str r2, [r0], # //将r2的值存入r0所指的地方,之后r0=r0+4
cmp r0, r3
bne 1b //b表示back
 sdram_config:
.long 0x22011110 //BWSCON
.long 0x00000700 //BANKCON0
.long 0x00000700 //BANKCON1
.long 0x00000700 //BANKCON2
.long 0x00000700 //BANKCON3
.long 0x00000700 //BANKCON4
.long 0x00000700 //BANKCON5
.long 0x00018005 //BANKCON6
.long 0x00018005 //BANKCON7
.long 0x008C04F4 //REFRESH
.long 0x000000B1 //BANKSIZE
.long 0x00000030 //MRSRB6
.long 0x00000030 //MRSRB7

  下图是SDRAM的原理图,由两片32M的SDRAM级联成64M,访问一次传递4字节数据。

SDRAM 原理图

SDRAM由BANK6控制,bank6地址空间为0x30000000~0x38000000,共计128MB。上图所示SDRAM存储空间为64M,因此SDRAM地址空间为0X30000000~0X33FFFFFF。

(4)重定位代码

将启动代码从片内SRAM复制到SDRAM中,使用C代码编写。调用C代码需要设置栈,至于为什么要设置栈请参阅http://www.cnblogs.com/xmphoenix/archive/2012/04/28/2475399.html。这里涉及到三个参数:从哪去读取启动代码,将代码复制到哪去,启动代码多大。

  • 从哪去读取启动代码(源地址)

启动代码烧写在NAND,待系统上电后,片内SRAM会加载NAND的起始4K内容。因此启动代码起始地址为:0x00000000

  • 读到哪去(目的地址)

在链接文件中指定了启动代码在SDRAM的中存放地址:0x33f80000,启动代码存到SDRAM顶端512k的地址空间中。

  • 读多少(大小)

启动代码大小 = 代码段+只读数据段+数据段。BSS段不包含在启动代码中,bss段存放没有初始化的全局变量,或者初始化为0的全局变量,程序运行前将bss段清零。

 /* 4. 重定位 : 把bootloader本身的代码从flash复制到它的链接地址去 */
ldr sp, =0x34000000 //设置栈,copy函数使用C语言写,调用C代码之前需要设置栈
bl nand_init mov r0, # //传递参数给 copy_code_to_sdram, 对于NOR 启动
ldr r1, =_start //链接地址即为代码存储区的首地址 _start = 0x33f80000;
ldr r2, =__bss_start //代码段不包括bss段
sub r2, r2, r1 //除去BSS段外的所有代码的空间大小 bl copy_code_to_sdram //参数依次为r0,r1,r2
bl clear_bss

完成以上4个步骤后,CPU会转到SDRAM中取指令执行。

基于JZ2440开发板编写bootloader总结(一)的更多相关文章

  1. Linux学习 :移植U-boot_2016.09到JZ2440开发板

    一.下载源码:ftp://ftp.denx.de/pub/u-boot/ 二.初始化编译: ①新建一个单板: cd board/samsung/ cp smdk2410 smdk2440 -rf   ...

  2. Linux学习 :移植U-boot_2012.04.01到JZ2440开发板

    一.下载U-boot源码:ftp://ftp.denx.de/pub/u-boot/ 二.uboot的启动过程: 部分硬件初始化——>加载完整uboot到RAM——>跳转到第二阶段入口开始 ...

  3. Jz2440开发板熟悉

    title: Jz2440开发板熟悉 tags: ARM date: 2018-10-14 15:05:56 --- 概述 外部晶振为12M Nand Flash 256M,Nor Flash 2M, ...

  4. 基于uFUN开发板和扩展板的联网校准时钟

    项目概述 上周在uFUN试用群里看到管理员说试用活动快结束了,要抓紧完成评测总结,看大家的评测总结也都写了,我也不能落后啊!正好最近做的扩展板到手了,于是赶紧进行调试,做了一个不用校准的时钟,时钟这种 ...

  5. 基于uFUN开发板的RGB调色板

    前言 使用uFUN开发板配合Qt上位机,实现任意颜色的混合,Qt上位机下发RGB数值,范围0-255,uFUN开发板进行解析,然后输出不同占空比的PWM,从而实现通过RGB三原色调制出任意颜色. Qt ...

  6. 基于uFUN开发板的心率计(三)Qt上位机的实现

    前言 上两周利用周末的时间,分别写了基于uFUN开发板的心率计(一)DMA方式获取传感器数据和基于uFUN开发板的心率计(二)动态阈值算法获取心率值,介绍了AD采集传感器数据和数据的滤波处理获取心率值 ...

  7. 基于uFUN开发板的心率计(二)动态阈值算法获取心率值

    前言 上一篇文章:基于uFUN开发板的心率计(一)DMA方式获取传感器数据,介绍了如何获取PulseSensor心率传感器的电压值,并对硬件电路进行了计算分析.心率计,重要的是要获取到心率值,本篇文章 ...

  8. JZ2440开发板:UART(串口)使用(学习笔记)

    查看UART在硬件上的信息,阅读JZ2440原理图可以看到: JZ2440开发板的UART0是可以跟USB相接的,用于打印调试,UART1,UART2两个串口用来外接模块.所以本文仅对UART0进行操 ...

  9. JZ2440开发板:修改ARM芯片时钟(学习笔记)

    想要修改ARM芯片的时钟,需要去查询芯片手册和原理图,获取相关的信息(见下方图片) 首先来看时钟的结构图 根据结构图可以看出,时钟源有两种选择:1. XTIpll和XTOpll所连接的晶振 2. EX ...

随机推荐

  1. Open-Falcon第二步安装绘图组件Transfer(小米开源互联网企业级监控系统)

    ----安装绘图组件---- 安装Transfer transfer默认监听在:8433端口上,agent会通过jsonrpc的方式来push数据上来. cd /usr/local/open-falc ...

  2. 广搜:codevs-3344(初步bfs)

    一道典型的迷宫问题 小刚在迷宫内,他需要从A点出发,按顺序经过B,C,D--,到达最后一个点,再回到A点.迷宫内有些障碍,问至少走几步. 输入描述 Input Description 第一行有三个数n ...

  3. Java-将多线程停止的两种方法

    线程如何停止呢 stop方法过时了,看起描述发现,有其他解决方案. 线程结束:就是让线程任务代码执行完,run方法结束. run方法怎么结束呢? run方法中通常都定义循环,只要控制住循环就哦了. / ...

  4. 运用经典方法进行横截面数据分类 笔记 (基于R)

    参考资料: [1]吴喜之. 复杂数据统计方法[M]. 中国人民大学出版社, 2015. 一.logistic回归与probit回归 logistic回归和probit回归都属于广义线性模型. 广义线性 ...

  5. 再起航,我的学习笔记之JavaScript设计模式09(原型模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...

  6. Angular2.0的项目架构

    Angular2.0的项目架构 一.项目服务端app a) Controller控制器 b) Router路由 c) Service服务 d) Public公共样式及脚本和图片等静态资源 e) Vie ...

  7. Android 5.1.1在外置SD卡中创建文件夹

    Android 4.4之后WRITE_MEDIA_STORAGE 权限仅提供给系统应用,不再授予第三方App,WRITE_EXTERNAL_STORAGE 权限,仅仅用于授权用户写 primary e ...

  8. VS2017 Cordova 出现错误 @ionic/app-scripts 未安装

    在安装vs2017 Cordova中遇到出现错误 @ionic/app-scripts 未安装 在系统添加环境变量SASS_BINARY_PATH,将我们下载的win32-ia64-47_bindin ...

  9. 【Git】 自动化Maven项目构建脚本(二)

    这次脚本增加了构建选择,可以按需构建了. #!/bin/bash #----------------------------------------------- # FileName: auto-b ...

  10. 【可视化】Echarts3 在世界地图中绘制中国各省份的轮廓

    要在世界地图展现出来的情况下绘制中国省份的轮廓,根据现有的echarts-api是不可行的. 但好在echarts也提供了自定义地图的方式,使用echarts.registerMap();来实现 第一 ...