Chinaunix首页 | 论坛 | 博客
  • 博客访问: 801758
  • 博文数量: 117
  • 博客积分: 2583
  • 博客等级: 少校
  • 技术积分: 1953
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-06 22:58
个人简介

Coder

文章分类
文章存档

2013年(1)

2012年(10)

2011年(12)

2010年(77)

2009年(13)

2008年(4)

分类: 嵌入式

2010-08-20 23:28:40

话说此时此刻,有那么一点小兴奋。尽管看了半年的内核代码,但还从来没有对主线代码做过改动。虽然写过那么两个小驱动,但是质量嘛,甚至都让人不好意思跟别人说自己写过内核代码。这算是一个小小的里程碑吧。不说别的啦,先贴上一段错误发生的上下文的信息。使用的内核的mini2440_defconfig,也就是mini2440的默认配置,然后针对mini2440的驱动程序做了一点点的修改。

Uncompressing Linux... done, booting the kernel.
Linux version 2.6.35.2 (hanpfei@hanpfei) (gcc version 4.3.2 (Sourcery G++ Lite 2008q3-72) ) #9 Wed Aug 18 03:21:53 CST 2010
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVT instruction cache
Machine: MINI2440
Memory policy: ECC disabled, Data cache writeback
CPU S3C2440A (id 0x32440001)
S3C24XX Clocks, Copyright 2004 Simtec Electronics
S3C244X: core 405.000 MHz, memory 101.250 MHz, peripheral 50.625 MHz
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256
Kernel command line: noinitrd root=/dev/nfs nfsroot=192.168.1.37:/media/mini2440/rootfs ip=192.168.1.39:192.168.1.37::255.255.255.0 console=ttySAC0,115200 init=/linuxrc mem=64M
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
Memory: 64MB = 64MB total
Memory: 60580k/60580k available, 4956k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    DMA     : 0xffc00000 - 0xffe00000   (   2 MB)
    vmalloc : 0xc4800000 - 0xe0000000   ( 440 MB)
    lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
    modules : 0xbf000000 - 0xc0000000   (  16 MB)
      .init : 0xc0008000 - 0xc0029000   ( 132 kB)
      .text : 0xc0029000 - 0xc03c3000   (3688 kB)
      .data : 0xc03e2000 - 0xc040aec0   ( 164 kB)
SLUB: Genslabs=11, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Hierarchical RCU implementation.
        RCU debugfs-based tracing is enabled.
        RCU-based detection of stalled CPUs is disabled.
        Verbose stalled-CPUs detection is disabled.
NR_IRQS:85
irq: clearing subpending status 00000003
irq: clearing subpending status 00000002
Console: colour dummy device 80x30
console [ttySAC0] enabled
Calibrating delay loop... 201.93 BogoMIPS (lpj=504832)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
gpiochip_add: gpios 288..303 (GPIOK) failed to register
gpiochip_add: gpios 320..334 (GPIOL) failed to register
gpiochip_add: gpios 352..353 (GPIOM) failed to register
NET: Registered protocol family 16
MINI2440: Option string mini2440=0tb
MINI2440: 't' ignored, touchscreen not compiled in
gpio_direction_output run successful.
the chip is not NULL.
bofore s3c_gpio_lock.
before s3c_gpio_do_setpull.
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 80000005 [#1]
last sysfs file:
Modules linked in:
CPU: 0    Not tainted  (2.6.35.2 #9)
PC is at 0x0
LR is at s3c_gpio_setpull+0x84/0xb8
pc : [<00000000>]    lr : []    psr: 60000093
sp : c3c23f68  ip : 00000b51  fp : 00000000
r10: 00000000  r9 : 00000000  r8 : 00000000
r7 : 00000002  r6 : 60000013  r5 : c03e8364  r4 : 00000001
r3 : c03e8758  r2 : 00000002  r1 : 00000001  r0 : c03e8364
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: c000717f  Table: 30004000  DAC: 00000017
Process swapper (pid: 1, stack limit = 0xc3c22270)
Stack: (0xc3c23f68 to 0xc3c24000)
3f60:                   c002504c c0008364 c002a818 c000b310 00000000 c000d900
3f80: 00000000 00000002 00000003 00000000 c03e7748 c03e6c70 00000000 00000000
3fa0: 00000000 00000000 00000000 00000000 00000000 c00226e8 c0008364 c000b328
3fc0: c00226e8 c0029384 c000b310 00000000 c040af40 c0022abc c00226e8 c0008364
3fe0: c002a818 00000013 00000000 c0008400 00000000 c002a818 e5960000 e596102c
[] (s3c_gpio_setpull+0x84/0xb8) from [] (mini2440_init+0x1a4/0x364)
[] (mini2440_init+0x1a4/0x364) from [] (customize_machine+0x18/0x24)
[] (customize_machine+0x18/0x24) from [] (do_one_initcall+0x5c/0x1b4)
[] (do_one_initcall+0x5c/0x1b4) from [] (kernel_init+0x9c/0x14c)
[] (kernel_init+0x9c/0x14c) from [] (kernel_thread_exit+0x0/0x8)
Code: bad PC value
---[ end trace 1b75b31a2719ed1c ]---
Kernel panic - not syncing: Attempted to kill init!
[] (unwind_backtrace+0x0/0xec) from [] (panic+0x54/0xe4)
[] (panic+0x54/0xe4) from [] (do_exit+0x64/0x578)
[] (do_exit+0x64/0x578) from [] (die+0x1b4/0x1e0)
[] (die+0x1b4/0x1e0) from [] (__do_kernel_fault+0x64/0x84)
[] (__do_kernel_fault+0x64/0x84) from [] (do_page_fault+0x1b8/0x1cc)
[] (do_page_fault+0x1b8/0x1cc) from [] (do_PrefetchAbort+0x34/0x94)
[] (do_PrefetchAbort+0x34/0x94) from [] (__pabt_svc+0x44/0x80)
Exception stack(0xc3c23f20 to 0xc3c23f68)
3f20: c03e8364 00000001 00000002 c03e8758 00000001 c03e8364 60000013 00000002
3f40: 00000000 00000000 00000000 00000000 00000b51 c3c23f68 c0034c28 00000000
3f60: 60000093 ffffffff
[] (__pabt_svc+0x44/0x80) from [] (s3c_gpio_setpull+0x84/0xb8)
[] (s3c_gpio_setpull+0x84/0xb8) from [] (mini2440_init+0x1a4/0x364)
[] (mini2440_init+0x1a4/0x364) from [] (customize_machine+0x18/0x24)
[] (customize_machine+0x18/0x24) from [] (do_one_initcall+0x5c/0x1b4)
[] (do_one_initcall+0x5c/0x1b4) from [] (kernel_init+0x9c/0x14c)
[] (kernel_init+0x9c/0x14c) from [] (kernel_thread_exit+0x0/0x8)

根据kernel pacnic的信息,程序计数器PC的值竟然是0x0,而链接寄存器LR的值是s3c_gpio_setpull+0x84/0xb8,而这则说明了错误正是出在了s3c_gpio_setpull函数中,好像是在s3c_gpio_setpull函数中调用了一个函数,而那个函数的地址竟然是奇怪的0。因为如果没有跳转语句的话,PC值断然是不会莫名其妙的变为0的。

内核的开发者,这函数名起的,自文档性还是挺好的,一看文件名,我们就知道这个函数这个函数只不过是用来设置GPIO的上拉使能开关的。这对于系统来说,自然远远不是最最重要的部分。所以,直接把这个函数给改了,使这个函数只有一行代码,那便是:
return -EINVAL
系统果然成功的启动起来了。

这样的解决办法确实粗放了点了,这样的话,即使系统成功启动,貌似内核的GPIO子系统也是没有办法工作的。不过此时此刻,我们最想的自然是先把系统启动起来,待回头在仔细来看看这个s3c_gpio_setpull函数。

使用uboot 2009.11.1,将上面这个经过了修改以后编译的内核,使用tftpboot命令直接下载到内存中,bootm启动内核,一切OK,可以挂在NFS。
但是,当把内核映像下载到NAND flash中,启动的时候,却出问题了。提示打不开网卡。

现在最新版本的内核,DM9000的驱动移植的已经比较完善了。基本不需要做什么改动。唯一的问题就是MAC地址。在网卡驱动中需要添加设置MAC地址的代码。
在drivers/net/dm9000.c文件里的dm9000_probe函数中添加下面代码(1580行附近):

    if (!is_valid_ether_addr(ndev->dev_addr)) {

            ndev->dev_addr[0] = 0x0a;
            ndev->dev_addr[1] = 0x1b;
            ndev->dev_addr[2] = 0x2c;
            ndev->dev_addr[3] = 0x3d;
            ndev->dev_addr[4] = 0x4e;
            ndev->dev_addr[5] = 0x5f;

    }
当然,前提是,则配置内核的时候选中了对于DM9000网卡的支持:

Device Drivers --->

  Network device support --->

    [*] Network device support --->

      Ethernet (10 or 100Mbit) --->

        <*> DM9000 support


MAC地址也可以设置为其他自己喜欢的值,只要同一个局域网中不和其他机器发生冲突即可。

阅读(3671) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~