第3阶段——内核启动分析之创建si工程和分析stext启动内核函数(4)

发布者:梦想启航最新更新时间:2024-07-15 来源: elecfans关键字:内核启动 手机看文章 扫描二维码
随时随地手机看文章

1 创建内核source sight 工程

1.1 点击 “add all” 添加所有文件,后面再慢慢删去Arch目录和Include目录中与2440芯片没用的文件。

1.2 点击Remove Tree 删除Arch文件夹,再添加与2440相关的硬件核心代码以及其它公用的代码

 Arch:包含了平台,处理器相关的代码,并包括boot文件夹。

1.2.1 点击Add Tree添加以下子目录:

           linux-2.6.22.6/arch/arm/boot   (启动配置文件) 

           linux-2.6.22.6/arch/arm/common      (公共文件)  

           linux-2.6.22.6/arch/arm/configs    (配置文件)  

           linux-2.6.22.6/arch/arm/kernel         (内核文件)         

           linux-2.6.22.6/arch/arm/lib            (固件库)  

           linux-2.6.22.6/arch/arm/mach-s3c2440  (machine 设备,2440设备库)  

           linux-2.6.22.6/arch/arm/mach-s3c2410   (2440中部分调用了2410设备库)  

           linux-2.6.22.6/arch/arm/Mm     (内存管理文件)  

           linux-2.6.22.6/arch/arm/nwfpe             

           linux-2.6.22.6/arch/arm/oprofile         (性能分析工具文件)                

           linux-2.6.22.6/arch/arm/plat-s3c24xx    (s3c24系列平台文件)      

           linux-2.6.22.6/arch/arm/tools     (常用工具文件)                          

           linux-2.6.22.6/arch/arm/vfp   (浮点运算文件)  

1.3 点击Remove Tree 删除Include文件夹,再添加与2440相关的头文件

Include: 包括了核心的大多数include文件,另外对于每种支持的体系结构分别有一个子目录 

1.3.1 点击Add All 添加 linux-2.6.22.6/include/asm-arm目录下文件(不包含子目录所有文件),如下图所示:

1.3.2 点击Add Tree添加以下子目录:        

           linux-2.6.22.6/include/asm-arm/arch-s3c2410     (2410处理器架构)           

           linux-2.6.22.6/include/asm-arm/hardware    (硬件相关头文件)

           linux-2.6.22.6/include/asm-arm/mach             (具体的设备文件)

           linux-2.6.22.6/include/asm-arm/plat-s3c24xx   (s3c24系列平台头文件)  

1.3.3返回到 linux-2.6.22.6/include目录下,点击Add Tree添加除了asm-xx开头的其它通用文件:   

            linux-2.6.22.6/include/acpi             (高级配置与电源接口文件)  

            linux-2.6.22.6/include/config 

            linux-2.6.22.6/include/crypto 

            linux-2.6.22.6/include/keys

            linux-2.6.22.6/include/linux

            linux-2.6.22.6/include/math-emu

            linux-2.6.22.6/include/mtd      

            linux-2.6.22.6/include/net 

            linux-2.6.22.6/include/pcmcia

            linux-2.6.22.6/include/rdma

            linux-2.6.22.6/include/rxrpc

            linux-2.6.22.6/include/scsi

            linux-2.6.22.6/include/sound

            linux-2.6.22.6/include/video

1.4 最后点击synchronize files    创建source insight工程

2.内核启动之分析uboot传递参数和链接脚本

2.1 内核在uboot启动之前是进入do_boom_linux函数

(do_boom_linux函数启动内核详解:http://www.cnblogs.com/lifexy/p/7310279.html)

do_boom_linux代码如下:

theKernel = (void (*)(int, int, unsigend int))0x30008000;


// 设置theKernel地址=0x30008000,用于后面启动内核


/*设置atag参数*/


setup_start_tag (void);                      //从0X30000100地址处开始保存start_tag数据,


setup_memory_tags (void);         //保存memory_tag数据,让内核知道内存多大 setup_commandline_tag (“boottargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0”);  


 /*保存命令行bootargs参数,让内核知道根文件系统位置在/dev/mtdblock3,指定开机运行第一个脚本/linuxrc,指定打印串口0*/


setup_end_tag (void);                        //初始化tag结构体结束


theKernel(0,362,0x300000100);        //362:机器ID,  0x300000100: params(atag)参数地址


/*传递参数跳转执行到0x30008000启动内核,           */


/*相当于: mov r0,#0                                */


/*ldr r1,=362                                       */


/*ldr r2,= 0x300000100                             */


/*mov pc,#0x30008000                            */


TAG参数内存布局图如下:

2.2然后来分析链接脚本arm/arm/kernel/vmlinux.lds


OUTPUT_ARCH(arm)                    //设置输出文件的体系架构


 ENTRY(stext)                          //设置stext全局符号为入口地址


 jiffies = jiffies_64;


SECTIONS

{

. = (0xc0000000) + 0x00008000;               


/*设置内核虚拟地址=0xc0000000+0x00008000 */

.text.head : {

  _stext = .;

  _sinittext = .;

  *(.text.head)         //添加所有.text.head段

}

.init : { /* Init code and data                */

   *(.init.text)

  _einittext = .;

  __proc_info_begin = .;

   *(.proc.info.init)               //存放处理器相关的信息初始化

  __proc_info_end = .;

  __arch_info_begin = .;

   *(.arch.info.init)              //存放与架构(arch)相关的信息(info)初始化

  __arch_info_end = .;

...  ...

从vmlinux.lds中得出linux内核启动第一步是进入stext入口函数。


那么stext入口函数又在哪里定义的呢?


搜索ENTRY(stext)得出,它在arch/arm/kernel/head.S中,


stext函数的在前置条件是:MMU, D-cache, 关闭; r0 = 0, r1 = machine nr, r2 = atags prointer.代码如下:


代码语言:javascript


/*


 * Kernel startup entry point.                      //内核 启动 入口 点


 * ---------------------------


 *


 * This is normally called from the decompressor code.  The requirements


 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,  


/* 前置条件是:MMU, D-cache, 关闭; r0 = 0, r1 =机器ID, r2 =atag参数地址.*/


 * r1 = machine nr.


* This code is mostly position independent, so if you link the kernel at


 * 0xc0008000, you call this at __pa(0xc0008000).


* See linux/arch/arm/tools/mach-types for the complete list of machine


 * numbers for r1.


 *


 * We're trying to keep crap to a minimum; DO NOT add any machine specific


 * crap here - that's what the boot loader (or in extreme, well justified


 * circumstances, zImage) is for.


 */


 section '.text.head', 'ax'                      /* 定义一个.text.head段,段的属性a是允许段,x可 执行 */ 


         .type  stext, %function                /*定义了由bootloader进入内核的入口stext */


ENTRY(stext)


... ...


它的功能是获取处理器类型和机器类型信息,并创建临时的页表,然后开启MMU功能(因为内核代码中全是0XCxxxxxxx地址),并跳进第一个C语言函数start_kernel。

所以,内核启动后第一步是 进入arch/arm/kernel/head.S的stext函数中.

3内核启动之stext函数分析(arch/arm/kernel/head.S)

stext函数内容,如下图:

(1) 关闭irq和fiq,设置svc管理模式

(2)判断是或支持这个CPU

(3)判断是否支持这个单板(通过uboot传入的机器ID判断)

(4)创建页表,为后面的MMU做准备

(5) 使能MMU并跳到__switch_data处,复制数据段,清除bss段,设置栈,调用start_kernel第一个C函数

stext函数代码如下:  


section '.text.head', 'ax'                          /* 定义一个.text.head段,段的属性a是允许段,x可 执行 */ 


         .type   stext, %function                     /*定义了由bootloader进入内核的入口stext */


ENTRY(stext)                                    //入口地址stext函数


      /*msr cpsr_c,0xD3   关闭irq和fiq,设置svc管理模式  */


         msr    cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode 


                                                          @ and irqs disabled


     /*获取cpu ID */


         mrc    p15, 0, r9, c0, c0              @ get processor id


     /*查找内核是否支持r9这个cpuID,若不支持r5=0,支持r5=处理器ID*/


         bl       __lookup_processor_type             @ r5=procinfo r9=cpuid


         movs  r10, r5                                      @ invalid processor (r5=0)?


      /*不支持则跳转到__error_p,死循环*/


         beq     __error_p                         @ yes, error 'p'


     /*查找内核是否支持uboot传入的r1机器ID(362),若不支持r5=0,支持r5=机器ID*/


         bl       __lookup_machine_type              @ r5=machinfo


         movs  r8, r5                              @ invalid machine (r5=0)?

[1] [2]
关键字:内核启动 引用地址:第3阶段——内核启动分析之创建si工程和分析stext启动内核函数(4)

上一篇:S3C2440C语言点灯
下一篇:boot移植(十一)---代码修改---支持nandflash

推荐阅读最新更新时间:2024-11-17 05:53

cortex-a8 uboot系列:第十一章 uboot源码分析 uboot如何启动内核1
一、Uboot和内核到底是什么(从系统启动角度看) 1.Uboot Uboot的本质是一个复杂的裸机程序。 2.内核 操作系统内核本身也是一个裸机程序,和uboot、其他裸机程序并没有什么本质区别。 但是和其他裸机程序的区别:操作系统运行起来后在软件上分为内核层和应用层,分层后两层的权限不同,内核访问和设备操作的管理上更加精细(内核可以随意访问各种硬件,而应用程序只能被限制的访问硬件和内存地址)。 Uboot的镜像是u-boot.bin,linux系统镜像是zImage,这两个文件都是两个裸机程序bin文件镜像。 二、SD卡中的分区 一个完整的软件+硬件的嵌入式系统,未上电时,bootloader、kernel、roo
[单片机]
cortex-a8 uboot系列:第十一章 uboot源码分析 uboot如何<font color='red'>启动</font><font color='red'>内核</font>1
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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