58.linux 内核 编译及调试

一.linux内核基本概念

1.  linux 内核 和 linux 操作系统的区别

  •      linux 内核 : 通常指的是由官网下载下来的源码 编译出来的 uImage 或者 zImage 镜像

            启动中包含的由 硬件抽象层、文件系统、进程调度、网络管理、驱动管理、内存管理(多任务)等功能。

  •      通常我们使用的 linux 系统 是指: 像 Ubuntu 等操作系统。 包含linux 内核, 工具集,各种第三方库,

            图形界面,应用程序的一个发布包(发行版)

     
  2.   linux 内核特性

  •             免费开源
  •             可移植性 支持广泛的硬件平台 //arm ppc mips x86...
  •             扩展性
  •             软硬件可裁剪
  •             高可靠性、稳定性
  •             网络功能强大
  •             多任务、多用户系统
  •             模块化设计

 3.    linux 内核版本
        采用 A.B.C.D 
            A 主版本号 
            B 次版本号 为偶数表示 稳定版本 奇数为开发中版本
            C 表示linux的发行版本号
            D 表示更新版本号

 4.   linux 内核包含的五大功能:

  1.         进程管理
  2.         内存管理
  3.         文件系统
  4.         网络协议
  5.         设备驱动管理

        linux 不会是一个真正的实时系统 (时间片轮转方式)
        vxwork 是一个真正的实时(RTOS )系统 收费
        
 5.   linux 分层
        
         应用程序
            ||
            \/
         系统调用
            ||
            \/
         linux 内核  分为 平台无关 和 平台相关码
            ||
            \/
         硬件平台
 6.      
    linux 内核 下载地址  https://www.kernel.org/
    linux 各个版本下载地址 https://www.kernel.org/pub/linux/kernel/
        编译内核 make uImage 
        编译设备树 make dtbs

 

二 .内核的编译

1.注意要把 linux源码 拷贝到 Ubuntu中 解压, 不要在共享文件夹直接解压
    因为 源码中会有一些软件链文件, 这些文件,windows文件系统 不能识别
    
2.    解压命令 tar -xvf ***.tar.xz

3.  配置交叉编译工具链:
      方法一:export PATH=/自己的路径/gcc-4.6.4/bin:$PATH //临时有效
      方法二:写到启动脚本中 /etc/profile  或者 .bashrc
    
4.   修改 源码顶层目录的 Makfile
    ARCH ?= arm
    CROSS_COMPILE ?= arm-none-linux-gnueabi-
5.

编译内核    make uImage
 
编译设备树  make dtbs

注:设备树: 用于描述硬件设备信息。 低版本内核的设硬件备信息,是存放在linux源码中的, 高版本是写到 设备树文件中    

如果想启动内核,还需要配置一下网络 ,可以看前几节的内容。

"mkimage" command not found - U-Boot images will not be built make[1]: *** [arch/arm/boot/uImage] Error 1

过程中出现了一个报错,

解决方法:

sudo apt-get install u-boot-tools

然后将编译后的uImage 和exynos4412-origen.dtb文件拷贝到虚拟机的tftpboot文件夹下,板卡启动验证程序。

cp arch/arm/boot/uImage /tftpboot/

三.内核目录结构

 

四.内核的启动过程

a. 自解压 decompess (arch/arm/boot/compressed/head.S) 汇编

b. 运行内核汇编部分 head.S 入口stext  (arch/arm/kernel/head.S)

        检测合法性(CPU 类型,机器类型)
c.  运行 C代码 start_kernel (init/main.c)

        CPU,机器参数的安装   setup_arch

        中断,定时,终端,内存等最基本的初始化

        创建核心进程 kernel_init运行,启动多任务调度

d. 挂载 rootfs
e. .  运行第一个应用程序init  (一般是 linuxrc)

 

五. 内核调试方法

    1. 汇编阶段 点灯法
    2. puts(内核解压前)
    3. printascii (console 初始化前)
    4. printk (内核解压后,信息输出显示到console初始化之后)
        打印级别  /proc/sys/kernel/printk

#define KERN_EMERG        "<0>"   /* system is unusable           */

#define KERN_ALERT        "<1>     /* action must be taken immediately */

#define KERN_CRIT         "<2>"   /* critical conditions          */

#define KERN_ERR          "<3>"   /* error conditions         */

#define KERN_WARNING      "<4>"   /* warning conditions           */

#define KERN_NOTICE       "<5>"     /* normal but significant condition */

#define KERN_INFO         "<6>"   /* informational            */

#define KERN_DEBUG        "<7>"   /* debug-level messages

 

printk( KERN_INFO \n  INFO Level \n);

通过proc在运行时查看和修改日志级别
cat /proc/sys/kernel/printk            显示   4 4 1 7
echo “7 4 1 7” > /proc/sys/kernel/printk  后 
cat /proc/sys/kernel/printk            显示7 4 1 7

 

测试一下:我们在init/main.c中添加一下打印信息,测试一下。

在start_kernel函数中进行打印信息的添加。

过程中出现了网络不通情况,虚拟机重新恢复了下网卡,tftp server 重新启动了一下。

 

        5.OOP内核异常信息

例:

1.  制造错误

    修改drivers/char/fs4412_led_drv.c

    s5pv210_led_init函数中int  ret=0;下增加下面语句: int *ptr  =  NULL; *ptr  = 0xff;

 

 2. 运行该内核报错

  [    1.165000] Unable to handle kernel NULL pointer dereference at virtual address 00000000

  [    1.170000] pgd = c0004000

  [    1.175000] [00000000] *pgd=00000000

  [    1.175000] Internal error: Oops: 805 [#1] PREEMPT SMP ARM

  [    1.180000] Modules linked in:

  [    1.185000] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.14.0 #25

  [    1.190000] task: ee8a0000 ti: ee8a4000 task.ti: ee8a4000

  [    1.195000] PC is at s5pv210_led_init+0x18/0x180

  [    1.200000] LR is at do_one_initcall+0x30/0x144

 [    1.205000] pc : [<c024225c>]    lr : [<c00087b4>]    psr: 60000153

  [    1.205000] sp : ee8a5ef8  ip : c059afac  fp : 00000000

  [    1.215000] r10: c052d4fc  r9 : c0564b80  r8 : c0242244

  [    1.220000] r7 : c05a3400  r6 : c055134c  r5 : 00000000  r4 : ee8a4000

  [    1.230000] r3 : 00000055  r2 : c04c0430  r1 : 00000001  r0 : 1f400000

  [    1.235000] Flags: nZCv  IRQs on  FIQs off  Mode SVC_32  ISA ARM  Segment kernel

  [    1.245000] Control: 10c5387d  Table: 4000404a  DAC: 00000015

  [    1.250000] Process swapper/0 (pid: 1, stack limit = 0xee8a4240)

  [    1.255000] Stack: (0xee8a5ef8 to 0xee8a6000)

3. 找出错位置

    根据PC is at s5pv210_led_init+0x18/0x180 知道出错的函数是s5pv210_led_init

    根据pc : [<c024225c>]  知道出错的位置

    #arm-none-linux-gnueabi-addr2line c024225c -e vmlinux -f   在源码中会显示具体出错的位置(利用小工具)

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值