Blob在S3C44B0上的移植

摘要:bootloader是嵌入式系统软件开发的第一个环节,它紧密地将软硬件衔接在一起,对于一个嵌入式设备后续的软件开发至关重要。blob是一款功能强大的bootloader,s3c44b0是三星公司一款基于arm7tdmi的嵌入式通用处理器。本文详细介绍blob在基于s3c44b0的开发板上的运行原理与移植过程。
bootloader对于嵌入式设备来说至关重要,它涉及到许多硬件相关的知识。对于自制的嵌入式开发板,它又是不可跳过的步骤,所以很多人对于它感到很头痛。本文将以一款优秀的bootloader blob为例,详细讲解它的运行原理以及在s3c44b0通用处理器上的移植过程,为在嵌入式设备上的后续软件开发打下基础。
1 blob简介
blob是boot loader object的缩写,是一款功能强大的bootloader。它遵循gpl,源泉代码完全开放。blob既可以用来简单的调试,也可以启动linux kernel。blob最初是jan-derk bakker和erik mouw为一块名为lart(linux advanced radio terminal)的板子写的,该板使用的处理器是strongarm sa-1100。现在blob已经被移植到了很多cpu上,包括s3c44b0。
mba44b0是一款基于s3c44b0的开发板。本文将以运行在mba44b0开发板上的blob的源代码为基础,再针对自己的开发板进行blob的移植。
开发板的主要配置为:
*三星arm7处理器s3c44b0;
*2mb的flash,地址范围0x0000 0000~0x0020 0000;
*8mb的sdram,地址范围0x0c00 0000~0x0c80 0000;
*1个串口,2个led灯;
*jtag接口;
*晶振为6mhz,系统主频为60mhz。
2 blob的运行过程分析
图1为blob程序启动流程
blob编译后的代码定义最大为64kb,并且这64kb又分成两个阶段来执行。第一阶段的代码在start.s中定义,大小为1kb,它包括从系统上电后在0x00000000地址开始执行的部分。这部分代码运行在flash中,它包括对s3c44b0的一些寄存器的初始化和将blob第二阶段代码从flash拷贝到sdram中。除去第一阶段的1kb代码,剩下的部分都是第二阶段的代码。第二阶段的起始文件为trampoline.s,被复制到sdram后,就从第一阶段跳到这个文件开始执行剩余部分代码。第二阶段最大为63kb,单词trampoline词义为“蹦床”,所以在这个程序中进行一些bss段设置,堆栈的初始化等工作后,最后跳转到main.c进入c函数。
我们的移植主要需要对上述的几个文件进行修改。在进行移植以前,首先需要对存储器的地址空间分配了解清楚。关于存储器空间的定义在/include/blob arch/mba44b0.h中。
图2为在flash中的存储器空间分布,图3为启动后在sdram中的存储器空间分布。
如图2所示,2mb的flash空间分别分配给出blob、kernel、ramdisk。系统上电后,先执行第一阶段代码,进行相应的初始化后,将blob第二阶段代码复制的ram地址bloc_abs_base,然后跳转到第二阶段开始执行。
在第二阶段中,从汇编跳转到c的main()函数,继续进行如下工作:
*外围的硬件初始化(串口,usb等);
*从flash中将kernel加载到sdram的kernel区域;
*从flash中的ramdisk加载到sdram的ramdisk区域;
*根据用户选择,进入命令行模块或启动kernel。
在我们使用的开发板上,kernel选用uclinux。由于flash的存储空间有限,所以存放在flash中的uclinux内核是经过压缩的。blob将压缩的uclinux内核加载到sdram地址0x0c300000。如果选择启动uclinux,那么压缩的uclinux内核将自解压.text段到0x0c00800(见uclinux/arch/armnommu/makefile),然后再跳转到核处,开始运行uclinux。具体的uclinux移植在此就不详细讨论了。
在sdram的存储器空间分配图中,可以看到有blob_base和blob_abs_base两部分。blob_abs_base大家已经知道了,是blob将自身的第二阶段代码复制到sdram所在的区域,而blob_base则是从blob进行自升级或调试的区域。举例说明,假如blob已经能正常运行了,但是对于flash的擦写还不能支持得很好,就可以使用已经运行的blob通过串口将所新编译好的blob下载到sdram中该区域进行运行调试。调试通过后,可以通过blob烧写进flash,覆盖原来的blob进行升级。这样就不必因为对blob做了一点小的改动就重新烧写flash,从而减少了烧写flash的次数。
3 blob的移植
对blob的运行有了一定了解后,就可以进行blob的具体移植了。首先要修改的start.s文件,具体工作如下:
*屏蔽掉看门狗wtcon;
*配置寄存器syscfg暂时关闭缓存,等blob运行稳定后再开启提高性能;
*初始化i/o寄存器;
*屏蔽中断;
*配置pllcon寄存器,决定系统的主频;
*调用ledasm.s,在串口未初始化时led状态对于程序是否正常运行很重要;
*调用memsetup-s3c44b0.s中的memsetup进行初始化存储器空间,初始化sdram刷新速率等;
*将第二阶段复制到sdram,并且跳转到第二阶段。
在ledasm.s中,提供了led的汇编的语言驱动程序。在blob还有个led.c文件,它和ledasm.s原理一样,只不过是在c语言中调用的。修改led是为了方便初期阶段的调试。在这里根据自己的开发板进行修改。
在memsetup-s3c44b0.s中,修改memory_config中设置存储器相关的配置,并设定sdram刷新速度,相关源码如下所示:
memory_config:
.long 0x11101002 /*进行存储器的配置,sdram刷新速度配置等*/
… /*这里需要根据不同情况进行修改*/
.long 0x20
.globl memsetup /*定义全局标号,以便能被start.s调用*/
memsetup:
ldr r0,=memory_config /*进行配置*/
ldmia r0,{r1-r13}
ldr r0,=0x01c80000
stmia r0,{r1-r13}
mov pc,lr /*程序返回*/
trampoline.s不需要进行修改。
进入main()后,串口传输速度在结构体blob_status中设定:
blob_status.downloadspeed=baud_115200;
blob_status.terminalspeed=baud_115200;
串口的初始化相关代码定义在函数s3c44b0_serial_init()中,该函数在serial-s3c44b0.c中。对于s3c44b0的串口,一般只需要初始化下面四个寄存器串口就可以正常工作。如果不能工作,可能是系统时钟设置不同,只需要按照下列公式计算出divisor:
divisor=(int)(mclk/(baud×16)) -1
替换下面的divisor即可。其中mclk为系统主频,baud为波特率。
/*serial-s3c44b0.c中中s3c44b0_serial_init()函数初始化串0部分*/
reg(ufcon0)=0x0;/*关闭fifo*/
reg(ulcon0)=0x03;/*设置数据位8,无奇偶校验,1位停止位*/
reg(ucon0)=0x0;/*脉冲中断,中断请求或查询模式*/
reg(ubrdiv0)=divisor;/*设置波特率*/
至此,初级移植工作已经完成,运行./configure ith-board=mba-44b0-with-linux-prefix=/path/to/linux-src进行相关配置。在此还可以加一些开关选项进行配置,具体请参阅blob自带文档。如果没有错误,就可以make进行编译了。如果编译正确,可在blob/src/blob下得到bin格式的blob,将其烧写到flash即可运行。关于blob第一部分和第二部分的链接脚本,可以在start-ld-script和rest-ld-script.in中看到相关的链接地址,编译器是根据这些地址链接程序的。在blob/src/blob/makefile中可以看到,两个阶段分别以blob-start和blob-rest来编译,最后通过dd命令将它们组成一个完事的blob二进制文件。
(1)命令行的修改
在笔者使用的blob版本中,backspace不能起作用,这对于调试非常的不方便。查阅源码,可以发现在src/blob/lib/command.c中,getcommand函数中定义着人机交互部分。将else if(c==''这一行修改为else if(c==0x7f),即可支持backspace功能。
(2)blob的运行
如果在前面的工作中没有什么问题的话,将blob/src/blob/blob文件烧写进flash后,上电就可以从串口看到欢迎信息。加载linux内核和文件系统的后,等待几秒,如果没有操作,将启动操作系统,否则出现提示符:
blob>
表示进入blob。在该模式下提供了许多命令,可以方便地进行硬件调试、系统升级和系统引导。
blob常用的命令有:blob、boot、xdownload、flashreload、dump、reblob、status等。
不同的flash操作有所不同。笔者发现通过blob烧写flash的软件有些问题,为了调试方便,决定编写自已的flash驱动程序。
(3)flash驱动程序的编写
flash作为非易失性的存储器,在开发板上的作用是能保存数据且掉电不丢失。和eprom最大的不同在于,对flash编程不需要对特定的引脚加高电平,只是对特定地址写入一组特定的数据即可进行编程,这样就直接在开发板上通过软件进行擦写,不必使用特定的编程器。但是它的缺点也是很明显的:操作过于复杂,sst39vf160是sst公司的一款16m位的flash,16位数据线宽度,共2mb容量,分为512个扇区,每个扇区有4kb,或32个块(block),每个块64kb。对flash编程之前,必须对相应的扇区、块或者整个芯片进行擦除后,才能进行编程。
通过s3c44b0进行flash的烧写需要注意几点:首先,s3c44b0外部地址总线是根据外部数据总线宽度连接的。例如,本开发板外部数据总线为16位宽度,这样s3c44b0的地址线a0就没有接入外部地址总线,而是从a1接起。
对flash编程需要对flash写入一个特定的时序。如果s3c44b0寻址0x5555,由于外部总线错了一位,这样在flash看来发过来的地址信号是0xaaaa,也就不能正确地完成操作。注意到这一点,根据blob自带的flash驱动程序,就可以很方便地改写出适合自己flash驱动程序。
结语
根据笔者经验介绍了blob在s3c44b0上的移植,目前它已经能稳定地运行在开发板上;并且可以进行烧写flash,查看内存,引导uclinux等操作,为项目的后续开发奠定了良好的基础。

这么像!小米5c是要模仿苹果?
EDP转LVDS屏转换方案 CS5211直接替代LT7211
机器学习模型类型分类
曝苹果自研基带将支持超快毫米波5G
魅族16T今日发布,延续经典对称式全面屏设计
Blob在S3C44B0上的移植
你以为共模电感选型只是简单的选个型号吗gujing
如何正确使用与日常维护铝壳电机?
比亚迪半导体推出智能摄像机Ahome Q1 采用自主研发的图像传感器
哈勃望远镜发现飞碟,与我们距离有约8500万光年
RL究竟是如何与LLM做结合的?
分类问题训练的GAP-CNN在目标定位方面的能力
自制示温蜡片和热敏变色漆,Thermal Paint
处于困境的特斯拉海外建厂之路能否顺利?
点焊机的性能特点以及技术参数的介绍
浅谈特斯拉对毫米波雷达的应用
百度大脑赋能清玄科技打造矿业智能化安全生产风控系统
大屏等离子技术或成突破口
超频版SoC的由来 值得关注的超频版SoC
致远微电子首款多媒体控制和图像显示应用的高集成度芯片