LINUX内核调试相关--oops信息的…

转载  LINUX内核调试相关--oops信息的定位2 收藏

Ø  实验目的与意义

1 、掌握printk 的使用、设置及实现原理,理解分级别进行打印log 信息的实现方法

2 、掌握如何分析oops 的方法

3 、掌握strace 工具的移植和使用方法

 

Ø  基本原理和方法

1 、请回顾栈的工作原理,尤其是栈帧的作用

2 、请对照printk 的源代码来进行printk 相关实验,并在实验中进一步理解源代码

 

Ø  实验内容及步骤 

一. Printk 实验

1 、在内核中编写自己的printk 代码,可利用上次系统调用实验中已有的代码,也可利用之前驱动实验中的模块。

2 、在根文件系统中增加/proc 目录,用来挂载proc 文件系统

3 、重新烧录uImage (如果有所改动的话)和根文件系统,进入控制台之后,输入命令挂载proc 文件系统:mount t proc none /proc

如果挂载成功, /proc 目录应该可以看到文件,比如下面的结果:

# ls proc

             74             devices        kpagecount     slabinfo

100            765             diskstats      kpageflags     stat

101            773            driver         loadavg        swaps

102            783            execdomains    locks          sys

103            784            fb             meminfo        sysrq-trigger

              786            filesystems    misc           sysvipc

             790            fs             modules        timer_list

             804            ide            mounts         tty

             806            interrupts     mtd            uptime

             buddyinfo      iomem          net            version

60             bus            ioports        pagetypeinfo   vmstat

65             cmdline        irq            partitions     yaffs

71             cpu            kallsyms       sched_debug    zoneinfo

737            cpuinfo        kmsg           self

4 、检查并修改printklog 级别,比如下面的命令:

# cat /proc/sys/kernel/printk
                7
# echo 1 >/proc/sys/kernel/printk
# cat /proc/sys/kernel/printk
                7

修改之后,默认的printk 打印(级别为4 )不会显示到串口终端,但仍可以通过“ cat /proc/kmsg ”看到打印结果。

5 、通过代码和 /proc/sys/kernel/printk 分别修改log 级别,并对应printk 的源代码来分析结果。

 

二.C 语言可变参数实验

1 、在内核代码kernel/printk.c 中的printk 函数用到了C 语言中的可变参数的用法。请参考下面的代码来学习如何使用可变参数。以下代码可直接在x86 环境测试:

 

#include <stdio.h>

 

typedef char *va_list;

 

 

#define  _AUPBND                 (sizeof (signed int) - 1)

#define  _ADNBND                (sizeof (signed int) - 1)

 

 

#define _bnd(X, bnd)            (((sizeof (X)) + (bnd)) & (~(bnd)))

#define va_arg(ap, T)           (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))

#define va_end(ap)              (void) 0

#define va_start(ap, A)         (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))

 

 

int max ( int num, ... )

{

    int m = -0x7FFFFFFF;

    int i;

     va_list ap;

    va_start ( ap, num );

    for ( i= 0; i< num; i++ )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值