近期学习linux 内核移植的工作总结

1149阅读 0评论2013-01-09 行健天下ing
分类:

总结一下最近学习linux 内核移植的工作。
之前,在uboot已经调通了uboot 的smsc9115网卡驱动,现在总结一下最近做了些啥:
在我自己的2440核心板上:
1 调通了smsc9115,设置好通过netconsole输出内核启动信息
2 编译了最新版的busybox,增加了telnetd功能,可以通过telnet链接到开发板
3 修改了nand flash分区,把rootfs写到了nand flash上 并实现从nand flash上启动
4 配置系统输入日志

下面逐一归纳一下对内核配置和文件做的修改,以及参数设置。
===========================================================================
1 smsc9115驱动配置,和netconsole的配置
smsc9115 的配置我是从网上找到的blackfin的开发板上别人的配置,依葫芦画瓢的改写
了友善的配置文件mach-mini2440.c,加入网卡的头文件#include ,改网卡配置如下,此外就不需要再做别的,编译系统搞定其余的工作。
static struct resource mini2440_smsc911x_resources[] = {
    [0] = {
        .start = 0x20000000,
        .end   = 0x20000000 + SZ_64K - 1,
        .flags = IORESOURCE_MEM,
    },
    [1] = {
        .start = IRQ_EINT3,
        .end   = IRQ_EINT3,
        .flags = IORESOURCE_IRQ | IRQ_TYPE_LEVEL_LOW,
    },
};

static struct smsc911x_platform_config mini2440_smsc911x_pdata = {
    .irq_polarity  = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
    .irq_type      = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
    .flags         = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
    .phy_interface = PHY_INTERFACE_MODE_MII,
};
static struct platform_device mini2440_smsc911x = {
    .name          = "smsc911x",
    .id            = 0,
    .num_resources = ARRAY_SIZE(mini2440_smsc911x_resources),
    .resource      = mini2440_smsc911x_resources,    
    .dev = {
        .platform_data = &mini2440_smsc911x_pdata,
    },
};
------------------------------------------------------------------------------
netconsole配置则比较麻烦,先说uboot.由于我的核心板串口有别的用途,所以想把uboot的console改到网口上,同时也可以减少
传输内核映像所需要的时间。刚开始没有设置好网卡时,当然还是得用串口来烧写和操作。
在uboot的include/configs/mini2440.h 设置net console
#define CONFIG_NETCONSOLE 1
#define CONFIG_NET_MULTI 1
#define CONFIG_SMC911X  1
#define CONFIG_SMC911X_16_BIT  1
#define CONFIG_SMC911X_BASE    0X20000000
#define CONFIG_SYS_CONSOLE_IS_IN_ENV 1
#define CFG_CONSOLE_IS_IN_ENV 1
#define CONFIG_PREBOOT
#undef  CONFIG_SILENT_CONSOLE
#define CONSOLE_BOOTDELAY 10
/*设置LCD 做console输出*/
#define CONFIG_CFB_CONSOLE
编译uboot后,要设置uboot的环境变量,包括网卡ip地址,以及接收输出信息的pc地址,
这里nc是netconsole的意思:
setenv ipaddr 192.168.1.112
setenv serverip 192.168.1.111
setenv gateway 192.168.1.1
setenv ncip=192.168.1.111
stdin=nc
stdout=vga
stderr=nc
这里我把输入设置为网络,输出设置为lcd了。
保存这些参数后,重新启动uboot,用uboot源码下tool目录的netconsole工具连接:
netconsole 192.168.1.112 6666  
发现netconsole已经能把按键输入发给uboot,但每发一个字符,网卡都被重启一次。
于是又向internet大神求教,发现uboot的代码确实是那么整的,不知道是否我前头的网卡配置项里有问题,还算别的原因。
在 找到了一些头绪,于是自己把uboot的代码改了一下,在网络初始化的代码里
加了个全局变量,禁止二次初始化网络设备(可我现在找不着当初改了的代码在那文件里)。这次uboot的netconsole就工作正常了。
----------------------------------------------------------------------------------------
内核的netconsole则简单多了,保证启动时识别到网卡,则只需要在make meuconfig时
Device Drivers ->Network device support->Network console logging support (EXPERIMENTAL)  选上,
配置bootargs:
set bootargs noinitrd root=/dev/nfs rw nfsroot=192.168.1.111:/home/yang/linux/rootfs ip=192.168.1.112:192.168.1.111:192.168.1.1:255.255.255.0:eth0 console=tty0 console=ttySAC0,115200 netconsole=6666@192.168.1.112/,@192.168.1.111/
这个设置里,我把根文件系统设为nfs,console=tty0把启动信息输出到lcd,console=ttySAC0,115200输出到串口
netconsole=6666@192.168.1.112/,@192.168.1.111/指定了板的ip和端口,pc端口也是6666省略。
ip=192.168.1.112:192.168.1.111:192.168.1.1:255.255.255.0:eth0 在里分别是板ip,server ip也就是pc ip,网关是我的路由器ip.
而后在netconsole里tftp 0x30007fc0 uImage 下载内核,boom启动,可以看见未识别网卡前,内核启动信息都输出到了lcd和串口上,等网卡启动了,信息开始同时在3个console同时显示。
========================================================================================
2 编译了最新版的busybox,增加了telnetd功能,可以通过telnet链接到开发板
真得感谢这些无私的自由软件开发着,busybox最新的1.20.2版本好得我没有遇到任何麻烦,一次编译后就能用。
在busybox项目的网站上下了源码后,修改Makefile文件,
CROSS_COMPILE = /home/yang/toolschain/4.4.3/bin/arm-none-linux-gnueabi-
ARCH=arm
然后make menuconfig修改配置 ,这里我没有选择动态编译,而是选了静态,反正我flash大:
Busybox Settings ->Build Options ->Build BusyBox as a static binary
Busybox Settings ->Installation Options 填写你想编译后的文件存放的地方,可以是你将来做rootfs的目录。
Networking Utilities里默认已经又telnet,httpd ftpd等功能,我基本每改动,但我把print 和mail的选项都去了
其余的选项可以参考tekkaman的根文件制作文章里,关于编译busybox的章节。
退出后make ,make install;去安装目录看看,文件和符合链接都建立好了。
我的根文件系统原来是tekkaman的blog上下载的,我直接把新编译的busybox的几个目录都拷贝到原来的rootfs目录下,覆盖他旧版的busybox.
接下来配置telnetd的启动:
在/etc/init.d/rcS里加入
/usr/sbin/telnetd -l /bin/login
/bin/mkdir /dev/pts
/bin/mount -t devpts devpts /dev/pts
pts 是telnetd所需要,据网上的资料显示,还需要内核支持:UNIX98_PTYS=y DEVPTS_FS=y,不过我原来的内核里已经勾了这些选项。
之后在pc上telnet 192.168.1.112,输入用户名和密码,成功登录板子
在这里顺便把配置系统日志log也说了吧,因为也是需要修改rcS文件启动日志,把下面的内容加入rcS
/bin/dd bs 1 if=/proc/kmsg of=/var/run/kmsg &
/sbin/klogd /var/run/kmsg
/sbin/syslogd -0 /var/log/messages
则系统的日志写入了 /var/log/messages,内核的消息在/var/run/kmsg里.
不过,fstab里应该把var目录挂成ramfs,否则,日后换到flash中时会非常花时间和空间。
========================================================================================
3 修改了nand flash分区,把rootfs写到了nand flash上 并实现从nand flash上启动
我直接改了友善的配置,只分成100m的根文件系统和另外一个分区,准备做存放用户文件
static struct mtd_partition friendly_arm_default_nand_part[] = {

    [0] = {
        .name    = "root",
        .offset = 0x0,
        .size    = 1024 * 1024 * 100, //
    },
    [1] = {
        .name    = "nand",
        .offset = 0x06400000,
        .size    = 1024 * 1024 * 1024, //
    }
};
之后从友善下载来的mkyaff2image文件把rootfs目录打包成rootfs.img文件,通过uboot tftp下载到内存
nand erase 0 0x6400000
nand write 0x30008000 0 0x560000
这样文件系统就写到nand flash上了
然后修改bootarg:
set bootargs noinitrd root=/dev/mtdblock0 ip=192.168.1.112:192.168.1.111:192.168.1.1:255.255.255.0:eth0 console=tty0 console=ttySAC0,115200 netconsole=6666@192.168.1.112/,@192.168.1.111/
发现系统在mount完了rootfs后就kprinc挂掉了,于是我把bootarg改会去nfs启动,
手动mount上nand flash 分区
mount -t yaffs2 /dev/mtdblk0 /mnt/yaffs,
发现里面只有lost+found.其余啥都没有。又上网查了一下,发现可能是内核加的yaffs2源码和制作mkyass2imgae工具的源码不一样,导致yaffs2的tag不同,
写进去的image不能识别。
我想了一下,既然我都能启动能mountle ,何不直接把现在的nfs拷贝到nand flash里。于是我就直接拷贝rootfs下各目录,
当然,你得跳过proc 和sys目录,mount由于已经mount起来了,也不行。这几个目录就手动mkdir.
再修改bootargs启动,这次成功了。
======================================================================================
4 内核启动logo
友善的内核源码里设置有自己的启动logo,我嫌它档了信息输出的空间,想去掉,
查了一下,只要在menuconfig去掉device driver->Graphics support ->Bootup logo的选项就好了
这个logo的制作倒是要花些功夫。

上一篇:Linux内核驱动自动创建设备节点文件
下一篇:socket和send系统调用协议栈工作流程