分类: LINUX
2011-11-28 15:00:38
1.uboot采用的是tekkamanninja-U-boot-2009.11_tekkaman-16deca6,根据自己的系统修改机器码就行。
2.内核源代码下载linux-2.6.25-android-1.0_r1.tar.gz
3.交叉编译器arm-linux-4.3.3
4.文件系统,使用的是busybox自己制作的普通的filesys,最后添加上网上下载的armv4.tar.gz提供的内容(注:刚开始还以为不能用,后来发觉还是可以的,主要是运行起来很慢,要等一会才能出现机器人图标)
整个移植过程中,内核配置主要看网上提供的一些文件,照着操作即可。主要做的工作是网卡的移植,mini2440上的网卡是DM9000A,源码中提供的应该是DM9000A,如果你在其它产品中成功应用过mini2440开发板,那么直接将你的网卡驱动移植过来就行,如果没有,可以参照tq2440提供的内核驱动,里面有DM9000A的驱动,我们只需要进行简单的修改就可以成功的驱动上 MINI2440 上面的 DM9000A 的网卡芯片。
现将调试过程中出现的一些记录全部写出来,由于过的时间很长了,没有整理过,需要的话各取所需:
网卡驱动移植(whizer)
转载:http://hi.baidu.com/maillzh3980/blog/item/e8fcf5edd8518af7b2fb95dd.html
一、驱动源码获取
在内核里面网卡驱动是相当完善的,这里需要注意一件事情,从 2.6.25 开始的内核的
“drivers/net/dm9000.c” 这个文件对应的 DM9000 的驱动(版本为 1.3 版)并不适合 DM9000E 这颗芯片,而在TQ2440 开发板上面用的是DM9000E这颗芯片,所以我们需要更换 “dm9000.c ”这个驱动程序,只要找到 1.2 版的 DM9000 的驱动就可以支持 DM9000E 这颗芯片了,下载一个linux-2.6.24.tar.bz2 的源码包,然后解压,提取 “drivers/net/dm9000.c ”这个文件,打开看一下,您可以发现这个驱动文件是 1.2 版本的,我们用它去替换掉 2.6.29.3 里面的对应源码即可开始进行我们的移植操作。
(注:以本人的经验实践证明,好像2.6.24的可以,而其他版本,虽然也是1.2的版本,编译也通不过,所以最好从2.6.24中提取,如果不信,大可 以一个一个的试试)
(就按上面说的作罢)
二、修改驱动源码
我们只需要进行简单的修改就可以成功的驱动上 TQ2440 上面的 DM9000 的网卡芯片。
修改内核源码的 “ arch/arm/plat-s3c24xx/common-smdk.c ” 文件:
在 46 行添加如下内容(红色部分所示):
#include
#include
#include
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
#include
#endif
/* LED devices */
static struct s3c24xx_led_platdata smdk_pdata_led4 = {
然后在 151 行左右,添加如下内容(红色部分所示):
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 10,
.twrph0 = 25,
.twrph1 = 10,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
/* DM9000 */
static struct resource s3c_dm9k_resource[] = {
[0] = {
.start = S3C2410_CS4, /* ADDR2=0 ,发送地址时使用这个地址 */
.end = S3C2410_CS4 + 3,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = S3C2410_CS4 + 4, /* ADDR2=1 ,传输数据时使用这个地址 */
.end = S3C2410_CS4 + 4 + 3,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_EINT7, /* 中断号 */
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ,
}
};
/* for the moment we limit ourselves to 16bit IO until some
* better IO routines can be written and tested
*/
static struct dm9000_plat_data s3c_dm9k_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};
static struct platform_device s3c_device_dm9k = {
.name = "dm9000",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_dm9k_resource),
.resource = s3c_dm9k_resource,
.dev = {
.platform_data = &s3c_dm9k_platdata,
}
};
#endif /* CONFIG_DM9000 */
/* devices we initialise */
static struct platform_device __initdata *smdk_devs[] = {
然后在 199 行左右,添加如下内容(红色部分所示):
static struct platform_device __initdata *smdk_devs[] = {
&s3c_device_nand,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
&s3c_device_dm9k,
#endif
};
修改内核源码的 “ drivers/net/dm9000.c ” 文件:
在 73 行添加如下内容(红色部分所示):
#include
#include
#include
#if defined(CONFIG_ARCH_S3C2410)
#include
#endif
#include "dm9000.h"
把从 118 行开始修改为如下内容(红色部分所示):
#ifdef CONFIG_BLACKFIN
#define readsb insb
#define readsw insw
#define readsl insl
#define writesb outsb
#define writesw outsw
#define writesl outsl
#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_HIGH)
#elif defined(CONFIG_ARCH_S3C2410)
#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_RISING)
#else
#define DM9000_IRQ_FLAGS IRQF_SHARED
#endif
(注:这个地方原博主解释的有点问题,注意了,可看清楚了,和源码照招,别站错误了)
在 414 行添加如下内容(红色部分所示):
static int
dm9000_probe(struct platform_device *pdev)
{
struct dm9000_plat_data *pdata = pdev->dev.platform_data;
struct board_info *db; /* Point a board information structure */
struct net_device *ndev;
unsigned long base;
int ret = 0;
int iosize;
int i;
u32 id_val;
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon;
unsigned int oldval_bankcon4;
#endif
/* Init network device */
在 428 行添加如下内容(红色部分所示):
/ * Init network device */
ndev = alloc_etherdev(sizeof (struct board_info));
if (!ndev) {
printk("%s: could not allocate device.\n", CARDNAME);
return -ENOMEM;
}
SET_NETDEV_DEV(ndev, &pdev->dev);
#if defined(CONFIG_ARCH_S3C2410)
oldval_bwscon = *((volatile unsigned int *)S3C2410_BWSCON);
*((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<16)) \
| S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;
oldval_bankcon4 = *((volatile unsigned int *)S3C2410_BANKCON4);
*((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;
#endif
PRINTK2("dm9000_probe()");
在 628 行添加内容(红色部分所示):
out:
printk("%s: not found (%d).\n", CARDNAME, ret);
#if defined(CONFIG_ARCH_S3C2410)
*((volatile unsigned int *)S3C2410_BWSCON) = oldval_bwscon;
*((volatile unsigned int *)S3C2410_BANKCON4) = oldval_bankcon4;
#endif
dm9000_release_board(pdev, db);
free_netdev(ndev);
return ret;
}
注意:还有一个问题,就是在1.2,编译“(board_info_t *) dev->priv”时,通不过。解决办法是,参照1.3,将所有的“(board_info_t *) dev->priv”改为“netdev_priv(dev)”,将所有的“(board_info_t *) ndev->priv”改为“netdev_priv(ndev)”。用替换不能全部改正,建 议先全部替换,然后手动搜索替换。
(注:上面的这断文中其实还是在这个dm9000.c替换的,只不过由于中间设计了*因此也不好替换(我指的是用vim),我的做法是用命令gedit 打开这个文本来编辑这个,这样好操作点,(不过最后好像还会出错一次,是因为有一个这样替换不料,就是(struct board_info_t *) ndev->priv),对于这个,就直接把他变成netdev_priv(ndev)就行了,这个原博注没有解释)
另外,这样编译之后网卡已经能够驱动,在linux中能正常使用,但是,如果使用nfs去不能正常下载文件系统,好像是网卡没驱动,如果要是他能使用 nfs,还必须修改dm9000.c:
dm9000_probe(struct platform_device *pdev)
{
struct dm9000_plat_data *pdata = pdev->dev.platform_data;
struct board_info *db; /* Point a board information structure */
struct net_device *ndev;
unsigned char ne_defethaddr[]={0x08,0x08,0x08,0x08,0x12,0x27,0};
(注:这个是mac地址,现在的mac地址一般已经不再设在网卡内部了,而是系统上电后从flash中读取的,所以说设置多少都无所谓,只是不要设成全0就行了(mac地址是6位,上面多了一位,也无所为))
const unsigned char *mac_src;
int ret = 0;
int iosize;
int i;
u32 id_val;
.
.
.
if (!is_valid_ether_addr(ndev->dev_addr)) {
/* try reading from mac */
for (i = 0; i < 6; i++)
ndev->dev_addr = ior(db, i+DM9000_PAR);
}
if (!is_valid_ether_addr(ndev->dev_addr)){
printk("%s: Invalid ethernet MAC address. Please "
"set using ifconfig\n", ndev->name);
for (i = 0; i < 6; i++)
ndev->dev_addr = ne_defethaddr;
}
(注:上面这一句原版有点问题(感觉是搂住不小心占错了,呵呵),得该一下,应该改为:ndev->dev_addr[i] = ne_defethaddr[i];记者这个地方一定要弄对,要不在后面虽然开发板可以上网,但是nfs就是连不成,我的就是这样(nfs),到最后是因为少了一个[],咳)
三、配置并编译内核
修改完以上的内容之后,输入: # make menuconfig ,进入配置单,然后添加上对 DM9000 网卡的配置 :
Device Drivers --->
Network device support --->
Ethernet (10 or 100Mbit) --->
-*- Generic Media Independent Interface device support
<*> DM9000 support
注:我是为了配置nfs,所以在这个地方加入配置nfs的选项:
File systems--->
[*]Networking File Systems--->
<*>NFS client support
[*]NFS client support for NFS version 3
[*]NFS client support for the NFSv3 ACL protocol extension
[*]Boot file system on NFS
[*]NFS server support
(4) DM9000 maximum debug level
配置好后,保存配置单,然后编译出镜像,烧写到开发板中。
dm9000.c (27.97 KB)
(下面的一部分,我没有管他,呵呵)
注意:我的板子是mini2440 所以unsigned char ne_defethaddr[]={0x08,0x90,0x90,0x90,0x90,0x90,0};而不是原版主的了 这里是MAC地址;还有就是我把ndev->dev_addr = ne_defethaddr修改为ndev->dev_addr[i] = ne_defethaddr[i] 要不然编译不过,还有就是将#include
【问题】
IP-Config: Complete:
device=eth0, addr=192.168.1.98, mask=255.255.255.0, gw=255.255.255.255,
host=192.168.1.98, domain=, nis-domain=(none),
bootserver=255.255.255.255, rootserver=192.168.1.88, rootpath=
Looking up port of RPC 100003/2 on 192.168.1.88
rpcbind: server 192.168.1.88 not responding, timed out
Root-NFS: Unable to get nfsd port number from server, using default
//网卡驱动的原因
借鉴mini2440的做法
在match-smdk2440.c中,加入match-mini2440.c的一些东西。
看看ok不?结果好像ok了,但是挂载不成功。
eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
IP-Config: Complete:
device=eth0, addr=10.107.4.147, mask=255.255.255.0, gw=10.107.4.145,
host=sbc2440, domain=, nis-domain=arm9.net,
bootserver=10.107.4.145, rootserver=10.107.4.145, rootpath=
Looking up port of RPC 100003/2 on 10.107.4.145
Root-NFS: Unable to get nfsd port number from server, using default
Looking up port of RPC 100005/1 on 10.107.4.145
rpcbind: server 10.107.4.145 not responding, timed out
Root-NFS: Unable to get mountd port number from server, using default
Root-NFS: Server returned error -5 while mounting /home/lzd/nfs
VFS: Unable to mount root fs via NFS, trying floppy.
VFS: Cannot open root device "nfs" or unknown-block(2,0)
网卡的数据流指示灯在闪。
他在工作了,只是很不稳定。
网上找了下,哦,原来是网卡驱动没有成功的初始化。
参考了 木椅子 的文章
http://blog.chinaunix.net/u3/101219/showart_2058344.html
只需要在dm9000.c文件中加上
//add by lzd
#include "dm9000.h"
#include
#include
#include
#include
#include
#include
#include
#define DM9000_IRQ IRQ_EINT7
在probe里加上
//add by lzd
unsigned int value;
value = __raw_readl(S3C2410_BWSCON);
value &= ~(S3C2410_BWSCON_WS4|
S3C2410_BWSCON_ST4|S3C2410_BWSCON_DW4_32);
value |= (S3C2410_BWSCON_ST4|S3C2410_BWSCON_DW4_16);
__raw_writel(value, S3C2410_BWSCON);
//config the bankcon4
value = 0;
value = (S3C2410_BANKCON_Tacs4|S3C2410_BANKCON_Tcos4|S3C2410_BANKCON_Tacc14|S3C2410_BANKCON_Tcoh4| \
S3C2410_BANKCON_Tcah4|S3C2410_BANKCON_Tacp6|S3C2410_BANKCON_PMCnorm);
__raw_writel(value,S3C2410_BANKCON4);
//config the irq pin (for mini2440)
set_irq_type(DM9000_IRQ,IRQ_TYPE_LEVEL_HIGH);
// s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_EINT7);
// s3c2410_gpio_pullup(S3C2410_GPF7, 0);
就ok了。
【问题】
Creating 5 MTD partitions on "NAND 256MiB 3,3V 8-bit":
0x000000000000-0x000000040000 : "supervivi"
uncorrectable error :
0x000000040000-0x000000060000 : "param"
ftl_cs: FTL header not found.
0x000000060000-0x000000560000 : "Kernel"
ftl_cs: FTL header not found.
0x000000560000-0x000040560000 : "root"
mtd: partition "root" extends beyond the end of device "NAND 256MiB 3,3V 8-bit" -- size truncated to 0xfaa0000
ftl_cs: FTL header not found.
0x000000000000-0x000040000000 : "nand"
mtd: partition "nand" extends beyond the end of device "NAND 256MiB 3,3V 8-bit" -- size truncated to 0x10000000
uncorrectable error :
//make menuconfig -> device driver->MTD 设置的问题
【问题】
nfs作为开发板根文件系统的技术补充细节
一开始的配置是启动之后完全没有反应,2.6.23,仅配置了
<*> NFS file system support
[*] Provide NFSv3 client support
[*] Provide client support for the NFSv3 ACL protocol extension
[ ] Provide NFSv4 client support (EXPERIMENTAL)
[*] Allow direct I/O on NFS files
启动参数
bootargs=console=ttyS0,115200 root=/dev/nfs rw ip=192.168.0.55 nfsroot=192.168.0.200:/mnt/new/nfs/rootfs
内核最后报错
VFS: Cannot open root device "nfs" or unknown-block(0,255)
Please append a correct "root=" boot option; here are the available partitions:
1f00 65536 mtdblock0 (driver?)
1f01 65536 mtdblock1 (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,255)
Rebooting in 180 seconds..
这个坎还是比较狠,幸好我有买书的好习惯。ELDD、Embedded Linux primer这种书真是充满了细节,每次阅读都能有新收获。原来NFS当根文件系统时必须配置
[*] Root file system on NFS
【问题】
网卡驱动加载后,无法mount rootfs:
-----------------------------------------------------------------------------------------------
[ 2.940000] ieee80211: 802.11 data/management/control stack, git-1.1.13
[ 2.950000] ieee80211: Copyright (C) 2004-2005 Intel Corporation
[ 3.490000] net eth0: link down
[ 3.490000] net eth0: normal mode
[ 3.500000] net eth0: multicast mode
[ 3.500000] net eth0: multicast mode
[ 4.510000] IP-Config: Complete:
[ 4.510000] device=eth0, addr=10.0.1.11, mask=255.255.255.0, gw=255.255.255.255,
[ 4.520000] host=enc28j60, domain=, nis-domain=(none),
[ 4.520000] bootserver=10.0.1.9, rootserver=10.0.1.9, rootpath=
[ 4.530000] Looking up port of RPC 100003/2 on 10.0.1.9
[ 39.540000] rpcbind: server 10.0.1.9 not responding, timed out
[ 39.540000] Root-NFS: Unable to get nfsd port number from server, using default
[ 39.550000] Looking up port of RPC 100005/1 on 10.0.1.9
[ 74.560000] rpcbind: server 10.0.1.9 not responding, timed out
[ 74.560000] Root-NFS: Unable to get mountd port number from server, using default
[ 109.570000] mount: server 10.0.1.9 not responding, timed out
[ 109.570000] Root-NFS: Server returned error -5 while mounting /home/nfs/rootfs
[ 109.580000] VFS: Unable to mount root fs via NFS, trying floppy.
[ 109.590000] VFS: Cannot open root device "nfs" or unknown-block(2,0)
[ 109.600000] Please append a correct "root=" boot option; here are the available partitions:
[ 109.600000] 1f00 512 mtdblock0 (driver?)
[ 109.610000] 1f01 8192 mtdblock1 (driver?)
[ 109.610000] 1f02 65536 mtdblock2 (driver?)
[ 109.620000] 1f03 187392 mtdblock3 (driver?)
[ 109.620000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
-----------------------------------------------------------------------------------------------
而对于正常的,加载驱动,并且mount rootfs的输出是:
-----------------------------------------------------------------------------------------------
[ 2.720000] ieee80211: 802.11 data/management/control stack, git-1.1.13
[ 2.730000] ieee80211: Copyright (C) 2004-2005 Intel Corporation
[ 3.270000] net eth0: link down
[ 3.270000] net eth0: normal mode
[ 3.280000] net eth0: multicast mode
[ 3.280000] net eth0: multicast mode
[ 3.320000] net eth0: link up - Half duplex
[ 4.300000] IP-Config: Complete:
[ 4.300000] device=eth0, addr=10.0.1.11, mask=255.255.255.0, gw=255.255.255.255,
[ 4.310000] host=enc28j60, domain=, nis-domain=(none),
[ 4.310000] bootserver=10.0.1.9, rootserver=10.0.1.9, rootpath=
[ 4.320000] Looking up port of RPC 100003/2 on 10.0.1.9
[ 4.360000] Looking up port of RPC 100005/1 on 10.0.1.9
[ 4.460000] VFS: Mounted root (nfs filesystem).
[ 4.470000] Freeing init memory: 100K
-----------------------------------------------------------------------------------------------
可以看出,是少了:
net eth0: link up - Half duplex
这一步,
最后的最后,终于搞清楚了,
原来是网卡驱动:
drivers\net\enc28j60.c中的probe函数:
static int __devinit enc28j60_probe(struct spi_device *spi)
中间,用到了GPIO2的初始化,去配置GPIO2,
而此处我的代码由于进行功耗管理,而在初始化的时候,将原先打开GPIO的clock关闭了,
导致此处虽然还是可以去配置gpio,但是实际没起效果,导致后面的网卡不能link up。
【解决办法】
确保网卡驱动初始化的时候涉及的clock时钟,都要开启,包括此处用到的GPIO的时钟,也要先打开。