linux内核的编译过程

15 篇文章 0 订阅
12 篇文章 0 订阅

linux内核的编译过程:
uImage:

进入顶层目录的Makefile文件中:

504 include $(srctree)/arch/$(SRCARCH)/Makefile  ====》 arch/arm/Makefile
   ||
   \/
   进入arch/arm/Makefile中
   必备变量:
   machine-$(CONFIG_ARCH_EXYNOS)       += exynos  ===》 machine-y  += exynos
   plat-$(CONFIG_ARCH_EXYNOS)  += samsung   ===> plat-y  += samsung
   
   MACHINE  := arch/arm/mach-$(word 1,$(machine-y))/  
   ===》MACHINE :=  arch/arm/mach-exynos/
   
    machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
 ===>   machdirs :=arch/arm/mach-exynos/
 
    platdirs := $(patsubst %,arch/arm/plat-%/,$(plat-y))
 ===>  platdirs := arch/arm/mach-samsung
 
 291 boot := arch/arm/boot  
   
 BOOT_TARGETS    = zImage Image xipImage bootpImage uImage      
 $(BOOT_TARGETS): vmlinux                                                                  
     $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@    
   ===> @ make -C $(build)=arch/arm/boot  MACHINE=arch/arm/mach-exynos/    arch/arm/boot/uImage
            ||
   \/
   进入arch/arm/boot/Makefile中
   
  14 ifneq ($(MACHINE),)                                                                                          
     15 include $(srctree)/$(MACHINE)/Makefile.boot  ====》include  arch/arm/mach-exynos/Makefile.boot                                                                  
     16 endif  
   
       arch/arm/mach-exynos/Makefile.boot文件内容:
        zreladdr-y   += 0x40008000      就是内核的入口地址                                                  
        params_phys-y   := 0x40000100   uboot传递参数的地址

      22 ZRELADDR    := $(zreladdr-y)                                                                            
      23 PARAMS_PHYS := $(params_phys-y)  
   export ZRELADDR INITRD_PHYS PARAMS_PHYS   到处为全局变量
   
   $(obj) ==  当前Makeifle的路径
   
   78 $(obj)/uImage:  $(obj)/zImage FORCE  
   
   $(obj)/zImage:  $(obj)/compressed/vmlinux FORCE    ===》arch/arm/boot/compressed/vmlinux                                                         |3| 5
                  $(call if_changed,objcopy)  
     
        ||
     \/
     进入arch/arm/boot/compressed/Makefile
     
     arch/arm/boot/compressed/vmlinux.lds  链接脚本
     25 HEAD    = head.o  
     
     86 suffix_$(CONFIG_KERNEL_GZIP) = gzip  ==》 suffix_y = gzip
     $(obj)/piggy.$(suffix_y).o  ===》arch/arm/boot/compressed/piggy.gzip.o
     
     26 OBJS    += misc.o decompress.o  他们是用来解压内核的代码
                                                                               
           148 lib1funcs = $(obj)/lib1funcs.o   ==》arch/arm/boot/compressed/lib1funcs.o  

         
$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \                          
         $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3)   $(bswapsdi2) FORCE                                        
       
 
195 $(obj)/piggy.$(suffix_y).o:  $(obj)/piggy.$(suffix_y) FORCE  
192 $(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE  ==>arch/arm/boot/Image  

                    ||
     \/
     退回arch/arm/boot/Makefile文件

 47 $(obj)/Image: vmlinux FORCE  ===》 依赖于源码顶层目录下的vmlinux文件                                                              
 48     $(call if_changed,objcopy)  
 
                     ||
      \/
     退回Makefile文件  

 802 export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)
 803 export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y)
 804 export KBUILD_LDS          := arch/$(SRCARCH)/kernel/vmlinux.lds
 
809 vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)
817 vmlinux: scripts/link-vmlinux.sh  $(vmlinux-deps)   FORCE  


Linux内核的启动流程:
arch/arm/kernel/vmlinux.lds  链接脚本
arch/arm/kernel/head.S    内核启动的第一段代码

        safe_svcmode_maskall r9      
         设置cpu的工作模式,关闭中断
   ||
   \/
    94     mrc p15, 0, r9, c0, c0      @ get processor id
         95     bl  __lookup_processor_type     @ r5=procinfo r9=cpuid  
         获得处理器的id,然后对比内核是否支持?
   
   ||
   \/
  bl  __vet_atags  
  判断uboot给内核传递参数的方式是taglist或者 dtb?
 
  bl  __create_page_tables 创建页表, 为开启MMU做准备
 
  ||
  \/
  参考  arch/arm/mm/proc-v7.S  查看对TLB  cache的初始化
 
  ldr r13, =__mmap_switched   赋值个sp寄存器
 
  ||
  \/
   b   __enable_mmu  使能mmu
   ||
   \/
   b   __turn_mmu_on  开启MMU
   ||
   \/
   b __mmap_switched
     拷贝相关数据
     清空BSS段
     
     ||
     \/  
  b   start_kernel  进入C语言代码
 
    setup_arch(&command_line);  就是获得uboot传递过来的参数
   
    setup_command_line(command_line); 获得bootargs参数
   
    console_init();  尤其注意的函数。
   
    rest_init();
     ||
     \/
   kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
                  ||
      \/
      kernel_init
      ||
      \/
      kernel_init_freeable(); 挂载文件系统相关的函数
                        ||
      \/
                  prepare_namespace(); 挂载文件系统
      567         if (strncmp(root_device_name, "/dev/", 5) == 0)
                        568             root_device_name += 5;  
     
        mount_root();  执行挂载
        ||
        \/
        510         if (mount_nfs_root())
                       511             return;
                 ||
        \/
        执行init程序,内核完全启动。

平台代码,设备树:

设备树:Device Tree

/{
   node1 {
     属性
  child_1 {
 
  };
  child_2 {
 
  };
   };

   node {
    属性
   };
   
};

设备树文件:
dts 设备树的原文件。
dtb 设备树二进制文件
dtsi :类似于头文件

属性:
model :表示具体某一个machine
compatible 用来将驱动和设备绑定
#address-cells = <1> 表示起始地址
#size-cells = <1>    表示范围

reg:可寻址设备用来表示编码地址信息,是一个列表
reg = <0x0203F000 0x1000>;


参考Documentation/devicetree/bindings 有例子







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_27205523

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值