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

发布时间:2024-07-15  

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)?

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>