Porting:linux内核编译、配置、修改配置文件、添加.c文件到内核

原创 2017年02月23日 22:47:30
1、linux内核
     www.kernel.org
     $:'uname -a
     $:'uanme -r
     // 查看linux内核版本,开发板上进入linux后是同样的命令。
     早起经常使用的版本:linux 2.6.x
     开发板上使用的版本:linux 3.4.39
     linux最新版本:linux 4.x

2、linux内核的5大功能
     1)内存管理功能;
     2)进程管理及进程间通信;
     3)虚拟文件子系统;
     4)设备驱动管理;
     5)网络子系统;

     嵌入式平台有操作系统,优势在于:
        1)编程简单,有库函数可以调用;
        2)可以实现更加复杂的业务逻辑;// 多进程 多线程

3、linux内核的编译
     env/kernel.tar.bz2
     $:'cp /mnt/hgfs/porting/env/kernel.tar.bz2 .
     $:' tar xvf *.bz2
     $:' cd kernel/
     $:'find ./ -type f | wc -l
     // 26129
     $:'cp arch/arm/configs/x6818_defconfig .config
     $:'vi Makefile
     // 195 ARCH ?= arm
     // 196 CROSS_COMPILE ?= arm-cortex_a9-linux-gnueabi-

     $:'make uImage -j4
     // arch/arm/boot/uImage  is  ready

     $:'make menuconfig -j4
     // 此项为内核功能配置,可删减(内核裁剪)

** 编译异常问题解决 **
     问题1:
     >>如果出现"mkuimage"command not find
     解决办法:
         $:'sudo cp ~/project/uboot/tools/mkimage /usr/bin/
         $:'make uImage
     问题2:
     >>Your display is too small...
     解决办法:
       缩小字体显示比例。

验证uImage的有效性:
    把uImage烧写0x800扇区开始的分区位置。
    通过加载的方式:
    cp arch/arm/boot/uImage /tftpboot/
    tftp 48000000 uImage
    bootm 48000000

    setenv bootcmd tftp 48000000 uImage \; bootm 48000000



3.1 内核的配置
【什么是配置?】
    假设linux内核中提供了10000种功能,但是具体到开发板上只需要其中2000个功能。
    1)裁剪掉内核中不需要的功能
         不需要挂载U盘
         // 内核中关于FAT32类型文件系统相关的代码的支持就不需要
    2)驱动程序的裁剪
         // 产品中没有键盘,裁剪掉内核中的键盘驱动
    【总之】根据目标产品的需要,以及开发板的实际硬件,裁剪掉不需要的内核代码。
【如何完成配置?】
    找一个相近的配置文件,在此基础上进行修改。
【去哪里找相近的配置?】
    1)去内核源码目录  arch/arm/configs/xxx_defconfig
    2)上游厂家提供
【如何修改配置?】
    cp 相近的配置.config  kernel/.config
    a)$:'  make menuconfig
       // 模拟菜单显示界面
         General setup  --->
         System Type  --->
                ARM system type (SLsiAP S5P6818)  --->
         Boot options  --->
         Device Drivers  ---> // 硬件驱动设备
         File systems  ---> // 文件系统
     b)$:' make config
    // 纯文字提示,基本不用
     c)$:'  make xconfig
     // 真实图形显示菜单界面,基本不用
     "make help" 查看内核make帮助命令。

内核本质也是一个裸板程序。
    .o ... .o  ---> elf 文件 (vmlinux)
    vmlinux  ---> Image(.bin)  --->  zImage  ---> uImage
    zImage:解压缩代码 + 压缩后的Image数据
    uImage:64Bytes + zImage
    // 64Bytes:内核的加载地址、内核版本 ... 一般给uboot使用。
    $:'du -h arch/arm/boot/Image
    // 11M
    $:'du -h arch/arm/boot/zImage
    // 5.2M <-b> 5400688,压缩后的Image
    $:' du -harch/arm/boot/uImage
    // 5.2M <-b> 5400752

<tips>
$:'du -h
// 以兆(M)显示文件大小 和 文件名
$:'du -b
// 以字节数显示文件大小 和 文件名

3.2 linux内核的启动过程
     阅读代码,组织工程。
     linux : vim + ctags
     $:'rm arch/arm/mach-s5p6818/prototype/prototype
     $:'ctags -R *
     windows : source insight
     入口点文件:
            $:'rm vmlinux
            $:'make uImage V=1
            // V=1 显示详细的编译过程
            $:'vi arch/arm/kernel/vmlinux.lds
            .head.text : {
                _text = .;
                *(.head.text)
            }
      // 整个linux内核的入口点文件:arch/arm/kernel/head.S
      head.S:
            设置SVC模式
            __lookup_processor_type  // 检查CPU的ID看内核的状态
            bl  __create_page_tables  // 创建页表
            ldr     r13, =__mmap_switched 
            b       __enable_mmu
                 。。。
                 。。。
              b       __turn_mmu_on
              450 ENTRY(__turn_mmu_on)
              457         mov     r3, r13
 458         mov     pc, r3 //跳转到__mmap_switched
__mmap_switched:
b       start_kernel
start_kernel
   -->rest_init
      {
           //创建一个新的内核线程
           kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
      }
         kernel_init( )
          {
             prepare_namespace( )
              {
                 //根据bootargs的参数,挂载根文件系统
                 mount_root( );
              }
              init_post( )
              {
                  //执行用户空间的1号进程
                  run_init_process("/sbin/init");
              }
          }
系统上电--->uboot完成硬件的初始化--->执行bootcmd中的命令--->加载操作系统到内存--->传递参数给内核,并启动内核--->检查CPU ID当前内核是否支持--->创建页表开启MMU--->start_kernel--->创建一个新的内核线程--->根据参数去挂载根文件系统--->从根文件系统中找到1号进程--->创建执行1号进程--->1号进程后续会创建子进程/bin/bash--->用户可以输入命令

    移植内核的关键文件:arch\arm\mach-s5p6818\cpu.c
    其中的关键代码信息:
            static void __initcpu_init_machine ( void ) {
                ...
            nxp_cpu_devs_register ( );
           nxp_board_devs_register ( );
            }
           // 该函数是在 kernel_init 中被调用,即系统启动过程中被调用。
            kernel_init ( ) {
                do_basic_setup ( ) {
                    do_initcalls ( ) {
                        ...
                       cpu_init_machine ( ); // 移植的重点。要改的函数。
                    }
                }
            }

4、配置过程是如何影响编译过程的
$:'  make menuconfig
    Device Drivers  --->
            Character devices  ---> 
                     -*- LED Support  ---> 
                    // LED Support for GPIO connected LEDs ---> help
---> 变量:CONFIG_LEDS_GPIO
$:' vi .config
CONFIG_LEDS_GPIO=y     // <*>
CONFIG_LEDS_GPIO=m   // <M>
# CONFIG_LEDS_GPIO is not set   // < >

【结论1】配置的结果是以变量取不同的值的形式保存在 .config 文件中。
【结论2】内核中几乎所有的目录下都有Makefile文件。
【结论3】各个子目录下的Makefile决定了当前目录下的文件(夹)是否参与编译过程。
$:'grep "CONFIG_LEDS_GPIO" * -nRw
   // grep显示行号-递归-内容检索:
    drivers/leds/Makefile:22行使用了该变量
    obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
    <*>   CONFIG_LEDS_GPIO=y  ' boj-y += leds-gpio.o
    <M> CONFIG_LEDS_GPIO=y  ' boj-m += leds-gpio.o    
    < >   CONFIG_LEDS_GPIO=y  ' boj-  += leds-gpio.o
【结论4】
在编译内核时 boj-y += xxx.o 代表 xxx.c 参与编译,并最终链接到内核uImage;
在编译内核时 boj-m += xxx.o 代表 xxx.c 参与编译,但不会链接进内核uImage,生成一个独立的xxx.o;
在编译内核时 boj-  += xxx.o 代表 xxx.c 不参与编译。


5、如何将一个.c文件编译进内核
// env/led_drv.c
$:'cp /mnt/hgfs/porting/env/led_drv.c drivers/char/
$:'vi drivers/char/Makefile
增加1行:obj-y               += led_drv.o
$:'make uImage
$:' cp arch/arm/boot/uImage  /tftpboot/

#:' tftp 48000000 uImage
#:' bootm 48000000
#:'dmesg >1.txt
#:'dmesg | grep "led_init"
版权声明:本文为博主<布衣不才>原创文章,未经允许不得转载。 || 博客地址:blog.csdn.net/sinat_36184075

linux配置文件详解

每个 Linux 程序都是一个可执行文件,它含有操作码列表,CPU 将执行这些操作码来完成特定的操作。例如,ls 命令是由 /bin/ls 文件提供的,该文件含有机器指令的列表,在屏幕上显示当前目录中...
  • cp25807720
  • cp25807720
  • 2013年05月22日 09:30
  • 1982

Linux内核模块配置文件

以CentOS为例说明: /boot/configure-*为当前Linux内核的模块配置文件,即在当前Linux内核中,系统已启用了哪些模块,哪些内容已编译到Linux内核等等,都可以通过...
  • lopng
  • lopng
  • 2017年06月01日 08:33
  • 341

史上最全linux内核配置详解

对于每一个配置选项,用户可以回答"y"、"m"或"n"。其中"y"表示将相应特性的支持或设备驱动程序编译进内核;"m"表示将相应特性的支持或设备驱动程序编译成可加载模块,在需要时,可由系统或用户自行加...
  • qq_29350001
  • qq_29350001
  • 2016年05月24日 12:50
  • 16768

Android Kernel Porting 的简单总结文档

  Simple Guide for Porting Android Kernel作者:刘旭晖 colorant@163.com 转载请注明出处http://blog.csdn.net/coloran...
  • colorant
  • colorant
  • 2008年02月27日 16:59
  • 14487

Linux Kernel Porting CPU 方法概要

Linux Kernel Porting CPU是什么?       Linux kernel发展至今,除了X86,代码包中默认支持很多流行的CPU,arch\arm\下可以看到已支持的ARM 架...
  • u012895903
  • u012895903
  • 2013年11月21日 12:58
  • 1259

Linux入门之内核编译与替换

Linux入门之内核编译与替换——black的专栏 —— washaxiu
  • u012596172
  • u012596172
  • 2016年10月05日 18:40
  • 4254

linux内核源码目录结构分析

注:本文是学习朱老师课程整理的笔记,基于linux2.6.35.7和九鼎X210BV3S开发板进行移植。...
  • Ultraman_hs
  • Ultraman_hs
  • 2016年10月26日 09:14
  • 3426

几个重要的内核文件介绍

几个重要的内核文件介绍 Linux服务器内核编译基础 --几个重要的RedHat Linux内核文件介绍 在网络中,不少服务器采用的是Linux系统。为了进一步提高服务器的性能,可能需要根据特定的硬件...
  • axlrosek
  • axlrosek
  • 2007年11月26日 17:38
  • 1985

几种linux内核Image文件的区别

内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件,Image大约为4M,而zImage不到2M。 那...
  • fivedoumi
  • fivedoumi
  • 2015年10月08日 19:11
  • 3434

Linux内核配置和编译过程详解

一、引言:  本文档的内容大部份内容都是从网上收集而来,然后配合一些新的截 图(内核版本:V2.4.19)。在每一配置项后会有一个选择指南的部份,用来指导大家怎么样 根据自己的情况来做相应的选择;还...
  • qq_29350001
  • qq_29350001
  • 2016年05月24日 12:48
  • 8316
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Porting:linux内核编译、配置、修改配置文件、添加.c文件到内核
举报原因:
原因补充:

(最多只允许输入30个字)