嵌入式学习小组
直播中

李茜

7年用户 167经验值
私信 关注

uclinux-20040408在44b0上的移植记录



  终于算是初步搞好了uclinux-20040408在44b0上的移植了。也只能说是初步吧,后续应该还会有很多问题浮出来滴~~

  照例,还是简单的纪录下所做的事吧:

    准备好源码包ucCinux-dist-20040408.tar.gz,uClinux-20040408-ARMSYS.patch,config_user,config_main,config_kernel。三个config_文件是杭州立宇泰公司准备的,感觉对自己的板子不太配,期间也制造了不少麻烦,浪费不少时间。那个patch文件也是立宇泰公司的,也是不太配吧,毕竟不是在那公司买的,也浪费了不少时间来修改。要修改的下面碰到时再说吧。

    解压,进入uClinux-dist目录后,先创建44B0目录吧,相当于UBOOT中复制B2板子相关文件样,这里的样板是4510,不太熟悉,貌似是网络功能强些。在vendors/Samsung/目录下创建44B0目录,并把4510内的文件复制到44B0。注意:这里创建的目录名只能是44B0,因为在立宇泰给的那个patch文件中的目录名是44B0,如果目录名不一致的话,在打补丁的时候会报错误。当然也可以修改patch文件,把相应的目录名字改为自己创建的目录名---那样的工作量还是比较大的。所以还是创建44B0名的目录比较好。

    回到uClinux-dist根目录。执行patch -p1 < uClinux-20040408-ARMSYS.patch后会提示有两个文件错误。都是在vendors/Samsung/44B0目录下,一个是Makefile,一个是rc。可根据补丁来修改。

    先修改rc吧,系统配置文件。比较简单,做如下修改:

    +/bin/expand /etc/ramfs2048.img /dev/ram1
    +mount -t ext2 /dev/ram1 /ramdisk
    +chmod 777 /ramdisk
    -最后一行
    +ifconfig eth0 192.168.168.101 netmask 255.255.255.0 up
    +cat /etc/motd

    在系统启动后,用ls -l 显示的内容即为些文件的内容。

    关于Makefile的修改有两种改法,看自己想要哪种咯。产要区别就在于想要生成哪种目标文件。体现在image后的实现上,现将相同的修改部分先列出吧:

    -IMAGE = $(IMAGEDIR)/image.bin
     -ELFIMAGE = $(IMAGEDIR)/image.ram
    +ROMIMAGE = $(IMAGEDIR)/image.rom
    +RAMIMAGE = $(IMAGEDIR)/image.ram

    *) echo "ttyS0:linux:/bin/sh" >>
    esac

    $(ROMFSINST) /etc/motd
    -$(ROMFSINST) /etc/boa.conf
    -$(ROMFSINST) index.html /home/index.html
     $(ROMFSINST) /etc/passwd
    echo "$(VERSIONSTR)"
    +cp $(ROOTDIR)/user/ramimage/ramfs2048.img
       $(ROOTDIR)/romfs/etc/ramfs2048.img

    -cat $ ~~~~~~

    image:

    -$(CROSS_COMPILE)  注:注释掉原有的两个编译

    -$(CROSS_COMPILE)  

 在此体现两种改法的不同:第一种,只要image.rom和image.ram两个目标文件。如下编译:

    +$(CROSS_COMPILE)ld -r -o $(ROOTDIR)/$(LINUXDIR)romfs.o         

    -b binary $(ROMFSIMG)
      +$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment     
      -S $(ROOTDIR)/$(LINUXDIR)/linux $(RAMIMAGE)
      +cp $(ROOTDIR)/$(lINUXDIR)/arch/armnommu/boot/zImage
      $(ROMIMAGE)

如果需要uclinux_ram.bin和uclinux_rom.bin文件的话就用这种改法:

   +$(CROSS_COMPILE)ld -r -o $(ROOTDIR)/$(LINUXDIR)/romfs.o
       -b binary $(ROMFSIMG)

      +$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment
       -S $(ROOTDIR)/$(LINUXDIR)/linux $(IMAGEDIR)/uclinux_ram.bin

     +$(ROOTDIR)/tools/gzip -9 $(IMAGEDIR)/uclinux_rom.bin

     +$(ROOTDIR)/tools/mkimage -A arm -O linux -T kernel -C gzip -a 0x0c008000 -e 0x0c008000 -n "uclinux-2.4-x" -d $(IMAGEDIR)/uxlinux_ram.bin.gz $(IMAGEDIR)/uclinux_rom.bin

    当然,两种改法的选择可以根据自己的需要。第一种改法得到的是两个下载到DRAM中运行的内核,为非压缩的,直接运行的内核。如果选用这种的话,还需要配以相应的其他的一些修改:

    Makefile文件下:

        TFTPDIR = /tftpboot

        +LINUXTARGET = bzImage

    增加zImage的编译,否则,在make image时,cp命令报:找不到$(ROOTDIR)/$(LINUXDIR)/arch/armnommu/root/zImage文件。不能生成image.rom文件。

    第二种改法的话就需要增加比较多的额外操作了,处理不好的话会提示比较多的错误,多半是一些工具准备不到位啦,比如mkimage。记得看过一篇文章教怎么用mkimage来制作这个目标文件的,由于找不到那篇文章了,具体操作也不知道了。大概是把uboot中的tools/目录里的mkimage.c编译成mkimage可执行文件(在我的uboot/tools目录下见到一个mkimage.o和mkimage,而且这个imkimage文件是可执行的)后,把

mkimage文件直接复制到vendors/Samsung/44B0目录下就行吧(有时间再找找吧,哎,真是的,有些资料不要时总在眼前晃呀晃的,真到了要的时候又找不到了)。这种改法生成的目标文件是可以下载到flash里自启动的,即UBOOT能加载的那种。关于两种编译得到的目标文件具体详情,可参见日志“image.ram image.rom zImage uImage”。

    到此,打补丁时遇到的问题解决了。接下来就该做做修改的工作了~~

    首先,这个uclinux默认选择的编译器为arm-elf-m68k的,本来就是针对m68k器件的嘛,可以理解。幸好还是给了选择的余地啊:当然体系是要ARM的,编译器是要arm-elf-的:

    linux-2.4/Makefile:
    #ARCH := armnommu   --->   ARCH := armnommu
    #CROSS_COMPILE = arm-elf-  -----> CROSS_COMPILE = arm-elf-

    接下来该做的事就是make menuconfig了。在这里就要用到立宇泰给的三个人不人,妖不妖的配置文件了。怎么说呢,还是有就好吧。至少有个框架,修修补补总还是能用,比没有还是要好的。想开始搞的那几天,没有这三个文件:config_user,config_main,config_kernel足足浪费了几天的时间。

    一步步来吧,很长很长,要慢慢来:

    make menuconfig:貌似只能这个想make xconfig的,但提示找不到wish命令

        选择好44B0器件和2.4内核后,再选择下面的第二和第三项,配置内核和配置应用。

这里没用那个config_main,感觉不用也行,选项比较少,且容易,主要是看的懂那几个提示单词。保存退出后,第一次运行后会提示一大堆什么的,一路按Enter就是咯。终于按完后会出来配置内核界面:

    这时才体现出立宇泰唯一的一点好处。这里也可以分两种方法,主要是内容太多了,还是简单点说吧:如果手头上有一个移植成功的源码可以对照,建议:先加载config_kernel,以配置个大概,等配置完后,编译之前,再对照移植成功的源码里的vendors/Samsung/44B0/config.linux2.4一项一项的对照,该加的加,该减的减。这样,现在做的工作虽然大一点,但编译的时候应该是一帆风顺的,可以减少时间的浪费,这个很重要。如果手头没有可参照的源码的话,建议:再加载了config_kernel文件后,再回过头去看哪些选项可以不要,哪些是要加上的,碰到不懂的选项和不认识的选项还有google嘛,这样也可以尽量减少时间的浪费。比如:在config_kernel这个文件里加入了对USB的支持,但貌似这个源码里的uclinux不支持USB,在编译的时候会提示错误,所以在最后的配置里就不要USB支持。还有一个很重要的是,在这个配置文件里,没有加入对串口和串口控制台的支持。哎~~还是在对照移植成功的源码时才发现的,怪不得开始移植时,总是发现一运行就神马都不显示~~~而一加入后,就立马显示了~~大意啊,白白浪费几天时间。同理,在配置应用时也采用相同的策略。经过一番的加加减减后,大概得出下列这些选项是要的:

配置应用:

vendors/Samsung/44B0/config.vendor
# Core Applications
CONFIG_USER_INIT_INIT=y
CONFIG_USER_INIT_CONSOLE_SH=y
CONFIG_USER_INIT_RUN_FIREWALL=y
CONFIG_USER_SASH_SH=y
CONFIG_USER_SASH_HISTORY=y
CONFIG_USER_SASH_REBOOT=y
CONFIG_USER_INIT_EXPAND=y
CONFIG_USER_INIT_EXPAND_NOZEROES=y
CONFIG_USER_VERSION_VERSION=y
CONFIG_USER_LOGIN_LOGIN=y
CONFIG_USER_AGETTY_AGETTY=y
# Library Configuration
CONFIG_LIB_LIBDES_FORCE=y
CONFIG_LIB_LIBSSL_FORCE=y
CONFIG_LIB_LIBGMP_FORCE=y
CONFIG_LIB_LIBG_FORCE=y
CONFIG_LIB_LIBPAM_FORCE=y
CONFIG_LIB_LIBPCAP_FORCE=y
CONFIG_LIB_ZLIB_FORCE=y
   CONFIG_LIB_LIBJPEG_FORCE=y
CONFIG_LIB_NCURSES_FORCE=y
# Network Applications
CONFIG_USER_DHCPCD_NEW_DHCPCD=y
CONFIG_USER_FTP_FTP_FTP=y
CONFIG_USER_FTPD_FTPD=y
CONFIG_USER_HTTPD_HTTPD=y
CONFIG_USER_ROUTE_IFCONFIG=y
CONFIG_USER_PING_PING=y
CONFIG_USER_ROUTE_ROUTE=y
CONFIG_USER_TELNETD_TELNETD=y
CONFIG_USER_TELNET_TELNET=y
CONFIG_LIB_LIBG=y
CONFIG_USER_TFTP_TFTP=y

# Miscellaneous Applications
CONFIG_USER_GDBSERVER_GDBSERVER=y
CONFIG_USER_LCD_LCD=y
CONFIG_USER_FILEUTILS_CAT=y
CONFIG_USER_FILEUTILS_CHGRP=y
CONFIG_USER_FILEUTILS_CHMOD=y
CONFIG_USER_FILEUTILS_CHOWN=y
CONFIG_USER_FILEUTILS_CMP=y
CONFIG_USER_FILEUTILS_CP=y
CONFIG_USER_FILEUTILS_DD=y
CONFIG_USER_FILEUTILS_GREP=y
CONFIG_USER_FILEUTILS_L=y
CONFIG_USER_FILEUTILS_LN=y
CONFIG_USER_FILEUTILS_LS=y
CONFIG_USER_FILEUTILS_MKDIR=y
CONFIG_USER_FILEUTILS_MKFIFO=y
CONFIG_USER_FILEUTILS_MKNOD=y
CONFIG_USER_FILEUTILS_MORE=y
CONFIG_USER_FILEUTILS_MV=y
CONFIG_USER_FILEUTILS_RM=y
CONFIG_USER_FILEUTILS_RMDIR=y
CONFIG_USER_FILEUTILS_SYNC=y
CONFIG_USER_FILEUTILS_TOUCH=y
CONFIG_USER_SHUTILS_DATE=y

# BusyBox
CONFIG_USER_BUSYBOX_BUSYBOX=y
CONFIG_USER_BUSYBOX_HOSTNAME=y
CONFIG_USER_BUSYBOX_IFCONFIG=y
CONFIG_USER_BUSYBOX_IFCONFIG_STATUS=y
CONFIG_USER_BUSYBOX_IFCONFIG_SLIP=y
CONFIG_USER_BUSYBOX_IFCONFIG_HW=y
CONFIG_USER_BUSYBOX_IFCONFIG_MEMSTART_IOADDR_IRQ=y
CONFIG_USER_BUSYBOX_MKDIR=y
CONFIG_USER_BUSYBOX_MOUNT=y
CONFIG_USER_BUSYBOX_MOUNT_LOOP=y
CONFIG_USER_BUSYBOX_MTAB_SUPPORT=y
CONFIG_USER_BUSYBOX_NFSMOUNT=y
CONFIG_USER_BUSYBOX_PING=y

# Tinylogin
CONFIG_USER_TINYLOGIN_TINYLOGIN=y
MicroWindows
CONFIG_USER_MICROWIN=y
CONFIG_USER_MICROWIN_OPTIMIZE=y
CONFIG_USER_MICROWIN_MICROWIN=y
CONFIG_USER_MICROWIN_NANOX=y
CONFIG_USER_MICROWIN_SHAREDLIBS=y
CONFIG_USER_MICROWIN_NWIDGET=y
CONFIG_USER_MICROWIN_OBJFRAMEWORK=y
CONFIG_USER_MICROWIN_MICROWINDEMO=y
CONFIG_USER_MICROWIN_MWPF_PALETTE=y
CONFIG_USER_MICROWIN_LINK_APP_INTO_SERVER=y
CONFIG_USER_MICROWIN_HAVE_GB2312_SUPPORT=y
CONFIG_USER_MICROWIN_X11=y
CONFIG_USER_MICROWIN_FRAMEBUFFER=y
CONFIG_USER_MICROWIN_FBVGA=y
CONFIG_USER_MICROWIN_VTSWITCH=y
CONFIG_USER_MICROWIN_PORTRAIT_MODE=y
CONFIG_USER_MICROWIN_FBREVERSE=y
CONFIG_USER_MICROWIN_VGALIB=y
CONFIG_USER_MICROWIN_HWVGA=y
CONFIG_USER_MICROWIN_CLEOVGA=y
CONFIG_USER_MICROWIN_TTYKBD=y
# Miscellaneous Configuration
CONFIG_USER_RAMIMAGE_RAMFS512=y
配置内核:

vendors/Samsung/44B0/config.linux-2.4-x
Automatically generated by make menuconfig: don't edit
CONFIG_ARM=y
CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_UCLINUX=y
MAGIC_ROM_PTR=y
# System Type
CONFIG_ARCH_SAMSUNG=y
CONFIG_SET_MEM_PARAM=y
DRAM_BASE=0C000000
DRAM_SIZE=00800000
FLASH_MEM_BASE=00000000
FLASH_SIZE=00200000
CONFIG_RAMKERNEL=y
CONFIG_BOARD_MBA44=y
CONFIG_SPU_NAME="S3C44B0X"
CONFIG_CPU_S3C44B0X=y
CONFIG_CPU_ARM710=y
CONFIG_CPU_32v4=y
CONFIG_CPU_32=y
   CONFIG_NO_PGT_CACHE=y
CONFIG_CPU_WITH_CACHE=y
CONFIG_ARM_CLK=60000000
CONFIG_SERIAL_S3C44B0X=y
# General setup
CONFIG_NET=y
CONFIG_NWFPE=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_FLAT=y
CONFIG_BINFMT_ZFLAT=y
CONFIG_KERNEL_ELF=y
CONFIG_LEDS=y
CONFIG_LEDS_TIMER=y
CONFIG_LEDS_CPU=y
# Networking options
CONFIG_PACKET=y
CONFIG_FILTER=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_NAT=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_MULTIPATH_SEQUENTIAL=y
CONFIG_IP_ROUTE_TOS=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_NET_ARP_LIMIT=y
CONFIG_ARP_LIMIT=20
CONFIG_NET_IPIP=y
CONFIG_NET_IPGRE=y
CONFIG_NET_IPGRE_BROADCAST=y
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_INET_ECN=y
CONFIG_SYN_COOKIES=y
CONFIG_VLAN_8021Q=y
# Network device support
CONFIG_NETDEVICES=y
# Ethernet (10 or 100Mbit)
CONFIG_NET_ETHERNET=y
CONFIG_NET_ISA=y
CONFIG_NE2000=y
CONFIG_NE2000_16b=y
# Block devices
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_BLKMEM=y
CONFIG_AMDFLASH=y
CONFIG_FLASHAUTO=y
CONFIG_FLASHAUTOBIT=y
# File systems
CONFIG_TMPFS=y
CONFIG_RAMFS=y
CONFIG_PROC_FS=y
CONFIG_ROMFS_FS=y
CONFIG_EXT2_FS=y
# Character devices
CONFIG_SERIAL_S3C44B0X=y
CONFIG_CONSOLE_UART=y
CONFIG_SERIAL_S3C44B0X_CONSOLE=y
# Serial drivers
CONFIG_SERIAL_S3C44B0X=y
CONFIG_SERIAL_S3C44B0X_CONSOLE=y
CONFIG_S3C44B0_DEFAULT_BAUDRATE=57600
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# Kernel hacking
CONFIG_FRAME_POINTER=y
CONFIG_NO_MMU_LARGE_ALLOCS=y ;解决分配内存不足问题
CONFIG_CONTIGUOUS_PAGE_ALLOC=y
# Library routines
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y

这里还有一个补充的问题是:有很多选项不是直接的,即,要选中前提选项才会显现的。比如CONFIG_NO_MMU_LARGE_ALLOCS。这个选项是解决在分配内在大于1M时的策略。若没有选择,则在遇到分配大于1M内存时会提示:Unable to allocate RAM for process text/data , errno 12等等相似的提示。而这个定义光这样在配置文件里加上也还是不行的。而是要在选择其前提选项时才有效。做如下选择:

        Code maturity level options

        Prompt for development and/or incomplete code/drivers

        Kernel hackingKernel hacking

        Non power-of-2 kernel allocator (EXPERIMENTAL)

        Allow allocating large blocks (> 1MB) of memory

这样,才能使CONFIG_CONTIGUOUS_PAGE_ALLOC=y生效。

    做完这些配置后,最好还是要检查一下几个关键点的实际情况。有这么几个关键点是要确认一下的:

    vendors/Samsung/44B0/config.arch
        CONSOLE_BAUD_RATE = 115200

    串口波特率,通常是115200与UBOOT中的一致,否则会什么也没有,或是乱码

    linux2.4/arch/armnommu/config.in
        if ["$CONFIG_BOARD_MBA44" = "Y"]
           define_int CONFIG_ARM_CLK 40000000
           define_bool CONFIG_SERIAL_S3C44B0X Y

    检查一下目标板调协的主频是否和UBOOT中设置的一致,是否设置了板子的串口等等关于串口,串口控制台等的设置是否生效。同样,如果在调试的时候发现串口上神马也没有,应该是这些设置中的一个或几个有问题,需要重新检查。

    还有一个重要的步骤就是:设置目标板。我的板子是44B0,相应的板子有MBA44,哎,这下才发现三星的好处,不管是UBOOT还是uclinux,三星的都有专门的对应,而LPC貌似还没有发现,这样移植所做的工作应该是最少的。现在就把板子相对应起来,相当于UBOOT里的建立相应的配置头文件一样。做如下工作:

    linux2.4/arch/armnommu/boot/Makefile
        ifeq($CONFIG_BOARD_MBA44),y))
                ZTEXTADDR=0X0C100000      //image.rom自解压地址。
               ZRELADDR=0X0C008000        //内核解压后代码输出起始地址。
         endif     

这里的两个地址很关键:ZTEXTADDR,如果只生成image.rom和image.ram目标文件的话,那么image.rom可以直接下载到ZTEXTADDR处,并可以直接运行;而image.ram则可以下载到ZRELADDR处直接运行。如果目标文件是ulcinuxrom.bin的话,在其加载地址,即mkimage命令参数-a后面的地址就应该是ZRELADDR。

    关于块驱动这里还是要检查一下的,如果没有则加上一些东西的,否则会影响到romfs文件系统的挂载。

    linux-2.4.x/drivers/block/blkmem.c:
如果没有定义CONFIG_BOARD_MBA44
就加上:
#ifdef CONFIG_BOARD_MBA44
extern char romfs_data[];
extern char romfs_data_end[];
#endif
再在
struct arena_t {
       .........
} arena[] = {  后加上

#ifdef CONFIG_BOARD_SNDS100
         {0, romfs_data, -1},
#endif

    最后就是挂载romfs文件系统咯 做如下修改:

    linux-2.4.x/arch/armnommu/vmlinux-armv.lds.in
        *(.got)下加上
        +romfs_data = .;
        +romfs.o
        +romfs_data_end = .;

    这样,基本的修改就大致好了,可以满足一般性的需求。感觉关键的地方还是在内核和应用的配置选项上。花的时间,花的冤枉时间最多的也就是因为没有配置好。配置好的最显著的标志就是,在编译时没有报错,一帆风顺的~~~当然,还是会有些疏漏,因此后面还会贴出些常见编译错误和解决方法。

    OK~现在要做的就是几个make了,在没有找到方法前,这几个make就差没把我搞疯了

    make dep:一般不会出问题,如果这有问题,那只能说明~~

    make lib_only:这个也不会出问题,如果有问题,建议下过一个源码包

    make user_only:问题多发地带:主要是配置问题,反复检查对照选项

    make romfs:前一步没问题的话,这步应该也不会有

    make image:通常提示找不到linux:no such file or direct:恭喜你,离成功又进了一步了

    make linux:这步也是问题多发地带,其实还是配置问题,有时甚至是操作不当引起的,应该检讨自          己的习惯了。最好是符合linux的习惯

    make image:如果上述一切OK的话,那这里也就OK了

    赶紧进入images/目录看下吧,romfs.img是肯定有的,也许会有image.rom,image.ram,image.bin

    uclinux_ram.bin,uclinux_rom.bin等等名称,无非就是.ram,.rom,.bin文件。

最后需要做的就是,把它们一一下载到板子上实际运行一下,如果运气好,见到了welcome to uclinux的话,说明成功了。运气不好,走到半路就死机了的话,再根据自己的板子,再反复检查一下内核和应用的配制和连接的地址等情况。

    贴下常见错误吧:

      make menuconfig的时候这样提示drivers/char/char.o: In function `write_mem':
/root/uClinux-dist/linux-2.4.x/drivers/char/mem.c:119: undefined reference to `s3c44b0x_console_init'
    做如下修改:linux2.4/driver/char/Makefile:
        #obj -$ (CONFIG_SERIAL_S3C44B0X)+=serial_s3c44bX.o去掉#

一般配置好内核和应用的话,就不会有神马错误了。除非还有些工作没做,比如说:启动内核运行到Console: colour dummy device 80x30就死掉了,说明你的二级向量表设置有问题。我的就是这样:

    linux2.4/include/asm-armnommu/proc/system.h        

        #ifdef CONFIG_BOARD_MBA44
          #undef vectors_base()
          #define vectors_base() (DRAM_BASE + 0x08)
        #endif

    根据自己UBOOT中设置的RAM中的二级中断异常向量表基地址修改vectors_base()的定义。我设置的二级跳转表在UBOOT中是0x0c000008,所以定义为DRAM_BASE + 0x08。

    再比如:当运行到Starting kernel时就死机;或是运行到Uncompressing Linux.............OK后就出现诸如:crc erro system halted;invalid compressed format (err 2) system halted什么的,大概就是UBOOT加载的那个压缩内核设置的地址有问题。简单的说呢,就是mkimage -a -e后面的地址参数设置不对咯,做适当修改就可以了。

    同时有一个重要的教训是:在你对错误提示没有有把握的了解或是把错误提示放到google上去找的时候发现只有自己有这样的问题时,最好放弃解决当前问题的想法,那样只会浪费更多的时间而没有任何好处。恰当的做法是回顾自己所做的选择,再重新考虑该在配置内核和应用时加上哪些或是减去哪些。


更多回帖

发帖
×
20
完善资料,
赚取积分