最简单的bootloader的编写步骤

合集下载

实验三Bootloader编译与烧写

实验三Bootloader编译与烧写

实验三 Bootloader编译与烧写一、实验目的1.熟悉Ubuntu Linux主机环境2.熟悉u-boot编译方法二、实验环境预装Fedora10的pc机一台,CVT-A8系列实验箱,以太网线一根,串口线一根,SD卡与读卡器。

三、实验步骤实验A:编译引导Linux系统的bootloader(u-boot.bin)1) 解压U-Boot把 u-boot-s5pv210.tar.gz 拷贝到 Linux 主机的工作目录下,用命令解压u-boot-s5pv210.tar.gz,并进入 U-Boot 目录。

# tar zxvf u-boot-s5pv210.tar.gz# cd u-boot-s5pv2102) 清理U-Boot# make clean3) 配置U-Boot检查Makefile,配置正确的交叉编译路径,这里用的是工具连arm-none-linux-gnueabi-4) 编译U-Boot在U-Boot的根目录下执行如下命令进行编译。

# make编译完成,检验u-boot.bin是否已生成。

实验B:SD卡烧写BoadLoader,通过SD卡烧写u-boot 到flash。

S5PV210 支持多种不同的启动方式,包括 SD、Nand Flash、One Nand、USB、串口等,可以通过 JP1 跳线来切换 CPU 的启动方式。

SD/MMC 启动方式为: [1 -6]= 00110X,NAND(2KB-5cycle)启动方式为:[1-6]=00001X,其中 X 表示随意,1 和 0 都可以。

在 Nand Flash 被擦除为空的时候,是不能从 Nand Fl ash 启动的,这时就需要通过其他方法,把 bootloa der(u-boot)烧写到 Nand Flash。

首先要制作一张可以启动的SD 卡,让系统先从 SD 卡启动,SD 启动后通过 U-Boot 的命令行把 bootloader 镜像烧写到Nand Flash,然后就可以通过跳线切换到 Nand Fl ash 启动了。

实验2-BootLoader编译与下载

实验2-BootLoader编译与下载

3、Boot Loader 实验【实验目的】熟悉交叉工具链的配置.掌握Jflash 的使用。

熟悉Blob 编译过程。

熟悉Blob的启动流程.掌握Blob的基本调试方法。

【实验步骤】Boot Loader 编译环境搭建第一步:在编译Boot Loader之前,首先要确保已经安装了交叉编译工具链,可以利用which arm-linux-gcc 命令进行检测,如果未安装,会显示如下提示信息(如下图1所示)。

检测arm-linux-gcc是否安装图1 检测arm-linux-gcc视图第二步:如果未安装,请将发货过光盘放入到光驱当中,(提示:并利用mount - t iso9660 /dev/cdrom /mnt/cdrom命令,将光盘挂载到Linux 操作系统下,或者直接点击Linux 系统桌面右键,选择光盘->挂载选项,将发货光盘挂载到Linux 系统当中。

)进入/mnt/cdrom/Toolchain 目录下,将xscalev1_liod_qt_2.3.7.tar.gz 工具链解压到/usr/local/ 目录下面,如下图2 所示。

(将xscalev1_liod_qt_2.3.7.tar.gz文件解压到/usr/local 目录下。

)[root@ local host root]# tar –xzvf xscalev1_liod_qt_2.3.7.tar.gz –C /usr/local图2解压交叉编译工具链第三步:利用export命令将交叉编译工具的路径加入到系统PATH环境变量中。

(也可以直接修改“root”目录下的“.bash_profile”文件)然后利用which命令查看交叉编译工具是否已在系统搜索路径中。

图3 添加arm-linux-gcc 交叉编译工具视图Blob 的交叉编译第四步:将光盘中的BootLoader文件夹中的Boot-XSBase270-2.6.tar.gz文件(具体文件名以光盘Blob 文件夹中所提供的文件为准)复制到/root/work/Blob 目录下(具体目录取决用户决定)。

Bootloader的结构和启动过程

Bootloader的结构和启动过程

Bootloader的结构和启动过程CPU上电后,会在某个地址开始执行,比如MIPS结构的CPU会从0xBFC00000取第一条指令,而ARM结构的CPU则从0x00000000开始,嵌入式开发板中,需要把存储器件ROM或Flash 等映射到这个地址。

而Bootloader就存在这个地址的开始处,这样一上电后就会从这个地址处执行。

Bootloader执行后从板子上的某个固态存储设备上将操作系统OS加载到RAM中运行。

(一些功能强大的Bootloader,比如U-boot在正常启动加载后可以延时若干秒(也可以自己设置),等待终端用户按下任意键后便可进入到下载模式;如果在指定的时间内没有按键,U-boot则会启动Linux内核,内核的启动参数可以是默认的或是由U-boot传递给它的)。

**注意:有的CPU在运行Bootloader之前先运行一段固件(firmware)中固化的boot代码,比如x86结构的CPU就是先运行BIOS中的固件然后才开始运行硬盘第一个分区中的Bootloader。

在大多数的嵌入式系统中并没有固件,Bootloader是上电后运行的第一个代码。

**下面便更细致得说明Bootloader的启动过程:从固态存储器上启动的Bootloader大多数是分二个阶段来启动的。

**第一个阶段**使用汇编代码来实现,它主要完成一些依赖于CPU体系结构的初始化,比如关看门狗、关中断、初始化RAM、将第二阶段调用的C语言代码复制到RAM(非必须,例如对于NOR Flash 等设备可以直接在上面执行,只不过比在RAM上执行效率低),设置CPU的速度和时钟频率(非必需,也可以放在第二阶段),设置好栈,跳转到第二阶段的C语言入口处等;**第二个阶段**通常用C语言来实现,它主要用来:初始化本阶段要用到的硬件设备、检测系统内存映射(就是确定板上使用了多少内存,他们的地址空间是什么)、将内核映像和根文件系统映像从Flash 上复制到内存RAM并且在内存中的某个固定位置为内核设置启动参数Boot parameters(Flash上的内核映像有可能是经过压缩的,那么读到RAM后还要进行解压。

BOOTLOADER编写实验

BOOTLOADER编写实验
9

基础知识
用来控制 BootLoader 的设备或机制
串口通讯是最简单也是最廉价的一种双机通讯设备,所以往 往在BootLoader中主机和目标机之间都通过串口建立连接, BootLoader 程序在执行时通常会通过串口来进行 I/O,比 如:输出打印信息到串口,从串口读取用户控制字符等。当 然如果认为串口通讯速度不够,也可以采用网络或者USB通 讯,那么相应的在BootLoader中就需要编写各自的驱动。
初始化本阶段要使用到的硬件设备 调用应用程序或启动内核
14

基础知识
Stage 1初始化流程图
stage 1的功能: RAM初始化, 设置各个部件的时钟和片选, 将BootLoader拷贝到RAM中,设 置堆栈,调用Stage 2。 注意:在本阶段,特别是在堆 栈设置之前,进行函数调用 (也有些汇编子程序不需要使 用堆栈)或者使用堆栈保存数 据将产生不可预知的结果;
通过串口设置下载地址和下载的长度 (用于缓冲接收的数据), 下载更新的Boot Loader
接收下载的数据
确认下载的数据
调用I28f320_Prog_Main 将数据写到FLASH中
返回
17

实验过程
实验过程
18

实验报告要求
实验报告要求
Bootloader在嵌入式系统中的作用是什么,它的基本功能 包括那些? 简述典型Bootloader的框架;
JX44B0实验系统教案 实验系统教案 BOOTLOADER编写实验 编写实验
武汉创维特信息技术有限公司
2010-11-19
提纲
1
实验目的
2
实验内容
3 4 5 6 7
预备知识

stm32f030 bootloader 例程

stm32f030 bootloader 例程

主题:STM32F030 Bootloader 例程一、简介STM32F030是STMicroelectronics公司推出的一款32位ARM Cortex-M0内核的微控制器。

它具有丰富的外设,如GPIO、UART、SPI、I2C等,适用于各种嵌入式系统应用。

在嵌入式系统开发中,Bootloader是一个重要的组成部分,它能够实现固件的更新和管理,提高系统的灵活性和可靠性。

本文将介绍如何使用STM32F030的Bootloader例程进行固件升级。

二、准备工作在使用STM32F030的Bootloader例程之前,我们需要准备好以下工具和材料:1. STM32F030开发板2. USB转TTL串口模块3. ST-Link下载器4. 针对STM32F030系列的Bootloader例程源码三、下载和安装Bootloader例程源码1. 在STMicroelectronics官全球信息站下载针对STM32F030的Bootloader例程源码2. 将下载的源码解压缩到本地3. 打开Keil MDK-ARM开发环境,导入源码并进行编译四、烧录Bootloader程序1. 使用ST-Link下载器将编译好的Bootloader程序烧录到STM32F030开发板上2. 确保烧录成功后,通过串口工具连接USB转TTL串口模块到STM32F030的串口引脚上五、固件升级测试1. 将需要升级的固件通过串口工具上传到开发板2. 在Bootloader程序中编写相关代码来实现固件的升级和校验3. 运行Bootloader程序,进行固件升级测试六、总结通过本文的介绍,我们了解了如何使用STM32F030的Bootloader 例程进行固件升级。

在实际的嵌入式系统开发中,Bootloader的作用不仅局限于固件升级,还可以实现固件的管理和安全验证。

掌握Bootloader的开发和使用对于提高系统的稳定性和可靠性是非常重要的。

Bootloader编写简明教程

Bootloader编写简明教程

Bootloader编写简明教程第⼀部分:基本功能流程CPU上电后会从IO空间的某地址取第⼀条指令。

但此时:PLL没有启动,CPU⼯作频率为外部输⼊晶振频率,⾮常低;CPU⼯作模式、中断设置等不确定;存储空间的各个BANK(包括内存)都没有驱动,内存不能使⽤。

在这种情况下必须在第⼀条指令处做⼀些初始化⼯作,这段初始化程序与操作系统独⽴分开,称之为bootloader。

实际上,很少有必要⾃⼰写⼀个Bootloader,因为U-Boot已经强⼤到能够满⾜各种需要。

但是强⼤必然复杂,⼀个初学者想要分析U-Boot的源代码,还是有些难度的。

出于学习的⽬的,我写了这个史上最简单的启动加载器,它只包含最基本的功能,却囊括了⼀个嵌⼊式Bootloader应该有的核⼼和精华。

我把这个启动加载器命名为S-Boot,是Simple Bootloader的缩写,亦可进⼀步简称为SB。

使⽤的实验环境为OK2440开发板,板上处理器为S3C2440A,有64M内存,Nand存储器为K9F1208,64M。

⽹⼝芯⽚为CS8900A。

我们要实现的功能是:从串⼝下载Linux内核映像到RAM;从⽹⼝下载Linux内核映像到RAM;从RAM启动内核挂载NFS根⽂件系统。

1. 第⼀阶段的汇编代码:start.S⼀个嵌⼊式Bootloader最初始部分的代码⼏乎必须是⽤汇编语⾔写成的,因为开发板刚上电后没有准备好C程序运⾏环境,⽐如堆栈指针SP没有指到正确的位置。

汇编代码应该完成最原始的硬件设备初始化,并准备好C运⾏环境,这样后⾯的功能就可以⽤C语⾔来写了。

对我们的S-Boot来说,上电后的起始运⾏代码是 start/start.S。

.text.global _start_start:b Reset ; 0x00: 发⽣复位异常时从地址零处开始运⾏b HandleUndef ; 0x04: 未定义指令中⽌模式的向量地址b HandleSWI ; 0x08: 管理模式的向量地址,通过SWI指令进⼊此模式b HandlePrefetchAbort ; 0x0C: 指令预取终⽌导致的异常的向量地址b HandleDataAbort ; 0x10: 数据访问终⽌导致的异常的向量地址b HandleNotUsed ; 0x14: 保留b HandleIRQ ; 0x18: 中断模式的向量地址b HandleFIQ ; 0x1C: 快中断模式的向量地址这⾥,汇编指⽰符.text表明以下内容属于代码段,.global _start指明_start是全局可访问的符号。

毕设级项目:基于单片机从零写bootloader

毕设级项目:基于单片机从零写bootloader

毕设级项目:基于单片机从零写bootloader摘要:1.引言2.单片机bootloader 简介3.单片机bootloader 设计与实现a.目标平台与工具选择b.代码烧写流程c.代码结构与组织d.重要函数与实现4.遇到的问题及解决方案a.硬件问题b.软件问题5.总结与展望正文:基于单片机的毕设项目,从零开始编写bootloader,对于学习和实践嵌入式系统的设计与开发具有很大的价值。

本文将详细介绍这一过程,包括bootloader 的设计思路、实现步骤以及遇到的问题和解决方案。

首先,我们需要了解什么是bootloader。

bootloader(引导加载程序)是嵌入式系统中的一个关键部分,它负责在系统加电后初始化硬件并执行系统启动代码。

通常情况下,bootloader 会被固化在单片机的非易失性存储器中,以保证系统能够从断电状态恢复。

接下来,我们将详细讨论单片机bootloader 的设计与实现。

首先,我们需要选择一个合适的单片机平台和相应的开发工具。

这里我们以STC89C52 单片机为例,采用Keil uVision5 作为开发环境。

在设计和实现bootloader 时,我们需要关注代码烧写流程。

一般来说,bootloader 的烧写过程可以分为以下几个步骤:1.下载程序到单片机:通过ISP(In-System Programming)或JTAG 接口将程序下载到单片机内部的非易失性存储器中。

2.跳转到bootloader 入口:单片机加电后,会从非易失性存储器中执行bootloader 的入口地址。

3.初始化硬件:bootloader 会对单片机内部和外部的硬件进行初始化,例如初始化时钟、复位和串口等。

4.烧写应用程序:bootloader 会将从串口接收到的应用程序代码烧写至单片机的程序存储器中。

5.跳转到应用程序入口:完成代码烧写后,bootloader 会跳转到应用程序的入口地址,开始执行。

stc单片机bootloader程序编写

stc单片机bootloader程序编写

stc单片机bootloader程序编写随着科技的不断发展,单片机在各个领域的应用越来越广泛。

而在单片机的开发过程中,Bootloader程序的编写是非常重要的一环。

本文将介绍STC单片机Bootloader程序的编写方法。

首先,我们需要了解什么是Bootloader程序。

Bootloader程序是位于单片机内部的一段特殊代码,它的作用是在单片机上电或复位时,负责初始化硬件设备,并加载用户程序到内存中运行。

因此,Bootloader程序的编写质量直接影响到单片机的启动速度和稳定性。

在STC单片机中,编写Bootloader程序需要以下几个步骤:1. 确定Bootloader程序的存储空间:在STC单片机中,Bootloader 程序通常存储在内部Flash中。

因此,我们需要确定Bootloader程序的存储地址和大小。

一般情况下,Bootloader程序的大小应该尽量小,以便为用户程序留出更多的空间。

2. 编写Bootloader程序的初始化代码:在Bootloader程序中,我们需要编写初始化代码,用于初始化单片机的硬件设备,如时钟、GPIO 等。

这些初始化代码的编写需要根据具体的单片机型号和硬件配置来进行。

3. 实现用户程序的加载功能:Bootloader程序的核心功能是加载用户程序到内存中运行。

在STC单片机中,我们可以通过串口通信或其他外部设备来实现用户程序的加载。

例如,我们可以通过串口接收用户程序的数据,并将其写入到内存中。

4. 实现用户程序的跳转功能:当用户程序加载完成后,Bootloader 程序需要实现跳转到用户程序的功能。

在STC单片机中,我们可以通过设置程序计数器(PC)的值来实现跳转。

具体的跳转地址需要根据用户程序的存储地址来确定。

5. 添加Bootloader程序的升级功能:为了方便后续的固件升级,我们可以在Bootloader程序中添加升级功能。

通过升级功能,我们可以通过串口或其他外部设备将新的Bootloader程序写入到单片机中,从而实现Bootloader程序的更新。

bootloader的编写

bootloader的编写

bootloader的编写
编写一个bootloader是一个复杂的任务,需要了解计算机架构
和操作系统的启动过程。

以下是编写一个简单的x86 bootloader的基本步骤:
1. 确定引导扇区的位置:在硬盘的第一个扇区(通常是0号扇区)创建一个引导扇区。

这个扇区需要包含一个主引导记录(Master Boot Record,MBR),以便计算机可以正确地引导。

2. 编写MBR代码:MBR是引导扇区中的第一扇区,它包含
了启动计算机所需的你的代码。

MBR的大小为512字节,所
以你的代码必须小于或等于512字节。

3. 使用汇编语言:编写x86汇编语言代码来实现MBR的功能。

你需要了解x86指令集和寄存器的使用。

确保你的代码具有正确的引导标志,并设置正确的启动设备。

4. 编写启动代码:启动代码是你的汇编代码的一部分,它是在MBR中执行的。

启动代码负责加载进一步的代码和操作系统。

这段代码通常位于MBR的末尾,并将控制转移到加载的代码。

5. 加载操作系统:启动代码负责从硬盘上加载操作系统的剩余部分,然后将控制权交给操作系统。

需要注意的是,编写一个完整的、功能完备的bootloader涉及
到更多的细节和复杂性,包括读取硬盘、文件系统的支持、加
载器链等。

上述步骤仅为编写一个最基本的x86 bootloader提供了一个概览。

自己写的简单ARM bootloader

自己写的简单ARM bootloader

经过数个星期的研究,终于完成了一个能在TQ2440开发板上运行的简单bootloader,其实目前功能很简单,就是做一些初始化并在串口显示一段文字,好多功能还没有实现。

经过这一番―痛苦‖的过程,自己还是有一些感想的:多看源码所谓―书读百变,其意自现‖,读代码也是同样的道理。

多读几遍之后,你就会发现原来让你一看就烦躁、郁闷的代码,其实也并不那么难理解。

推荐看开发板提供给我们的代码,以及目前比较流行的通用bootloader(例如UBoot)。

多查文档对于写这种偏底层的开发,文档时必需的。

bootloader大部分的工作其实就是读写各种寄存器(或是某内存单元),其实有时令人郁闷的不是怎么设置一些值,而是查找这些值背后含义以及原理的过程。

文档上面写的清清楚楚,就看你能不能找到以及理解背后的原理。

多做试验bootloader还是很复杂的,一下子就把所有功能实现基于是不可能的。

那就要从一个最简单的功能做起,比如LED或是串口输出,以这个目标去做bootloader应该会比较容易实现。

可以把开发板提供给我们的bootloader仔细研究研究,注释掉一些功能,看看有什么影响,如果有影响,说明这段代码对于某个功能起了作用,这样可以把研究范围缩小。

下面就是bootloader的主要代码,供大家参考,欢迎留言讨论。

startup.s;CPSR[4:0]中各模式USRMODE * 0X10 ;用户模式FIQMODE * 0X11 ;FIQ模式IRQMODE * 0X12 ;IRQ模式SUPMODE * 0X13 ;管理模式ABTMODE * 0X17 ;中断模式UDFMODE * 0X1B ;未定义模式SYSMODE * 0X1F ;系统模式MODEMSK * 0X1F ;00011111 用于清除[4:0]NOINT * 0XC0 ;AIFT = 1100;The location of stacks_STACK_BASEADDRESS EQU 0×33ff8000USRSTACK EQU (_STACK_BASEADDRESS-0×3800) ;0×33ff4800 ~ SUPSTACK EQU (_STACK_BASEADDRESS-0×2800) ;0×33ff5800 ~ UDFSTACK EQU (_STACK_BASEADDRESS-0×2400) ;0×33ff5c00 ~ ABTSTACK EQU (_STACK_BASEADDRESS-0×2000) ;0×33ff6000 ~ IRQSTACK EQU (_STACK_BASEADDRESS-0×1000) ;0×33ff7000 ~ FIQSTACK EQU (_STACK_BASEADDRESS-0×0) ;0×33ff8000 ~;UPLLU_MDIV * 56U_PDIV * 2U_SDIV * 2M_MDIV * 92M_PDIV * 1M_SDIV * 1BIT_SELFREFRESH * 1<<22IMPORT |Image$$RO$$Base| ; Base of ROM codeIMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data) IMPORT |Image$$RW$$Base| ; Base of RAM to initialiseIMPORT |Image$$ZI$$Base| ; Base and limit of areaIMPORT |Image$$ZI$$Limit| ; to zero initialiseGET 2440addr.sGET memcfg.sAREA init, CODE, READONLYENTRYresetEntryB reset ;复位; B undefined_instruction ;未定义指令; B software_interupt ;软件中断; B prefetch_abort ;预取指令错误; B data_abort ;预取数据错误; B . ;保留中断向量; B irq ;irq异常; B fiq ;fiq异常EXPORT resetreset;关闭看门狗ldr r0, =WTCONldr r1, =0×0str r1, [r0];关闭所有中断ldr r0, =INTMSKldr r1, =0xFFFFFFFFstr r1, [r0]ldr r0, =INTSUBMSK ;关闭所有子中断ldr r1, =0×7FFFF ;INTSUBMSK只有[14:0]被使用str r1, [r0];初始化时钟ldr r0, =LOCKTIMEldr r1, =0xFFFFFFFFstr r1, [r0]ldr r0, =CLKDIVNldr r1, =5 ;1:4:8str r1, [r0]ldr r0, =UPLLCONldr r1, =(U_MDIV<<12) + (U_PDIV<<4) + U_SDIV ;Fin = 12MHz UCLK = 48MHz str r1, [r0]nop ; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed.nopnopnopnopnopnop;MPLLldr r0, =MPLLCONldr r1, =(M_MDIV<<12) + (M_PDIV<<4) + M_SDIV ;Fin = 12MHz PCLK =400MHzstr r1, [r0];工作在异步模式mrc p15,0,r0,c1,c0,0orr r0,r0,#0xc0000000mcr p15,0,r0,c1,c0,0;LED显示ldr r0,=GPBCONldr r1,=0×155500str r1,[r0]ldr r0,=GPBDATldr r1,=0×0str r1,[r0] ;LED=****;初始化SDRAMldr r0, =BWSCONldr r1,=(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16) +(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))str r1, [r0]ldr r0, =BANKSIZEldr r1, =0×32str r1, [r0]ldr r0, =REFRESHldr r1,=((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Tsrc<<18)+(Tchr<<16)+REFCNT) str r1, [r0]ldr r0, =MRSRB6ldr r1, =0×32str r1, [r0]bl InitStack;copy_proc_begadr r0, resetEntryldr r2, BaseOfROMcmp r0, r2beq Overldr r3, TopOfROMldmia r0!, {r4-r7}stmia r2!, {r4-r7}cmp r2, r3bcc %B0IMPORT MainOverbl Main ;C程序入口b . ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;初始化堆栈;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;InitStackmrs r0, cpsrbic r0, r0, #MODEMSK;初始化未定义模式栈orr r1, r0, #UDFMODE|NOINTmsr cpsr_cxsf, r1 ;cpsr_all = cpsr_cxsf ldr sp, =UDFSTACK;初始化FIQ栈orr r1, r0, #FIQMODE|NOINTmsr cpsr_cxsf, r1ldr sp, =FIQSTACK;初始化IRQ栈orr r1, r0, #IRQMODE|NOINTmsr cpsr_cxsf, r1ldr sp, =IRQSTACK;初始化ABORT栈orr r1, r0, #ABTMODE|NOINTmsr cpsr_cxsf, r1ldr sp, =ABTSTACK;初始化管理模式栈orr r1, r0, #SUPMODE|NOINTmsr cpsr_cxsf, r1ldr sp, =SUPSTACKmov pc, lrBaseOfROM DCD |Image$$RO$$Base|TopOfROM DCD |Image$$RO$$Limit|BaseOfBSS DCD |Image$$RW$$Base|BaseOfZero DCD |Image$$ZI$$Base|EndOfBSS DCD |Image$$ZI$$Limit|ENDmain.c#include "2440addr.h"#include <stdarg.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <ctype.h>int PCLK = 50000000; //50MHzvoid Port_Init(void){//CAUTION:Follow the configuration order for setting the ports.// 1) setting value(GPnDAT)// 2) setting control register (GPnCON)// 3) configure pull-up resistor(GPnUP)//32bit data bus configuration//*** PORT A GROUP//Ports : GPA22 GPA21 GPA20 GPA19 GPA18 GPA17 GPA16 GPA15 GPA14 GPA13 GPA12//Signal : nFCE nRSTOUT nFRE nFWE ALE CLE nGCS5 nGCS4 nGCS3 nGCS2 nGCS1 //Binary : 1 1 1 , 1 1 1 1 , 1 1 1 1//Ports :GPA11 GPA10 GPA9 GPA8 GPA7 GPA6 GPA5 GPA4 GPA3 GPA2 GPA1 GPA 0//Signal : ADDR26 ADDR25 ADDR24 ADDR23 ADDR22 ADDR21 ADDR20 ADDR19 ADDR18 ADDR17 ADDR16 ADDR0//Binary : 1 1 1 1 , 1 1 1 1 , 1 1 1 1 rGPACON = 0×7fffff;//**** PORT B GROUP//Ports :GPB10 GPB9 GPB8 GPB7 GPB6 GPB5 GPB4 GPB3 GPB2 GPB1 GPB 0//Signal : nXDREQ0 nXDACK0 nXDREQ1 nXDACK1 nSS_KBD nDIS_OFF L3CLOCK L3DATA L3MODE nIrDATXDEN Keyboard//Setting: INPUT OUTPUT INPUT OUTPUT INPUT OUTPUT OUTPUT OUTPUT OUTPUT OUTPUT OUTPUT//Binary : 00 , 01 00 , 01 00 , 01 01 , 01 01 , 01 01//rGPBCON = 0×000150;(youlong)rGPBCON = 0×015550;rGPBUP = 0×7ff; // The pull up function is disabled GPB[10:0]//*** PORT C GROUP for youlong//Ports : GPC15 GPC14 GPC13 GPC12 GPC11 GPC10 GPC9 GPC8 GPC7 GPC6 GPC5 GPC4 GPC3 GPC2 GPC1 GPC0//Signal : VD7 VD6 VD5 VD4 VD3 VD2 VD1 VD0 LCDVF2 LCDVF1 LCDVF0 VM VFRAME VLINE VCLK LEND//Binary : 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10//rGPCCON = 0xaaaaaaaa;//rGPCUP = 0xffff; // The pull up function is disabled GPC[15:0]//*** PORT C GROUP//Ports : GPC15 GPC14 GPC13 GPC12 GPC11 GPC10 GPC9 GPC8 GPC7 GPC6 GPC5 GPC4 GPC3 GPC2 GPC1 GPC0//Signal : VD7 VD6 VD5 VD4 VD3 VD2 VD1 VD0 LCDVF2 LCDVF1 LCDVF0 VM VFRAME VLINE VCLK LEND//Binary : 10 10 , 10 10 , 10 10 , 10 01 , 01 01 , 01 10 , 10 10 , 10 10rGPCCON = 0xaaa956aa;rGPCUP = 0xffff; // The pull up function is disabled GPC[15:0]//*** PORT D GROUP//Ports : GPD15 GPD14 GPD13 GPD12 GPD11 GPD10 GPD9 GPD8 GPD7 GPD6 GPD5 GPD4 GPD3 GPD2 GPD1 GPD0//Signal : VD23 VD22 VD21 VD20 VD19 VD18 VD17 VD16 VD15 VD14 VD13 VD12 VD11 VD10 VD9 VD8//Binary : 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 , 10 10 ,10 10 rGPDCON = 0xaaaaaaaa;rGPDUP = 0xffff; // The pull up function is disabled GPD[15:0]//*** PORT E GROUP//Ports : GPE15 GPE14GPE13 GPE12 GPE11 GPE10 GPE9 GPE8 GPE7 GPE6 GPE5 GPE4 //Signal : IICSDA IICSCL SPICLK SPIMOSI SPIMISO SDDATA3 SDDATA2 SDDATA1 SDDATA0 SDCMD SDCLK IN//Binary : 10 10 , 10 10 , 10 10 , 10 10 , 10 10 ,10 00 ,//——————————————————————————————————-//Ports : GPE3 GPE2 GPE1 GPE0//Signal : IN IN IN IN//Binary : 00 00 , 00 00//rGPECON = 0xaaaaaaaa;//rGPEUP = 0xffff; // The pull up function is disabled GPE[15:0]rGPECON = 0xa02aa800; // For added AC97 settingrGPEUP = 0xffff;//*** PORT F GROUP//Ports : GPF7 GPF6 GPF5 GPF4 GPF3 GPF2 GPF1 GPF0//Signal : nLED_8 nLED_4 nLED_2 nLED_1 nIRQ_PCMCIA EINT2 KBDINT EINT0//Setting: Output Output Output Output EINT3 EINT2 EINT1 EINT0//Binary : 01 01 , 01 01 , 10 10 , 10 10rGPFCON = 0×55aa;rGPFUP = 0xff; // The pull up function is disabled GPF[7:0]//*** PORT G GROUP//Ports : GPG15 GPG14 GPG13 GPG12GPG11 GPG10 GPG9 GPG8 GPG7 GPG6//Signal : nYPON YMON nXPON XMON EINT19 DMAMODE1 DMAMODE0 DMASTART KBDSPICLK KBDSPIMOSI//Setting: nYPON YMON nXPONXMON EINT19 Output Output Output SPICLK1 SPIMOSI1//Binary : 11 11 , 11 11 , 10 01 , 01 01 , 11 11//—————————————————————————————–//Ports : GPG5 GPG4 GPG3 GPG2 GPG1 GPG0//Signal : KBDSPIMISO LCD_PWREN EINT11 nSS_SPI IRQ_LAN IRQ_PCMCIA//Setting: SPIMISO1 LCD_PWRDN EINT11 nSS0 EINT9 EINT8//Binary : 11 11 , 10 11 , 10 10rGPGCON = 0×00a2aaaa;// GPG9 input without pull-uprGPGUP = 0xffff; // The pull up function is disabled GPG[15:0]//*** PORT H GROUP//Ports : GPH10 GPH9 GPH8 GPH7 GPH6 GPH5 GPH4 GPH3 GPH2 GPH1 GPH0 //Signal : CLKOUT1 CLKOUT0 UCLK nCTS1 nRTS1 RXD1 TXD1 RXD0 TXD0 nRTS0 nCTS0 //Binary : 10 , 10 10 , 11 11 , 10 10 , 10 10 , 10 10rGPHCON = 0×00faaa;rGPHUP = 0×7ff; // The pull up function is disabled GPH[10:0]// Added for S3C2440X, DonGo//*** PORT J GROUP//Ports :GPJ12 GPJ11 GPJ10 GPJ9 GPJ8 GPJ7 GPJ6 GPJ5 GPJ4 GPJ3 GPJ2 GPJ1 GPJ0//Signal : CAMRESET CAMPCLKOUT CAMHREF CAMVSYNC CAMPCLKIN CAMDAT[7] CAMDAT[6] CAMDAT[5] CAMDAT[4] CAMDAT[3] CAMDAT[2] CAMDAT[1] CAMDAT[0] //Binary : 10 10 10 10 10 10 10 10 10 1010 10 10rGPJCON = 0×02aaaaaa;rGPJUP = 0×1fff; // The pull up function is disabled GPH[10:0]//External interrupt will be falling edge triggered.rEXTINT0 = 0×22222222; // EINT[7:0]rEXTINT1 = 0×22222222; // EINT[15:8]rEXTINT2 = 0×22222222; // EINT[23:16]}void Uart_Init(int pclk,int baud){int i;if(pclk == 0)pclk = PCLK;rUFCON0 = 0×0; //UART channel 0 FIFO control register, FIFO disablerUFCON1 = 0×0; //UART channel 1 FIFO control register, FIFO disablerUFCON2 = 0×0; //UART channel 2 FIFO control register, FIFO disablerUMCON0 = 0×0; //UART chaneel 0 MODEM control register, AFC disablerUMCON1 = 0×0; //UART chaneel 1 MODEM control register, AFC disable//UART0rULCON0 = 0×3; //Line control register : Normal,No parity,1 stop,8 bits// [10] [9] [8] [7] [6] [5] [4] [3:2] [1:0] // Clock Sel, Tx Int, Rx Int, Rx Time Out, Rx err, Loop-back, Send break, Transmit Mode, Receive Mode// 0 1 0 , 0 1 0 0 , 01 01// PCLK Level Pulse Disable Generate Normal Normal Interrupt or PollingrUCON0 = 0×245; // Control registerrUBRDIV0=( (int)(pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0/*//UART1rULCON1 = 0×3;rUCON1 = 0×245;rUBRDIV1=( (int)(pclk/16./baud+0.5) -1 );//UART2rULCON2 = 0×3;rUCON2 = 0×245;rUBRDIV2=( (int)(pclk/16./baud+0.5) -1 );*/for(i=0;i<100;i++);}void Uart_SendByte(int data){if(data==‘\n‘){while(!(rUTRSTAT0 & 0×2));// Delay(1); //because the slow response of hyper_terminalWrUTXH0(‗\r‘);}while(!(rUTRSTAT0 & 0×2)); //Wait until THR is empty.// Delay(1);WrUTXH0(data);}void Uart_SendString(char *pt){while(*pt)Uart_SendByte(*pt++);}void Uart_Printf(char *fmt,…){va_list ap;char string[256];va_start(ap,fmt);vsprintf(string,fmt,ap);Uart_Printf(string);va_end(ap);}void Led_Display(int data){//Active is low.(LED On)// GPF7 GPF6 GPF5 GPF4//nLED_8 nLED4 nLED_2 nLED_1// rGPFDAT = (rGPFDAT & 0xf) | !((data & 0xf)<<4);// rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);//Active is low.(LED On)// GPF7 GPF6 GPF5 GPF4//nLED_8 nLED4 nLED_2 nLED_1// rGPFDAT = (rGPFDAT & 0xf) | !((data & 0xf)<<4);rGPBDAT = (rGPBDAT & ~(0xf<<5)) | ((~data & 0xf)<<5);//rGPCDAT = (rGPBDAT & ~(0xf<<5)) | ((~data & 0xf0)<<5); }char* msg = "Hello, embedded!\n";int Main (){Led_Display(10);Port_Init();Uart_Init(0, 115200);Uart_SendString(msg);return 0;}。

基于STM32的简易Bootloader实现

基于STM32的简易Bootloader实现

基于STM32的简易Bootloader实现⼀、背景 公司在开发⼀款智能眼镜,使⽤STM32L0系列芯⽚作为主控芯⽚,蓝⽛连接,总体来说不是很复杂。

在发给客户测试的时候发现了⼀些问题,需要重新更新程序。

这在开发⼈员看来只要两三下的事情,在客户⼿⾥可能就是⼀个巨⿇烦的事情。

所以决定给设备添加在线升级功能,通过蓝⽛将新的固件更新到主控芯⽚⾥,⽽bootloader就是OTA中不可或缺的⼀部分。

⼆、实现思路 bootloader其实就是⼀段启动程序,它在芯⽚启动的时候⾸先被执⾏,它可以⽤来做⼀些硬件的初始化,当初始化完成之后跳转到对应的应⽤程序中去。

我们可以将内存分为两个区,⼀个是启动程序区(0x0800 0000 - 0x0800 2000 )⼤⼩为8K Bytes,剩下的为应⽤程序区(0x0800 2000 -0x0801 0000)。

芯⽚上电时先运⾏启动程序,然后跳转到应⽤程序区执⾏应⽤程序。

三、程序跳转 bootloader⼀个主要的功能就是⾸先程序的跳转。

在STM32中只要将要跳转的地址直接写⼊PC寄存器,就可以跳转到对应的地址中去。

怎么实现呢? 当我们实现⼀个函数的时候,这个函数最终会占⽤⼀段内存,⽽它的函数名代表的就是这段内存的起始地址。

当我们调⽤这个函数的时候,单⽚机会将这段内存的⾸地址(函数名对应的地址)加载到PC寄存器中,从⽽跳转到这段代码来执⾏。

那么我们也可以利⽤这个原理,定义⼀个函数指针,将这个指针指向我们想要跳转的地址,然后调⽤这个函数,就可以实现程序的跳转了。

代码如下:#define APP_ADDR 0x08002000 //应⽤程序⾸地址定义typedef void (*APP_FUNC)(); //函数指针类型定义APP_FUNC jump2app; //定义⼀个函数指针jump2app = ( APP_FUNC )(APP_ADDR + 4); //给函数指针赋值jump2app(); //调⽤函数指针,实现程序跳转 上⾯的代码实现了我们要的跳转功能,但是为什么要跳转到(APP_ADDR + 4)这个地址,⽽不是APP_ADDR 呢? ⾸先我们要了解主控芯⽚的启动过程。

BOOTLOADER编写实验-ext

BOOTLOADER编写实验-ext

博创科技 嵌入互动
BootLoader 的移植和修改 对于两块不同的嵌入式板而言,即使它们是基于同一种 CPU而构建的,如果他们的硬件资源和配置不一致的话, 要想让运行在一块板子上的BootLoader程序也能运行在另 一块板子上,也还是需要作一些必要的修改。
© 2005 博创科技

基础知识
博创科技 嵌入互动
© 2005 博创科技
博创科技 嵌入互动
四、初始化有特殊要求的端口,设备 五、初始化应用程序执行环境 映像一开始总是存储在ROM/Flash里面的,其RO部分即可以在ROM/ Flash里面执行,也可以转移到速度更快的RAM中执行;而RW和ZI这两 部分是必须转移到可写的RAM里去。所谓应用程序执行环境的初始化, 就是完成必要的从ROM到RAM的数据传输和内容清零。

基础知识
博创科技 嵌入互动
BOOTLOADER的基本概念 的基本概念
从而将系统的软硬件环境带到一个合适的状态, 以便为最终调用操作系统内核或用户应用程序准 备好正确的环境。 通常,BootLoader 是依赖于硬件而实现的,特 别是在嵌入式领域,为嵌入式系统建立一个通用 的 BootLoader 是很困难的。
© 2005 博创科技
博创科技 嵌入互动
三、初始化堆栈 因为ARM有7种执行状态,每一种状态的堆栈指针寄存器(SP)都是独立 的。因此,对程序中需要用到的每一种模式都要给SP定义一个堆栈地址。 方法是改变状态。注意:不要切换到User模式进行User模式的堆栈设置,因为进 入User模式后就不能再操作CPSR回到别的模式了,可能会对接下去的程 序执行造成影响。
© 2005 博创科技

基础知识
博创科技 嵌入互动

bootloader的编写

bootloader的编写

bootloader的编写
编写一个 bootloader 是一个底层任务,需要对计算机硬件和操
作系统的工作原理有深入的了解。

下面是一个简单的bootloader 编写示例。

1. 使用汇编语言编写代码:bootloader 需要使用汇编语言编写,因为它是操作系统加载和启动的第一个阶段。

2. 设置处理器状态:在 bootloader 的开头部分,需要设置处理
器状态,包括设置堆栈指针和其他相关的寄存器。

3. 初始化硬件:在 bootloader 中,需要初始化计算机硬件,如
内存控制器、显示器、键盘等设备。

4. 加载操作系统:bootloader 的主要任务是加载操作系统,它
需要从磁盘或其他存储介质中读取操作系统的二进制代码,并将其加载到内存中的指定地址。

5. 跳转至操作系统:一旦操作系统的二进制代码加载到内存中,bootloader 需要跳转到操作系统的入口点,将控制权交给操作
系统。

注意事项:
- 由于不同的计算机架构和操作系统可能有不同的要求,编写bootloader 需要根据具体的硬件和操作系统平台进行调整。

- 在编写 bootloader 时要小心使用硬编码的内存地址,因为这
些地址可能与操作系统或其他程序的内存地址冲突。

- 需要仔细测试 bootloader 的正确性,以确保其能正确加载和跳转到操作系统。

在实践中编写 bootloader 是一个复杂的任务,需要有一定的编程经验和对计算机硬件和操作系统的深入了解。

因此,如果你不熟悉这些概念或没有相关经验,最好参考已有的 bootloader 实现或使用现成的解决方案。

bootloader的编写

bootloader的编写

bootloader的编写[Bootloader的编写]引言:在计算机系统中,所有软件程序的启动都需要从硬件开始,即从计算机的引导加载程序(bootloader)开始。

Bootloader是计算机系统中的第一个程序,它位于计算机的非易失性内存(ROM或闪存)中,负责将操作系统加载到计算机的内存中并进行初始化。

本文将一步一步回答关于Bootloader的编写的问题,帮助读者了解Bootloader的基本原理和编写过程。

一、什么是Bootloader?Bootloader是指位于计算机系统启动过程中的第一个可执行程序,它负责初始化硬件设备、加载操作系统并将控制权交给操作系统。

在引导加载过程中,计算机会首先执行Bootloader程序,然后再按照一定的规则将操作系统加载到内存中并启动它。

二、为什么需要编写Bootloader?编写Bootloader的目的是为了在计算机系统启动时对硬件进行初始化,并将操作系统加载到内存中。

Bootloader起到了桥梁的作用,将硬件和操作系统连接起来。

此外,编写Bootloader还可以添加一些自定义功能,如双重引导、数据恢复等。

三、Bootloader的基本原理是什么?Bootloader编写的基本原理包括以下几个方面:1. 硬件初始化:Bootloader首先需要对计算机的硬件设备进行初始化,包括处理器、内存、外设等。

这些初始化工作是确保计算机能够正常启动的基础。

2. 加载操作系统:Bootloader需要加载操作系统的二进制映像文件(通常是内核文件)到内存中。

这需要通过读取硬盘或其他存储设备上的引导块或分区来完成。

3. 进入操作系统:一旦操作系统加载到内存中,Bootloader将控制权交给操作系统,让其接管计算机的控制。

四、如何编写Bootloader?编写Bootloader的过程可以分为以下几个步骤:1. 了解目标硬件:首先需要了解目标计算机的硬件平台和体系结构,包括处理器类型、内存布局、外设接口等。

bootloader的开发

bootloader的开发

◆OEMReadData ()
●从传输端口读取指定数目的数据到调用者指定的缓冲区 中。该函数最终调用的还是函数OEMEthGetFrame
◆OEMEthGetFrame () //从网卡读取数据
●调用库函数pfnEDbgGetFrame
◆OEMEthSendFrame () //写数据到网卡
●调用库函数pfnEDbgSendFrame
◆ OEMStartEraseFlash()
●初始化FLASH存储器的擦除过程
◆ OEMFinishEraseFlash()
●写OS镜像时调用,以所需要的FLASH存储空间是否完全擦除
◆ OEMContinueEraseFlash()
●下载过程中不断调用该函数,继续对FLASH进行擦缓冲区,这样就可以保证 所有全局缓冲区共享数据都位于同一个RAM页中。
主函数main()的设计与实现
●由Startup()函数调用,C语言代码的入口点,在该函数中调 用Blcommon库中的BootLoaderMain()函数. ●为实现BootLoader的Main()函数,须执行以下操作: 在目录 %_WINCEROOT%\Platform\MyPlatform\Src\BootLoader\Eb oot下创建一个名为Main.c的文件 ●在Main.c文件中实现如下代码: void main(void) { BootLoaderMain (); SpinForever(); }
控制流函数的实现
BootLoader的控制流函数有以下几个: ◆ OEMPlatformInit ()
●完成平台特定的初始化,包括实时时钟、Flash存储器、 网络适配器等
◆ OEMPreDownload ()

毕设级项目:基于单片机从零写bootloader

毕设级项目:基于单片机从零写bootloader

毕设级项目:基于单片机从零写bootloader一、概述在一个计算机系统中,引导加载程序(Bootloader)是为了引导操作系统或其他软件的一种特殊程序。

它负责在系统上电初始化之后,加载并执行操作系统内核或其他程序。

在嵌入式系统中,单片机起到了非常重要的作用。

因此,编写一个基于单片机的Bootloader是一项非常有意义的毕设项目。

二、单片机选择在选择单片机时,我们需要考虑一些因素,例如性能、功耗、扩展性等。

常见的单片机厂商有Microchip(美国)、NXP (荷兰)、STMicroelectronics(法国)等。

根据实际需求选择一款支持Bootloader开发的单片机。

三、Bootloader的功能1. 初始化硬件:Bootloader首先需要对单片机的硬件资源进行初始化操作,包括时钟配置、外设初始化、中断设置等。

2. 读取外部存储器:Bootloader需要读取外部存储器中的程序代码,这可以是Flash、EEPROM、SD卡等。

3. 检查程序完整性:在加载程序代码之前,Bootloader可以通过计算校验和或者进行散列计算等方法,对程序的完整性进行检查。

4. 加载程序代码:Bootloader从外部存储器中读取程序代码,并将其加载到内部存储器中,如RAM或Flash中。

5. 跳转到程序代码:加载完程序代码之后,Bootloader会将控制权转交给操作系统或其他程序,从而开始执行相应的程序。

四、编写Bootloader的步骤1. 硬件初始化:使用单片机的寄存器设置时钟源、时钟分频器、外部设备的初始化等。

2. 系统初始化:设置堆栈、全局变量初始化等。

3. 外部存储器读取:根据硬件接口和通信协议,读取外部存储器中的程序代码。

4. 完整性检查:对读取的程序代码进行校验和检查。

5. 程序加载:将程序代码加载到相应的内存位置。

6. 跳转执行:通过跳转指令将控制权转交给所加载的程序。

五、Bootloader的扩展功能1. 烧录新程序:通过串口、USB或SD卡等外设,实现对程序代码的更新烧录。

最简单的bootloader的编写步骤

最简单的bootloader的编写步骤

最简单的bootloader的编写步骤
 内核从板载启动的bootargs--内核启动参数,bootargs 是bootloader 传递给内核的启动字符串。

 BootLoader的目标是启动内核,大多数boot loader 都包含两种不同的操作模式:”启动加载”模式和”下载”模式。

 在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。

可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。

在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。

在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader程序。

常见的BootLoader程序如下:
 最简单的bootloader的编写步骤:
 1). 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH。

bootloader流程2

bootloader流程2

1.硬件初始化和系统引导完整的Bootloader引导流程可描述如下:硬件初始化阶段一-> 复制二级Exception Vector Table -> 初始化各种处理器模式-> 复制RO和RW,清零ZI -> (跳转到C代码入口函数) -> 初始化Exception/Interrupt Handler Entry Table -> 初始化Device Drivers -> 硬件初始化阶段二-> 建立人机界面下面对上述各步骤逐一加以说明。

1.1 硬件初始化阶段一板子上电或复位后,程序从位于地址0x0的Reset Exception Vector处开始执行,因此需要在这里放置Bootloader的第一条指令:b ResetHandler,跳转到标号为ResetHandler处进行第一阶段的硬件初始化,主要内容为:关Watchdog Timer,关中断,初始化PLL和时钟,初始化Memory Controller。

比较重要的是PLL的输出频率要算正确,这里把它设置为50MHz;后面在计算SDRAM的Refresh Count和UART的Baud Rate等参数时还要用到。

1.2 复制二级Exception Vector TableException Vector Table是Bootloader与uClinux Kernel发生联系的地方之一(另两处是加载and/or调用Kernel,以及向Kernel传递启动参数)。

ARM7规定Exception Vector T able 的基地址是0x0,所以Flash Memory的基地址也必须是0x0;而S3C44B0X处理器又不支持Memory Remap,这意味着无论运行什么样的上层软件,一旦发生中断,程序就得到Flash Memory中的Exception Vector Table里去打个转(中断Interrupt是异常Exception的一种)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

最简单的bootloader的编写步骤
内核从板载启动的bootargs--内核启动参数,bootargs 是bootloader 传递给内核的启动字符串。

BootLoader的目标是启动内核,大多数boot loader 都包含两种不同的操作模式:"启动加载"模式和"下载"模式。

在嵌入式操作系统中,BootLoader是在操作系统内核运行之前运行。

可以初始化硬件设备、建立内存空间映射图,从而将系统的软硬件环境带到一个合适状态,以便为最终调用操作系统内核准备好正确的环境。

在嵌入式系统中,通常并没有像BIOS那样的固件程序(注,有的嵌入式CPU也会内嵌一段短小的启动程序),因此整个系统的加载启动任务就完全由BootLoader来完成。

在一个基于ARM7TDMI core的嵌入式系统中,系统在上电或复位时通常都从地址0x00000000处开始执行,而在这个地址处安排的通常就是系统的BootLoader 程序。

常见的BootLoader程序如下:
最简单的bootloader的编写步骤:
1). 初始化硬件:关看门狗、设置时钟、设置SDRAM、初始化NAND FLASH
1.关看门狗:2440的开发板一上电看门狗是打开的,不关闭的话每三秒就会复位一次开发板。

看门狗的地址为:0x53000000
2.设置时钟:CLKDVIN寄存器的地址为0x4c000014,必须设置为异步模式,这是datasheet 所规定的。

注:
判断从nand启动还是nor启动就往内存中写数据即可,之后看是否能从内存相应地址读出对应的值。

相关文档
最新文档