免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3043 | 回复: 10
打印 上一主题 下一主题

我也来做嵌入式 linux(连载二) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-10-10 10:21 |只看该作者 |倒序浏览
昨天建好了工作空间,搭建好了交叉编译环境,今天来编译内核

———————————————————————————————————
第三章        内核编译
1、        编译
因为我打算新系统应该支持网桥,而且需要网桥下Netfilter的支持,所以先到sourceforge下载2.4.18内核的网桥补丁bridge-nf-0.0.8-bds-against-2.4.18.diff.gz。我下载的URL:
http://sourceforge.net/project/showfiles.php?group_id=39571&package_id=49683
偷个懒,在Win2000下解压,然后拷贝到内核所在目录
给内核打补丁:
[root@skynet linux-2.4.18]# patch -p1 <bridge-nf-0.0.8-bds-against-2.4.18.diff
patching file include/linux/netfilter.h
patching file include/linux/netfilter_ipv4.h
patching file include/linux/skbuff.h
patching file net/bridge/br.c
patching file net/bridge/br_forward.c
patching file net/bridge/br_input.c
patching file net/bridge/br_private.h
patching file net/bridge/Makefile
patching file net/Config.in
patching file net/core/netfilter.c
patching file net/core/skbuff.c
patching file net/ipv4/ip_output.c
patching file net/ipv4/netfilter/ip_tables.c
patching file net/ipv4/netfilter/ipt_LOG.c
patching file net/bridge/br_netfilter.c

开始编译内核:
# make ARCH=i386 CROSS_COMPILE=i386-linux- menuconfig
根据实际情况选择,以前还没有在2.4.18下边做过支持网桥的测试,找了半天没有找到
netfilter (firewalling) support
这个东东,郁闷了,管它的,继续……

# make ARCH=i386 CROSS_COMPILE=i386-linux- clean dep

# make ARCH=i386 CROSS_COMPILE=i386-linux- bzImage

总算可以去上洗手间了……
OK,编译完成,673K,稍微大了点,得想办法做到512以下才好,算了,等整个系统做完了,再回头来想办法做这个工作。

因为没有选择内核支持,建立/安装内核的步骤工作又省了……

2、        安装
先将编译好的压缩的内核映像、未压缩的内核映像、内核符号映射文件以及配置文件拷贝到${PRJROOT}/images中:
# cp arch/i386/boot/bzImage ${PRJROOT}/images/bzImage-2.4.18-rmk5
# cp vmlinux ${PRJROOT}/images/vmlinux-2.4.18-rmk5
# cp System.map ${PRJROOT}/images/System-2.4.18-rmk5
# cp .config ${PRJROOT}/images/2.4.18-rmk5

清理内核源码,让它恢复到初始状态:
# make ARCH=i386 CROSS_COMPILE=i386-linux- distclean

3、        测试内核
将bzImage-2.4.18-rmk5拷贝至boot目录下,编译lilo.conf
#vi /etc/lilo.conf
加入如下语句:

image=/boot/bzImage-2.4.18-rmk5
        label=linux-bridge
        root=/dev/hda1
        read-only
        append="root=/dev/hda1"
重新安装lilo:
#lilo
Added linux-bridge
Added linux *

重启系统试试……
还算好,一切顺利,系统启来了……
花费时间:30分钟

总结:
1、编译内核时,没有看到针对2.4.19时,网桥下那个netfilter (firewalling) support选项,是2.4.18本身就没有吗,还是补丁打得不对?没有经验,希望哪位大哥指正;

2、没有仔细根据目标机的实际硬件配置,来精简内核。希望等系统做完整了,能正常运行了,以后再慢慢来把内核精简了^


附,内核选择:
内核编译记录:
Code maturity level options                不选
Loadable module support                不选,不用模块支持,全部编译进内核,因为定位一个小型系统,功能非常简单,这样做,虽然扩展性差点,内核大点,不过可以省很多工作;
Processor type and features                根据实际,选择处理器类型
General setup  --->;
  • Networking support
  • PCI support
    (Any)   PCI access mode
  • PCI device name database
  • System V IPC
  • Sysctl support
    (ELF) Kernel core (/proc/kcore) format
  • Kernel support for ELF binaries
  • Power Management support

    Memory Technology Devices (MTD)  --->;                MTD设备,我用CF卡,不选

    Parallel port support  --->;                                        不选

    Plug and Play configuration  --->;                                我的系统用不着即插即用,不选

    Block devices  --->;
  • Loopback device support  
  • RAM disk support
    (4096)   Default RAM disk size (NEW)
  •    Initial RAM disk (initrd) support  

    Multi-device support (RAID and LVM)  --->;  不选

    Networking options  --->;                
    [ ]   Packet socket: mmapped IO                                                            
    [ ] Netlink device emulation
    [ ]   Network packet filtering debugging (NEW)  
    [ ] Socket Filtering
    [ ]   IP: kernel level autoconfiguration
    [ ]   IP: tunneling
    [ ] The IPX protocol
    [ ] Appletalk protocol support  
    [ ] DECnet Support
    QoS and/or fair queueing  --->; 不选

    ATA/IDE/MFM/RLL support  --->;                  用了默认的

    Telephony Support  --->;                不选

    SCSI support  --->;                 不选

    Fusion MPT device support  --->;         不选

    I2O device support  --->;                   不选

    Network device support  --->;                  根据实际情况选择

    Amateur Radio support  --->;                 不选   

    IrDA (infrared) support  --->;                不选

    ISDN subsystem  --->;                        不选

    Old CD-ROM drivers (not SCSI, not IDE)  --->;        不选

    Input core support  --->;                        不选

    Character devices  --->;  
  • Virtual terminal
  •    Support for console on virtual terminal
  • Standard/generic (8250/16550 and compatible UARTs) serial support
  •    Support for console on serial port

    Multimedia devices  --->;                 不选

    File systems  --->;
  • Kernel automounter version 4 support (also supports v3)
  • Virtual memory file system support (former shm fs)
  • /proc file system support
  • Second extended fs support

    Console drivers  --->;
  • VGA text console          调试时接显示器用

    剩下三个都不要
    Sound  --->;
    USB support  --->;  
    Kernel hacking  --->;
  • 论坛徽章:
    1
    荣誉版主
日期:2011-11-23 16:44:17
    2 [报告]
    发表于 2005-10-10 10:23 |只看该作者

    我也来做嵌入式 linux(连载二)

    建议发到同一个贴子中...

    论坛徽章:
    0
    3 [报告]
    发表于 2005-10-10 10:25 |只看该作者

    我也来做嵌入式 linux(连载二)

    先謝過, 若能做成一份完整的文檔, 那就更好了.

    论坛徽章:
    0
    4 [报告]
    发表于 2005-10-10 10:27 |只看该作者

    我也来做嵌入式 linux(连载二)

    [quote]原帖由 "惠繪洋"]先謝過, 若能做成一份完整的文檔, 那就更好了.[/quote 发表:


    因为这个是笔记,也就是我边做边记录的,所以目录还没有办法做成完整的文档,之所以现在就陆续发,是因为:
    1、我想把过程与大家分享;
    2、我在做的过程中,也会遇到一些问题和疑问,希望大家指正,帮助我;

    等系统做完整了,我就把文档整合,加上到时候大家给的意见和建议,把它做完整。

    论坛徽章:
    0
    5 [报告]
    发表于 2005-10-10 11:18 |只看该作者

    我也来做嵌入式 linux(连载二)

    Networking options  --->;
    [ ]   Packet socket: mmapped IO                                                            
    [ ] Netlink device emulation
    [ ]   Network packet filtering debugging (NEW)   
    [ ] Socket Filtering
    [ ]   IP: kernel level autoconfiguration
    [ ]   IP: tunneling
    [ ] The IPX protocol
    [ ] Appletalk protocol support   
    [ ] DECnet Support
    QoS and/or fair queueing  --->; 不选

    这些都不选?这个设备不在网络中用吗?

    另外,建议全部写在一个贴子中,这样易于管理和查看

    论坛徽章:
    0
    6 [报告]
    发表于 2005-10-10 13:04 |只看该作者

    我也来做嵌入式 linux(连载二)

    原帖由 "platinum" 发表:

    这些都不选?这个设备不在网络中用吗?

    另外,建议全部写在一个贴子中,这样易于管理和查看


    呵呵
    [ ] The IPX protocol
    [ ] Appletalk protocol support   
    [ ] DECnet Support
    这三个肯定是不选了,我是在以太网及tcp/ip网络中用的
    [ ]   IP: tunneling
    这个功能偶暂时用不着,就没有选
    [ ]   IP: kernel level autoconfiguration
    内核级的自动配置?不知是拿来做什么用的?查资料没有查到;
    [ ] Socket Filtering
    []Packet socket: mmapped IO
    这两个好像DHCP会用到的,选的时候忽略了……回头添上;
    [ ]   Network packet filtering debugging (NEW)  
    这个也用不上……
    [ ] Netlink device emulation
    这个是拿来做什么的?唔知了……

    _____________________________________________
    我系统做完,会把文档合在一起,重新发的……现在是边做边写了

    论坛徽章:
    0
    7 [报告]
    发表于 2005-10-10 13:39 |只看该作者

    我也来做嵌入式 linux(连载二)

    把剩下的内容都发到这个贴,中午吃饭的时候,边吃边完成了根文件系统的制作:

    ———————————————————————————————————
    第四章        制作根文件系统
    1、建立目录
    构建工作空间时,rootfs文件夹用来存放根文件系统,
    #cd rootfs
    根据根文件系统的基本结构,建立各个对应的目录:
    # mkdir dev etc lib proc sbin tmp usr var
    # chmod 1777 tmp
    # mkdir usr/bin usr/lib usr/sbin
    # ls
    dev  etc  lib  proc  sbin  tmp  usr  var
    # mkdir var/lib var/lock var/log var/run var/tmp
    # chmod 1777 var/tmp

    准备好根文件系统的骨架后,把前面建立的文件安装到对应的目录中去。

    2、拷贝链接库
    把uclibc的库文件拷贝到刚才建立的lib文件夹中:
    # cd ${PREFIX}/uclibc/lib
    [root@skynet lib]# for file in libuClibc ld-uClibc libc libdl \
    >; libcrypt libm libresolv libutil
    >; do
    >; cp $file-*.so ${PRJROOT}/rootfs/lib
    >; cp -d $file.so.[*0-9] ${PRJROOT}/rootfs/lib
    >; done
    cp: cannot stat `libuClibc.so.[*0-9]': No such file or directory
    cp: cannot stat `libc-*.so': No such file or directory
    有两个文件报找不到,是因为它们本身就不存在,没有关系。
    当然,也不必非要全部拷贝,可以根据实际需要来取舍。

    4、        拷贝内核映像和内核模块
    因为没有模块,所以拷贝模块就省了,
    新建boot目录,把刚才建立好的内核拷贝过来
    # cd /home/kendo/control-project/daq-module/rootfs/
    # mkdir boot
    # cd ${PRJROOT}/images
    # cp bzImages-2.4.18-rmk5 /home/kendo/control-project/daq-module/rootfs/boot

    5、        建立/dev下边的设备文件
    在linux中,所有的的设备文件都存放在/dev中,使用mknod命令创建基本的设备文件。
    mknod命令需要root权限,不过偶本身就是用的root用户,本来是新建了一个用户专门用于嵌入式制作的,不过后来忘记用了……
    # mknod -m 600 mem c 1 1   
    # mknod -m 666 null c 1 3
    # mknod -m 666 zero c 1 5
    # mknod -m 644 random c 1 8
    # mknod -m 600 tty0 c 4 0
    # mknod -m 600 tty1 c 4 1
    # mknod -m 600 ttyS0 c 4 64
    # mknod -m 666 tty c 5 0
    # mknod -m 600 console c 5 1
    基本的设备文件建立好后,再创建必要的符号链接:
    # ln -s /proc/self/fd fd
    # ln -s fd/0 stdin
    # ln -s fd/1 stdout
    # ln -s fd/2 stderr
    # ls
    console  fd  mem  null  random  stderr  stdin  stdout  tty  tty0  tty1  ttyS0  zero

    设备文件也可以不用手动创建,听说RedHat /dev下的脚本MAKEDEV 可以实现这一功能,不过没有试过……

    基本上差不多了,不过打算用硬盘/CF卡来做存储设备,还需要为它们建立相关文件,因为我的CF在目标机器上是CF-to-IDE,可以把它们等同来对待,先看看Redhat 下边had的相关属性:
    # ls -l /dev/hda
    brw-rw----    1 root     disk       3,   0 Jan 30  2003 /dev/hda
    # ls -l /dev/hda1
    brw-rw----    1 root     disk       3,   1 Jan 30  2003 /dev/hda1
    对比一下,可以看出,had类型是b,即块设备,主编号为3,次编号从0递增,根限位是
    rw-rw----,即660,所以:
    # mknod -m 660 hda b 3 0
    # mknod -m 660 hda1 b 3 1
    # mknod -m 660 hda2 b 3 2
    # mknod -m 660 hda3 b 3 3

    6、        添加基本的应用程序
    未来系统的应用程序,基本上可以分为三类:
    1、        基本系统工具,如ls、ifconfig这些……
    2、        一些服务程序,管理工具,如WEB、Telnet……
    3、        自己开发的应用程序

    这里先添加基本的系统工具,有想过把这些工具的代码下载下来交叉编译,不过实在是麻烦,用BusyBox,又精简又好用……
    将busybox-1.00.tar.gz下载至sysapps目录下,解压:
    #tar zxvf busybox-1.00.tar.gz
    #cd busybox-1.00
    //进入配置菜单
    #make TARGET_ARCH=i386 CROSS=i386-uclibc- PREFIX=${PRJROOT}/rootfs menuconfig
    //建立依存关系
    #make TARGET_ARCH=i386 CROSS=i386-uclibc- PREFIX=${PRJROOT}/rootfs dep
    //编译
    #make TARGET_ARCH=i386 CROSS=i386-uclibc- PREFIX=${PRJROOT}/rootfs
    这回没有这么好运气了:
    /home/kendo/control-project/daq-module/sysapps/busybox-1.00/networking/udhcp/udhcp.a(files.o): In function `read_mac':
    files.o(.text+0x4e): undefined reference to `ether_aton'
    collect2: ld returned 1 exit status
    make: *** [busybox] Error 1
    编译udhcp报错了……
    重新进入menuconfig,取消udhcp的选项,重新来过,这回一切顺利了。编译完成,安装之:
    //安装
    #make TARGET_ARCH=i386 CROSS=i386-uclibc- PREFIX=${PRJROOT}/rootfs install
    完装完成,回头看看:
    # cd bin
    # ls
    addgroup  busybox  chown  delgroup  echo      kill   ls     mv       ping  rm     sleep
    adduser   chgrp    cp     deluser   grep      ln     mkdir  netstat  ps    rmdir  umount
    ash       chmod    date   dmesg     hostname  login  mount  pidof    pwd   sh     vi
    一下子多了这么多命令……

    注意:关于busybox的配置,交叉编译时比较关键的有以下几项:
    1、        指明编译器
  • Do you want to build BusyBox with a Cross Compiler?                                      (i386-uclibc-) Cross Compiler prefix  
    2、指明安装路径
    []Don't use /usr
    (${PRJROOT}/rootfs) BusyBox installation prefix  
    其它需要的命令,可以根据实际需要选择


    7、        系统初始化
    内核启动时,最后一个初始化动作就是启动init程序,当然,大多数发行套件的Linux都使用了与System V init相仿的init,可以在网上下载System V init套件,下载下来交叉编译。另外,我也找到一篇写得非常不错的讲解如何编写初始化文件的文件,bsd-init,回头附在后面。不过,对于嵌入式系统来讲,BusyBox init可能更为合适,在第6步中选择命令的时候,应该把init编译进去。
    #cd ${PRJROOT}/rootfs/etc
    #vi inittab
    我的inittal文件如下:
    #指定初始化文件
    ::sysinit:/etc/init.d/rcS       
    #打开一个串口,波特率为9600                                       
    ::respawn:/sbin/getty 9600 ttyS0
    #启动时执行的shell
    ::respawn:/bin/sh
    #重启时动作
    ::restart:/sbin/init
    #关机时动作,卸载所有文件系统
    ::shutdown:/bin/umount -a –r

    保存退出;

    再来编写rcS脚本:
    #mkdir  ${PRJROOT}/rootfs/etc/init.d
    #cd ${PRJROOT}/rootfs/etc/init.d
    #vi rcS
    我的脚本如下:
    #!/bin/sh

    #Set Path
    PATH=/sbin:/bin
    export PATH

    syslogd -m 60
    klogd

    #install /proc
    mount -n -t proc none /proc

    #reinstall root file system by read/write mode(need: /etc/fstab)
    mount -n -o remount,rw /

    #reinstall /proc
    mount -n -o remount,rw -t proc none /proc

    #set lo ip address
    ifconfig lo 127.0.0.1

    #set eth0 ip address
    #当然,这样子做只是权宜之计,最后做的应该是在这一步引导网络启动脚本,像RedHat
    #那样,自动读取所有指定的配置文件来启动
    ifconfig eth0 192.168.0.68 netmask 255.255.255.0

    #set route
    #同样的,最终这里应该是运行启动路由的脚本,读取路由配置文件
    route add default gw 192.168.0.1

    #还差一个运行服务程序的脚本,哪位有现成的么?
    #网卡/路由/服务这三步,事实上可以合在一步,在rcS这一步中,做一个循环,运行指定启动目录下的所有脚,先将就着这么做吧,确保系统能够正常启动了,再来写这个脚本。

    #set hostname
    hostname MyLinux

    保存退出。

    编写fstab文件
    #vi fstab
    我的fstab很简单:
    /dev/hda1 / ext2 defaults 1 1
    none /proc proc defaults 0 0

    终于差不多了,不过还有一些步骤:
    1、        为多用户做点准备;
    2、        移植至目标系统;
    3、        安装引导程序;
    睡个午觉再继续了……
  • 论坛徽章:
    0
    8 [报告]
    发表于 2005-10-11 09:12 |只看该作者

    我也来做嵌入式 linux(连载二)

    总算把系统做来可以启动了,这一步费了我的时间最久……
    ——————————————————————————————————
    第五章        初次整合
    当然,还有很多的工作没有做,不过已经等不及了,想试试新的系统能不能正常运行:
    1、        满足偶启动新系统的强烈愿望;
    2、        好证明我后边的工作都是正确的;

    我是先重新拿一个硬盘来试的,因为以后目标机,都是had,而我现在直接挂上去,则会是hdb、hdc……这样,安装lilo时有点麻烦(虽然也可以实现)。所以我想了另一个办法:
            把新硬盘挂在IDE0的primary上,进入linux后,会被认为是had;
            原来主机的装Redhat的硬盘,我将它从IDE0的primary上变到了IDE1 的primary,因为它的lilo早已装好,基本上不影响系统的使用;
            BIOS中改为从第二个硬盘启动;

    分区
    #fdisk /dev/hda
    用d参数删除已存在的所有分区
    用n参数新建一个分区,也是就/dev/hda1

    格式化
    #mkfs.ext2 /dev/hda1

    打算用lilo引导系统,准备配置文件
    #cd ${PRJROOT}/rootfs/etc
    #vi target.lilo.conf
    boot=/dev/hda
    disk=/dev/hda
            bios=0x80
    image=/boot/bzImage-2.4.18-rmk5
            label=Linux
            root=/dev/hda1
    append="root=/dev/hda1"
            read-only

    这个新的引导程序配置文件名为target.lilo.conf,它是放在rootfs/etc下,可不要放到/etc中去了。

    新建文件夹,为mount做新准备
    #mkdir /mnt/cf
    #mount –t ext2 /dev/hda1 /mnt/cf
    回到rootfs
    #cd ..
    拷贝所有文件至目标硬盘
    #cp –r * /mnt/cf

    安装lilo
    这一步很关键,也就是为我的目标硬盘安装引导程序。
    #lilo –r /mnt/cf –C etc/target.lilo.conf
    Fatal: open /boot/boot.b: No such file or directory
    这是因为lilo版本是22.3以前的。下载22.3,重新安装lilo
    再次安装lilo,完装完成后:
    # lilo -r /mnt/cf -C etc/target.lilo.conf
    Warning: LBA32 addressing assumed
    Added Linux *
    呵呵,成功了……,
    #umout /mnt/cf
    #reboot
    BIOS改一下,从第一个硬盘,也就是我的目标硬盘引导……
    阿门,希望一切顺利……
    可是,现实是无情的:
    Kernel panic:NO init found.Try passing init=option to kernel
    只有再次重来,找原因吧……
    ……记得上次做的时候,在这一步重启了十多次机器……原本以为这回运气会好一点呢……
    都怪上回没有做笔记,这回所有的一切要从头来了。
    1、        内核编译错误?排除,前面编译好的时候在原来的系统中能正确引导的;
    2、        没有init程序,或者是权限不足?排除,重进了原来的系统,运行了一下init,可以正常运行,权限是777,对应链接的busybox运行位都是x;
    3、        lilo中的分区指定有误?应该不是,root是mount成功的,又再仔细检查了一下target.lilo.conf,确认无误;
    4、        不会是内核编译时忘了把ext2编译进去吧? 检查内核配置文件:CONFIG_EXT2_FS=y,这个可能性也排除;
    5、        那会不会是busybox的问题了,我在redhat下运行是没有问题的,那会不会是busybox的动态链接库出了问题?
    重新进入busybox的配置菜单,将编译项调整为静态编译;重新对目标硬盘安装系统……

    怀着忐忑的心情,系统终于引导成功了……虽然报Bummer,could not run ‘/etc/init.d/rcS’ermission denied……呵呵,应该是建立一个文件的时候,运行的权限位出了问题,管它的,回头改了就是,先在享受几分钟偶的新系统!!

    总结:
    1、        busybox的编译出了问题,起先是udhcp部份出了问题,后来是因为使用动态库编译造成系统不能启动,说找不着init。看来偶还得回头仔细分析一下出现这个问题的原因才行。
    2、        系统现在能够运行了,接着可以慢慢完善它了

    论坛徽章:
    0
    9 [报告]
    发表于 2005-10-11 09:41 |只看该作者

    我也来做嵌入式 linux(连载二)

    顶一下

    论坛徽章:
    0
    10 [报告]
    发表于 2005-10-11 10:48 |只看该作者

    我也来做嵌入式 linux(连载二)

    [quote]原帖由 "Mc_Hill"]顶一下[/quote 发表:


    谢谢支持,我只是想把我的过程拿出来和大家分享一下,也希望大家不要走和我一样的弯路!!
    现在最头痛的事情有三样:
    1、起初没有做好整体规划,比如busybox的telnetd中,帮助文件里指明,需要
    your kernel needs:                                                                                                 CONFIG_UNIX98_PTYS=y                                                                    
    CONFIG_DEVPTS_FS=y  
    好像我起初编内核时,就没有注意,诸如此类……
    2、交叉编译一些软件时很麻烦,一个人做起来头绪太过烦杂,特别是装OpenSSH
    3、最要命的是,自己一些glibc下编译的程序,uclibc竟然过不了,虽然都是一些细节的问题,但是改起来太痛苦了……(现在我都在打算是不是要在原生主机上静态编译它们,然后拷贝过来算了……因为我的CF卡有128M嘛,应该够了,不过这都是万不得已的打算)

    不过做到这一步,还是挺顺利的,只是busybox遇到点点麻烦,花了些时间。我会继续做下去的,只要有时间!希望大家多关注、多帮助我!
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP