Android培训班(86)内核运行之前的引导程序

发布者:纯真年代最新更新时间:2024-10-21 来源: cnblogs关键字:Android  引导程序 手机看文章 扫描二维码
随时随地手机看文章

Android系统的内核要加载并运行,其实是经历了千辛万苦的,因为万事开头难。在一个系统刚开始时,并没有什么资源可以使用,CPU只认得0x00000000地址,并从那里运行第一条指令,并且这段代码有大小限制,不可以很大。因此需要开发一个引导程序放在那里运行,在这里的培训课程里,主要使用是S3C6410开发板,并且使用UBoot作为引导程序(Bootloader)。UBoot是一个很通用的引导程序,并且在嵌入式系统的应用里非常广泛,功能也相当强大,设计的架构相当灵活,很方便移植到不同的嵌入式设备里。


从前面知道ARM的CPU是固定从0x00000000开始运行的,那么UBoot的编译出来的大小,是放不到0x00000000的内存空间的,那么UBoot又是怎么样获得控制权呢?其实在S3C6410里可以通过CPU的管脚设置不同的电平,可以选择运行CPU内部的程序,然后让这段小程序加载UBoot到合适地址运行。那么接着下来的问题就是UBoot放到那里才是合适的地址?要理解这个合适地址,就需要看S3C6410的手册了,通过阅读这个手册,就会发现CPU的内存是固定在两个地址空间,如下:

0x50000000--0x5FFFFFFF 大小为256M

0x60000000--0x6FFFFFFF 大小为256M

由此可知,所有内存RAM都必须放到这段地址空间,也就是物理地址空间,因此UBoot就必须加载到这段内存空间里才可以运行,那么UBoot在编译时是否需要知道在那里运行呢?答案是需要的。UBoot运行时,有很多数据是需要找到对内存地址寻址。在UBoot编译时,就作出如下指定:

TEXT_BASE= 0xc7e00000

哗,这里的地址为什么是0xc7e00000的呢?难道是写错了吗?其实这里是大有文章的,与其相关的内容就是MMU了,所谓的MMU就是一个内存映射的硬件,主要作用就是把无限的虚拟内存地址空间映射到有限的物理内存地址空间,作用就是复用物理内存,方便编译所有软件。由此可知,UBoot是编译到虚拟地址0xc7e00000运行,在未有开启MMU之前,它的物理地址是0x57e00000,其实在物理地址上来看来是同一个地方。


从前面的可以知道UBoot真实运行的物理地址是0x57e00000,相对应的虚拟地址是0xc7e00000,这段地址相对于256内存来说是一个高端地址,为什么要放到这个地址运行,而不放到0x50000000的物理地址(虚拟机地址0xC0000000)运行呢?其实这是为了后面的内核linux运行做好准备,否则就会相互打架,整个系统运行就出错。从UBoot编译后的内存映像文件可以看到相关信息:

c7e00000T _start

c7e00020t _undefined_instruction

c7e00024t _software_interrupt

c7e00028t _prefetch_abort

c7e0002ct _data_abort

c7e00030t _not_used

c7e00034t _irq

c7e00038t _fiq

c7e0003ct _pad

c7e00040T _end_vect

c7e00040t _TEXT_BASE

c7e00044t _TEXT_PHY_BASE

c7e00048T _armboot_start

c7e0004cT _bss_start

c7e00050T _bss_end

c7e00054t reset


这段映像文件就说明所有开始代码都是相对0xc7e00000开始的,包括所有数据访问。在UBoot的MMU配置里,用下面的代码来把物理地址0x50000000映射到虚拟地址0xc0000000,如下:

//128MB for SDRAM 0xC0000000 -> 0x50000000

.set__base, 0x500

.rept0xD00 - 0xC00

FL_SECTION_ENTRY__base,3,0,1,1

.set__base,__base+1

.endr


引导程序加载运行,做好充分准备之后就可以加载内核运行了。它加载内核地址也是有讲究的,一般linux内核需要加载在0x50008000的物理地址开始,因此虚拟地址就是0xc0008000了,这样就可以把内核加载在低端运行,高端地址就可以给所有应用程序运行了。


总结一下,CPU从0x00000000开始运行Flash的程序,然后把UBoot重定位到物理地址0x57e00000(虚拟地址0xc7e00000)运行,然后打开MMU,就对应在虚拟地址0xc7e00000运行,然后加载内核到虚拟地址0xc0008000(物理地址0x50008000),然后再跳到这个地址里运行,因此UBoot要指定虚拟地址0xc7e00000作来连接程序的基地址。


下面是UBoot加载内核并运行的代码片段:

voiddo_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],

ulong addr, ulong *len_ptr, intverify)

{

#ifdefCONFIG_CMDLINE_TAG

char *commandline = getenv('bootargs');//取得内核启动参数

#endif


theKernel = (void (*)(int, int,uint))ntohl(hdr->ih_ep);//在mkimage.c里面指定的内核入口地址


/*

* Check if there is an initrd image

*/

if (argc >= 3){//检测initrd临时要文件系统,包括:magicnumber,头和数据的crc校验,和前面类似

SHOW_BOOT_PROGRESS (9);


addr = simple_strtoul (argv[2], NULL,16);//取得initrd的地址,下面检测过程类似内核

}


if (data) {

initrd_start = data;

initrd_end = initrd_start + len;

}



//下面开始向内核传递参数

#ifdefined (CONFIG_SETUP_MEMORY_TAGS) ||

defined (CONFIG_CMDLINE_TAG) ||

defined (CONFIG_INITRD_TAG) ||

defined (CONFIG_SERIAL_TAG) ||

defined (CONFIG_REVISION_TAG) ||

defined (CONFIG_LCD) ||

defined (CONFIG_VFD)

setup_start_tag (bd);

#ifdefCONFIG_SERIAL_TAG

setup_serial_tag (¶ms);

#endif

#ifdefCONFIG_REVISION_TAG

setup_revision_tag (¶ms);

#endif

#ifdefCONFIG_SETUP_MEMORY_TAGS

setup_memory_tags (bd);

#endif

#ifdefCONFIG_CMDLINE_TAG

setup_commandline_tag (bd, commandline);

#endif

#ifdefCONFIG_INITRD_TAG

if (initrd_start && initrd_end)

setup_initrd_tag (bd, initrd_start,initrd_end);

#endif

#ifdefined (CONFIG_VFD) || defined (CONFIG_LCD)

setup_videolfb_tag ((gd_t *) gd);

#endif

setup_end_tag (bd);

#endif


/* we assume that the kernel is in place */

printf ('nStarting kernel ...nn');


cleanup_before_linux ();//启动内核之前需要进行的设置


theKernel (0, bd->bi_arch_number,bd->bi_boot_params);//启动内核,uboot使命到此全部完成.

}



关键字:Android  引导程序 引用地址:Android培训班(86)内核运行之前的引导程序

上一篇:ARM——栈
下一篇:开发可统计单词个数的Android驱动程序(3)

推荐阅读最新更新时间:2026-03-25 12:15

关于STM32 ST-LINK Utility查看内核运行状态,助你判断程序是否跑飞
本文围绕STM32 ST-LINK Utility讲几点主要功能及相关拓展知识: 1.STM32编程下载; 2.利用该编程工具查看内核运行状态; 3.Option Bytes选项字配置; 1STM32编程下载 STM32 ST-LINK Utility一个最重要的功能就是对STM32进行编程。支持常见的hex、bin文件,还有早期摩托罗拉定义的srec和s19格式的文件(说实话,我都不了解这两种格式的文件)。 这里主要想提示一下初学者:hex带有地址,而bin文件不带地址,下载时需要填写起始地址。 下面看两张在STM32 ST-LINK Utility中下载选择文件的图大家就明白了。 1.选择hex下载,地址不可修改(灰色)
[单片机]
关于STM32 ST-LINK Utility查看<font color='red'>内核</font><font color='red'>运行</font>状态,助你判断<font color='red'>程序</font>是否跑飞
mini2440内核停在booting the kernel问题以及无法运行linuxrc问题的解决方法
这几天在2440板子上面移植2.6.32.2的内核,用的现成的uboot,但是每次uImage自解压之后就卡住了,booting the kernel然后就没有下文了,高了半天才发现制作uImage出了问题,我直接make uImage生成的uImage,也不知道是不是uboot里面的mkimage工具生成uImage的时候抽风了,最后还是保险地自己用mkimage工具生成uImage: mkimage -n 'mini2440' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008000 -d zImage uImage 然后内核启动就没有问题了
[单片机]
ARM内核目标系统中的代码运行时间测试
  在ARM系统中,有时需要精确的时间测量。通常,取时间的C函数(如gettime()等)不仅通用性差(必须包含头文件DOS.H,且不支持Unix、Linux和标准C),明显不适用于ARM系统 ;更成问题的是,其最短时间只能到10-2 秒级,不能提供更短的时间分度。根本原因在于: 这类函数是基于系统实时时钟(RTC)的,而RTC通常采用标准化钟表晶振,频率只有32.768 kHz而已 。   然而很多应用涉及μs级的时间计量,这是标准化了的RTC以及基于它的时间函数所无能为力的。笔者在移植DES算法到ARM系统的实验过程中,便遇到过要定量评估加密算法耗时多少的问题,发现的确不能用上述常规的C函数解决。经对ARM芯片结构的
[单片机]
基于DM642的FLASH分页二级引导程序设计
基于DM642的FLASH分页二级引导程序设计 0 引 言 TMS320DM642是TI公司推出的一款高性能的数字多媒体处理器,具有二级存储器和高速缓冲器,以及超长指令字结构。其运算速度快、体积小、功耗低的优点使得它在多媒体处理领域得到了广泛的应用。开发基于FLASH引导DM642的应用系统,在系统上电后,系统的自动引导机制将FLASH中的应用程序自动加载到片内RAM中去运行。但是,由于自动引导机制只能将片外FLAH中的1 KB代码加载到RAM中。这就要求必须开发能够将应用程序全部加载的引导程序,即二级引导程序。 1 DM642的引导方式 DM642主要有三种引导方式: (1)不加载。CPU直接开始执行地址0处存储
[模拟电子]
基于DM642的FLASH分页二级<font color='red'>引导</font><font color='red'>程序</font>设计
基于Linux的无线传感器网络引导程序的设计
0 引言   对等网络(Peer-to-Peer,P2P) 和自组织网络(SelforganizationNetwork) 是目前国际计算机网络技术领域的研究热点,有别于传统通信网络的Client/Server 机制,对等网络节点之间不仅可以直接通信,而且每个节点都可作为中间节点为其他节点提供服务,使本不能相互覆盖的2 个或多个网络节点之间实现通信与数据传输。   无线传感器网络作为新一代的传感器网络,充分借鉴了对等网络技术和自组织网络技术的特点。终端作为网络的实体和业务的承载体,节点芯片是整个无线传感器网络的基础,网络及其关键技术的研究应首先搭建网络和业务的承载平台,可移动终端则成为验证节点芯片移动性、数据传输、覆盖范围
[安防电子]
基于Linux的无线传感器网络<font color='red'>引导</font><font color='red'>程序</font>的设计
用U-BOOT构建嵌入式系统的引导装载程序
引 言:   本文以U-BOOT为例,介绍了如何在ARM9开发板上移植BootLoader的过程。LH7A400学习板是旋极公司推出的一款高性能嵌入式开发板,其采用的处理器LH7A400是Sharp公司生产的一款基于ARM922T内核的32位RISC芯片。该芯片集成了高性能的32位RISC处理器核ARM922T(运算速度200MHz,总线速度100MHz) ,能使处理速度达到每秒220百万条指令(MIPS),能耗为1.33mW/MIPS,可以在低电压状态下工作(核心1.8V,输入/输出3.3 V),片内带有锁相回路(PLL)和低能耗核心。此外该芯片还包括: 16KB 高速缓存(Cache), 存储器管理单元(MMU), 80KB
[单片机]
基于U-BOOT的S3C44B0引导装载程序的设计与实现
引言 嵌入式Linux的引导装载程序(Bootloader)是操作系统内核启动之前运行的一段程序,其作用与PC机上的BIOS类似。通过这段程序,将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核做好正确的环境 。Bootloader 与底层硬件相关密切,即每个不同配置的目标板都有不同的Bootloader。对于两块不同的嵌入式板,即使它们使用同一种CPU构建,要想让运行在其中一块上的Bootloader程序也能够运行在另一块板子上,通常也都需要修改Bootloader源程序。 嵌入式系统的硬件部分不可能是完全一致的,不可能有通用的bootloader。因此,需要针对硬件系统进行有关引导程序的设计。对于嵌入式系统来
[单片机]
基于U-BOOT的S3C44B0<font color='red'>引导</font>装载<font color='red'>程序</font>的设计与实现
利用MSP430实现Blackfin DSP的程序引导
Blackfin处理器是ADI公司与Intel公司于2003年4月联合推出的一系列DSP产品,主要面向嵌入式音频、视频和通信等领域,除了具有强大的信号处理性能和理想的电源效率,还集成了32位的RISC精简指令集。ADSP-BF533是目前Blackfin系列数字信号处理器中性能最高的一款,具有600MHz的主频,双16位的MAC(乘加器)和两个40位的ALU(算术逻辑单元),4个8位的视频处理单元,8个算术寄存器,10个地址寻址单元。DSP集成了148K字节的片内RAM,并具有丰富的外部接口,如SDRAM、通用并行数据口、SPI、PPI、同步和异步串口等。 MSP430F149是工业级闪存型16位RISC MCU,具
[单片机]
利用MSP430实现Blackfin DSP的<font color='red'>程序</font><font color='red'>引导</font>
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved