写一个简单的BootLoader(一)——Start.S分析笔记
来源:互联网 发布:淘宝鼠标滑动效果代码 编辑:程序博客网 时间:2024/04/27 17:29
韦东山嵌入式视频第三期,讲解了如何自己写一个简单的BootLoader。本篇是学习笔记,开发板是JZ2440:
- 一 什么是BootLoader
- 二 StartS分析笔记
- 关看门狗
- 设置时钟
- 初始化SDRAM
- 重定位
- 执行main
一 什么是BootLoader?
装过系统的朋友应该知道在电脑的操作系统启动之前,需要先运行一个名为BIOS的程序,之后操作系统才开始启动。这个所谓的BIOS全称为“Basic Input Output System”,是“基本输入输出系统”的意思。它保存着计算机最重要的基本输入输出的程序、开机后自检程序和系统自启动程序。其主要功能是为计算机提供最底层的、最直接的硬件设置和控制。类似于PC的BIOS,在嵌入式设备中也有这样一个程序,这就是BootLoader了(PS:这个应该叫启动加载器吗?差不多是这个意思吧)。这个程序起到了初始化硬件和启动操作系统的作用。
二 Start.S分析笔记
在JZ2440中,一个最简单的BootLoader需要做这些工作——关看门狗、设置时钟、初始化SDRAM、重定位、为内核设置串口、从Flash中将内核读入内存、设置启动参数、跳转到内核。能够完成这些工作,就能够称得上是一个“最小型”的BootLoader。
关看门狗
ldr r0, =0x53000000 mov r1, #0 str r1, [r0]
首先关看门狗,这个是常识,如果不关掉的话,就需要每隔一段时间喂狗,否则芯片就会复位。JZ2440的看门狗控制寄存器的地址是0x53000000,这个可以在芯片手册上查到,然后将每一位都置零就可以关闭了。
设置时钟
尽早设置时钟可以提高芯片的工作频率,虽然这个对于启动速度来说几乎没有什么影响,U-Boot中也没有将此步骤放在非常靠前的位置,但是强迫症韦老师还是将这一步骤放在前面。在这边也可以顺带将指令缓存ICACHE启动,这可以肉眼可见的幅度提高启动速度。
ldr r0, =0x4c000014 //CLKDIVN寄存器的地址 mov r1, #0x05; //FCLK:HCLK:PCLK=1:4:8 str r1, [r0] /* 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode” */ //HDIVN 是否是 0 ,这个条件主要判断的是 “FCLK:HCLK:PCLK=”。 //当 HDIVN == 0 的时候,FCLK:HCLK:PCLK = 1:1:1 ,这就是 //说,如果不是这个比例,HCLK和PCLK的频率就要降低,这个时候我们总 //线上的频率和CPU的频率就不一样了,所以我们要把总线模式改为异步总 //线模式 mrc p15, 0, r1, c1, c0, 0 /* 读出控制寄存器 */ orr r1, r1, #0xc0000000 /* 设置为“asynchronous bus mode” */ mcr p15, 0, r1, c1, c0, 0 /* 写入控制寄存器 */ //MPLLCON = S3C2440_MPLL_400MHZ //S3C2440_MPLL_400MHZ = //((0x5c<<12)|(0x01<<4)|(0x01)) ldr r0, =0x4c000004 ldr r1, =S3C2440_MPLL_400MHZ str r1, [r0] // 启动ICACHE mrc p15, 0, r0, c1, c0, 0 @ read control reg orr r0, r0, #(1<<12) mcr p15, 0, r0, c1, c0, 0 @ write it back //启动速度大幅度提升,大概提升两三倍的样子
初始化SDRAM
初试化SDRAM其实很简单,就是把13个寄存器设置好就可以了。
ldr r0, =MEM_CTL_BASE //SDRAM控制寄存器的起始地址 adr r1, sdram_config //(sdram_config)的当前地址 add r3, r0, #(13*4) //r3=r0+52,之所以为13,是因为有13个控制寄存器 //每个长度为4,所以为13*4 1: ldr r2, [r1], #4 //将r1的值加载到r2,同时r1加4。取出寄存器将要被设置的值 str r2, [r0], #4 //将r2的值存储到r0,同时r0加4。将要设置的值赋给对应的寄存器 cmp r0, r3 //如果r0小于r3,那么就跳回到标签1处 bne 1b //b是back的意思,结束之后,SDRAM的所有寄存器就都设置好了 . . . 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
重定位
为了完成比较复杂的工作,不能仅仅使用汇编代码。我们需要使用C语言来编写一些功能,在使用C语言代码之前一定要设置栈。
ldr sp, =0x34000000 //JZ2440的SDRAM大小为64M,并且起始地址为0x30000000。 //这里指向最高的内存,因为栈是向低地址走的。 //这里0x04000000为64M(每个地址对应一个字节) //所以设为0x30000000+0x04000000 bl nand_init //跳转到C语言程序中的NAND FLASH初始化函数 mov r0, #0 //copy_code_to_sdram的第一个参数 ldr r1, =_start //链接脚本起始地址,这是copy_code_to_sdram的第二个参数 ldr r2, =__bss_start //bss段的起始地址 //BSS(Block Started by Symbol) sub r2, r2, r1 //第三个参数,copy_code_to_sdram的len参数 bl copy_code_to_sdram //开始从flash中复制代码到SDRAM bl clear_bss //清除bss段
这就是使用的链接脚本代码
SECTIONS { . = 0x33f80000;代码段的起始地址 .text : { *(.text) } . = ALIGN(4);这句是用来取整的 .rodata : {*(.rodata*)} . = ALIGN(4); .data : { *(.data) } . = ALIGN(4); __bss_start = .;bss段的起始地址 .bss : { *(.bss) *(COMMON) } __bss_end = .;}
最后的bss段用于存储未定义的变量的,是不存储在程序中的,所以其实程序大小是__bss_end减去0x33f80000的值这里的0x33f80000就是start.S中的_star
执行main
到这里汇编代码的工作就全部结束了,开始进入C语言程序
ldr lr, =halt //返回地址 ldr pc, =mainhalt: b halt //死循环,避免开发板随便跑飞
- 写一个简单的BootLoader(一)——Start.S分析笔记
- 简单的bootloader分析(start.s)
- 自己写bootloader笔记2---start.S分析
- 自己写bootloader笔记2---start.S分析
- 写一个简单的BootLoader(二)——init.c分析笔记
- 写一个简单的BootLoader(三)——boot.c分析笔记
- 写一个简单的BootLoader(四)——链接文件boot.lds分析笔记
- 自己写bootloader(1)——start.S
- U-Boot源代码阅读笔记(一) —— 对start.S的分析
- U-Boot源代码阅读笔记(一) —— 对start.S的分析
- 自己动手写一个简单的bootloader
- U-boot移植之自己写一个简单的bootloader(一)
- uboot的start.s分析笔记
- 1 学习笔记——start.S文件分析
- Uboot学习笔记④---(start.S简单分析)
- 伟东山视频自学笔记——uboot-的start.S详细注解及分析
- 19、Bootloader(3) -- U-Boot第一阶段代码start.S分析
- Bootloader Startup.s 学习笔记一
- 世界十大著名海盗:有一个是中国美女
- Spring的autowire
- 【CentOS】CentOS7的安装,网络的开启和VMware Tools的安装
- 基础面试总结
- Linux系统下安装rz/sz命令及使用说明
- 写一个简单的BootLoader(一)——Start.S分析笔记
- 基于ELK的OpenStack日志获取和分析 [1] - ELK概述
- 正则表达式之非空白字符串
- Oracle建立表空间和用户
- 自己写的语句······笔记
- 订餐系统:技术不重要,技术很重要,设计最重要
- Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider
- UVa 11235
- Android开发之如何保证Service不被杀掉(broadcast+system/app)