系统移植第五天

来源:互联网 发布:java能自学吗 编辑:程序博客网 时间:2024/06/04 13:35
系统移植第五天
printk
    1. 总的框架,见《printk工作原理》
    2. 查看console级别
       cat /proc/sys/kernel/printk
    3. 改console级别
       echo "6" > /proc/sys/kernel/printk
       
    4. 可以不从console输出消息,从/proc/kmsg文件输出,从这个文件输出只能读取一次消息,消息即被删除
    5. 为了能反复的读取内核消息,需要使用klogd工具,通常跟syslogd,klogd和syslogd共同把内核消息读取出来,放置到/var/log/messages
   
oops
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
// oops 编号
Internal error: Oops: 805 [#1]
last sysfs file:
Modules linked in:
// 第几个CPU出问题
CPU: 0 Not tainted (2.6.35 #19)
// cpu寄存器的值
PC is at s3c_fb_probe+0x10/0x6c0
LR is at platform_drv_probe+0x18/0x1c
pc : [<c028c22c>] lr : [<c01a4350>] psr: a0000013
sp : cfc29ee8 ip : 00000064 fp : 00000000
r10: 00000000 r9 : 00000000 r8 : 00000000
r7 : c03a39e0 r6 : c03a39e0 r5 : 00000000 r4 : c038f2d8
r3 : 00000002 r2 : 00000001 r1 : 00000868 r0 : c038f2d0
Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 10c5387d Table: 20004019 DAC: 00000017
// 栈信息(函数的调用历史)
Process swapper (pid: 1, stack limit = 0xcfc28268)
Stack: (0xcfc29ee8 to 0xcfc2a000)
9ee0: 00000000 cfdec450 00000000 cfc29f00 cfc07ae0 00000000
9f00: c038f30c c038f2d8 c038f2d8 c03a39e0 c03a39e0 00000000 00000000 00000000
9f20: 00000000 c01a4350 c038f2d8 c01a3478 c038f2d8 c038f30c c03a39e0 00000000
9f40: 00000000 c01a3588 c03a39e0 cfc29f58 c01a3528 c01a2d10 cfc01d08 cfc461c0
9f60: c03a39e0 c03a39e0 cfd91a80 c03a7b08 00000000 c01a2604 c03292a2 c03292a2
9f80: cfc24000 c03a39e0 c001fe50 00000000 00000013 00000000 00000000 c01a3858
9fa0: c001835c c001fe50 00000000 00000013 00000000 c0027380 c001835c c034375e
9fc0: c03b3e80 c03b3e80 c001fd3c c001fe50 c0028e1c 00000000 00000000 00000000
9fe0: 00000000 c000857c 00000000 c00084e0 c0028e1c c0028e1c fadafb7d 7bffafdd
[<c028c22c>] (s3c_fb_probe+0x10/0x6c0) from [<c01a4350>] (platform_drv_probe+0x18/0x1c) 
[<c01a4350>] (platform_drv_probe+0x18/0x1c) from [<c01a3478>] (driver_probe_device+0xa8/0x158)
[<c01a3478>] (driver_probe_device+0xa8/0x158) from [<c01a3588>] (__driver_attach+0x60/0x84)
[<c01a3588>] (__driver_attach+0x60/0x84) from [<c01a2d10>] (bus_for_each_dev+0x48/0x84) 
[<c01a2d10>] (bus_for_each_dev+0x48/0x84) from [<c01a2604>] (bus_add_driver+0x98/0x214) 
[<c01a2604>] (bus_add_driver+0x98/0x214) from [<c01a3858>] (driver_register+0xac/0x13c) 
[<c01a3858>] (driver_register+0xac/0x13c) from [<c0027380>] (do_one_initcall+0x58/0x1b0)
[<c0027380>] (do_one_initcall+0x58/0x1b0) from [<c000857c>] (kernel_init+0x9c/0x150)
[<c000857c>] (kernel_init+0x9c/0x150) from [<c0028e1c>] (kernel_thread_exit+0x0/0x8)
Code: e92d4ff0 e3a05000 e3a03002 e24dd01c (e5853000)
---[ end trace dec6997083161631 ]---
Kernel panic - not syncing: Attempted to kill init!
解决:
1. 找到崩溃程序的源代码位置
   arm-cortex_a8-linux-gnueabi-addr2line 0xc028c22c(崩溃点的程序指令地址) -e vmlinux(带调试信息的ELF文件) -f(打印出崩溃点所在的函数)
   
2. 将ELF文件反汇编,找到崩溃点
   arm-cortex_a8-linux-gnueabi-objdump -d vmlinux > vmlinux.dis
   
   
添加驱动模块到内核源码树
    原理:
    只需要知道,模块的Makefile原理及书写方法, 原理如下:
    1. 任务
       把驱动模块动态或静态编译到内核
   
    2. 动态编译到内核
       向内核的Makefile的obj-m变量中加入模块的目标代码
       例:
       obj-m := module_hello.o(由module_hello.c编译出来,使用的规则是自动推导)
       
    3. 静态编译到内核
       向内核的Makefile的obj-y变量中加入模块的目标代码
       obj-y := module_hello.o(由module_hello.c编译出来,使用的规则是自动推导)
       
    4. 通知上一级的Makefile调用驱动模块的Makefile
       在上级的Makefile的obj-y的变量中加入当前模块的目录:
       例:
       obj-y += test/
       
     经过这3步骤之后,我们就可以编译驱动模块到内核。
     
    5. 模块编译到内核的方式由Makefile决定,Makefile不是每个人都会修改,所以最好是能
       通过图形的办法,来决定模块编译到内核的方式。要做到这点,只需要Makefile变量
       obj-y和obj-m的后半部分能够换成变量,然后用图形产生变量的值。所以模块的Makefile可以
       写成如下方式:
       obj-$(CONFIG_TEST) := module_hello.o
       我们需要通过图形的方式产生CONFIG_TEST变量的值,需要通过Kconfig脚本产生,Kconfig脚本添加方法
       如下:
       1. 在模块中加入Kconfig,内容如下:
          config HELLO
      tristate "hello driver"
      help
       "hello driver info"
       
    2. 在上一级的Kconfig中,包含模块的Kconfig,方法如下:
       source "drivers/test/Kconfig"
    

内核调试实验
[console口输出实验]
在虚拟机中:
[1] 添加printk测试程序到内核,编译
1. 获取printk_test.c代码
2. 在drivers目录下新建printk_test, 然后拷贝代码到目录,命令如下:
    cd drivers
    mkdir printk_test
3. 添加Makefile, 在printk_test目录下新建Makefile(不能使dos)文件,然后添加如    下内容:
    obj-m = printk_test.c
4. 在drivers/Makefile文件中添加如下内容;
    obj-y += printk_test/
5. make 
[2] 拷贝printk_test.ko到/source/rootfs/lib/modules/2.6.35
cp drivers/printk_test/printk_test.ko /source/rootfs/lib/modules/2.6.35
 
在开发板中:
[3] 查看console级别
    cat /proc/sys/kernel/printk
    修改console级别
    echo "7" > proc/sys/kernel/printk
 
[4] 加载和卸载模块方法
加载:
insmod /lib/modules/2.6.35/printk_test.ko
卸载:
rmmod printk_test
[/proc/kmsg输出实验]
    cat /proc/kmsg查看文件内容即可
    注意:这个文件只能1次,读完之后内核会自动删除__log_buf里面的消息
 
[syslogd输出实验]
[1] 在启动shell脚本中,做如下事情:
  mount -t tamfs none /var
  mkdir /var/log
  klogd&
  syslogd&
  重启
[2] 查看log
 cat /var/log/messages
 tail /var/log/messages
0 0
原创粉丝点击