• linux内核启动笔记


    一、 1、解压    tar xjf linux-2.6.22.6.tar.bz2

    2、打补丁  patch -p1 < ../linux-2.6.22.6_jz2440.patch

    3、配置

      a. make menuconfig

      b. 使用默认的在上面修改 c.使用厂家的配置文件

    b:

    find -name "*defconfig*"  

    在/arch/arm/configs找到相似的配置文件 xxx_defconfig

    make xxx_defconfig       结果是configuration written to .config make menu config

    c: ls config_ok

    cp config_ok .config

    make menuconfig

    make uImage

     

        case 'k':   {              

              strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)");                

             run_command(cmd_buf, 0);               

              break;       

          }

    二、 配置结果 生成config

    配置项 CONFIG_DM9000  = Y

    grep "CONFIG_DM9000" * -nwR

    1.C源码 CONFIG_DM9000     宏来源于include/linux/autoconf.h

    2.子目录makefile     drivers/net/Makefile

    3.include/config/auto.conf   

    4.include/linux/autoconf.h     定义为1

    2: obj-$(CONFIG_DM9000) += dm9000.o

    obj-y += xxx.o    为编译到内核

    obj-m += yyy.o    最终编译为可加载模块 -》yyy.c->yyy.ko

    make uImage 时

    a..config-->autoconf.h

    b..config-->auto.conf

    分析Makefile:第一个文件、链接脚本

    a.c b.c 组成一个模块

    obi——m +=ab.o  

    ab-objs := a.o b.o

     a.c ->a.o  |        | -->ab.ko

     b.c->b.o    

    1、子目录下的Makefile

    obj-y += xxx.o  

    obj-m += yyy.o 

    2、 make uImage --》  arch/arm/Makefile  被包含到顶层Makefile

    include $(srctree)/arch/$(ARCH)/Makefile

     

    zImage Image xipImage bootpImage

    uImage: vmlinux uImage: vmlinux          头部 + 内核

    vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE

     

    vmlinux-init := $(head-y) $(init-y)

    head-y  := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o

    init-y  := init/

    init-y  := $(patsubst %/, %/built-in.o, $(init-y))

      = init/built-in.o  把所有init下的文件编译为in.o

     

    vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)

    core-y  := usr/

    core-y  += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

    core-y  := $(patsubst %/, %/built-in.o, $(core-y))      

        = usr/built-in.o kernel/built-in.o mm/built-in.o fs/built-in.o ipc/built-in.o      

        security/built-in.o crypto/built-in.o block/built-in.o  

     

    libs-y  := lib/

    libs-y1  := $(patsubst %/, %/lib.a, $(libs-y))

    libs-y2  := $(patsubst %/, %/built-in.o, $(libs-y))

    libs-y  := $(libs-y1) $(libs-y2)      

        =lib/built-in.o lib/lib.a drivers-y :

        = drivers/built-in.o   sound/built-in.o net-y  := net//built-in.o

     

    vmlinux-all  := $(vmlinux-init) $(vmlinux-main)

    vmlinux-lds  := arch/$(ARCH)/kernel/vmlinux.lds

     

    第一个文件arch/arm/kernel/head.s

    链接脚本archarmkernel/vmlinux.lds

    0、判断是否支持这个cpu

    1、处理u-boot传入的参数    

    arch/arm/kernel/head.s u-boot启动内核时传入的机器ID判断是否支持这个单板

    2、因为使用地址为虚拟地址说以,建立页表

    3、启用mmu

    4、跳转到start_kernel   第一个c函数

    挂接根文件系统

    最终目的:应用程序

    __lookup_machine_type:  

      adr r3, 3b       @r3 = address of 3b  real address ,phy address  

      ldmia r3, {r4, r5, r6}  @r4 = "."the virtual address of 3b r5 = __arch_info_begin,r6 = __arch_info_end  

      sub r3, r3, r4   @ get offset between virt&phys  

      add r5, r5, r3   @ convert virt addresses to  

      add r6, r6, r3   @ physical address space

     

      __arch_info_begin = .;   

    *(.arch.info.init)  

    __arch_info_end = .;

     

    #define MACHINE_START(_type,_name)   

    static const struct machine_desc __mach_desc_##_type 

     __used       

     __attribute__((__section__(".arch.info.init"))) = {   .nr  = MACH_TYPE_##_type,    

    .name  = _name,

    #define MACHINE_END    

    };

    static const struct machine_desc __mach_desc_S3C2440 

     __used         

    __attribute__((__section__(".arch.info.init"))) = { 

     .nr  = MACH_TYPE_S3C2440,  

     .name  = SMDK2440,

     /* Maintainer: Ben Dooks <ben@fluff.org> */

     .phys_io = S3C2410_PA_UART,

     .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

     .boot_params = S3C2410_SDRAM_PA + 0x100,      0x30000100

     .init_irq = s3c24xx_init_irq,  

    .map_io  = smdk2440_map_io,

     .init_machine = smdk2440_machine_init,  

    .timer  = &s3c24xx_timer,

    };

     

     

    struct machine_desc {

     /*   * Note! The first four elements are used  

    * by assembler code in head-armv.S   */  

    unsigned int  nr;  /* architecture number */  

    unsigned int  phys_io;/* start of physical io */  

    unsigned int  io_pg_offst; /* byte offset for io        * page tabe entry */

     const char  *name; /* architecture name */

     unsigned long  boot_params; /* tagged list  */

     unsigned int  video_start; /* start of video RAM */

     unsigned int  video_end; /* end of video RAM */

     unsigned int  reserve_lp0 :1; /* never has lp0 */  

    unsigned int  reserve_lp1 :1; /* never has lp1 */  

    unsigned int  reserve_lp2 :1; /* never has lp2 */  

    unsigned int  soft_reboot :1; /* soft reboot  */

     void   (*fixup)(struct machine_desc *,       struct tag *, char **,       struct meminfo *);

     void   (*map_io)(void);/* IO mapping function */  

    void   (*init_irq)(void);  struct sys_timer *timer;  /* system tick timer */  

    void   (*init_machine)(void);

    };

     

     setup_arch(&command_line);  

    setup_command_line(command_line); 处理传到内核阐述

     

    static int __init root_dev_setup(char *line)

    {

     strlcpy(saved_root_name, line, sizeof(saved_root_name));

     return 1;

    }

     

    __setup("root=", root_dev_setup);  

     

    #define __setup(str, fn)     

     __setup_param(str, fn, fn, 0)   #define __setup_param(str, unique_id, fn, early)   

     static char __setup_str_##unique_id[] __initdata = str; 

     static struct obs_kernel_param __setup_##unique_id 

      __attribute_used__      

     __attribute__((__section__(".init.setup")))    

    __attribute__((aligned((sizeof(long)))))   

     = { __setup_str_##unique_id, fn, early }    

     

    obsolete_checksetup  

    do_early_param   

     

      内核启动流程

    arch/arm/kernel/head.s

     

    start_kernel  

      setup_arch           //解析u-boot传入的启动参数  

      setup_command_line   //解析u-boot传入的启动参数

       parse_early_param    

        do_early_param     

           __setup_start到 __setup_end;调用early函数  

      unknown_bootoption   

        obsolete_checksetup    

          __setup_start到 __setup_end;调用非early函数  

      rest_init   

        kernel_init    

        prepare_namespace     

          mount_root  //挂接根文件系统    

        init_post      // 执行应用程序  

     


     分析分区
     代码里边写死的
      grep ""bootloader"" * -nR 
    arch/arm/plat-s3c24xx/common-smdk.c:120:        .name   = "bootloader", 
    static struct mtd_partition smdk_default_nand_part[] = {
     [0] = {
            .name   = "bootloader",
            .size   = 0x00040000,
      .offset = 0,
     },
     [1] = {
            .name   = "params",
            .offset = MTDPART_OFS_APPEND,    //紧接着上一个
            .size   = 0x00020000,
     },
     [2] = {
            .name   = "kernel",
            .offset = MTDPART_OFS_APPEND,
            .size   = 0x00200000,
     },
     [3] = {
            .name   = "root",
            .offset = MTDPART_OFS_APPEND,
            .size   = MTDPART_SIZ_FULL,
     }
    };

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    javascript的字段值,私有变量,静态方法声明
    取得序列中某个点的范围边界
    使用wubi安装ubuntu11.04后无线网卡被禁用无法打开解决办法
    WEB前端性能优化
    jQuery的arrayLike
    在手机上安装BT5系统,没错就是破解无线密码的那个
    PHP在子类方法B调用父类的方法A时,不传参数时仍能得到方法B的名称
    讨厌的文本选区
    PHP遍历解析XML为一个数组
    “软工厂代码生成工具”的学习笔记
  • 原文地址:https://www.cnblogs.com/CZM-/p/5077078.html
Copyright © 2020-2023  润新知