从接触到成功,经过了一个礼拜了,查过看过的资料很多,但好多的都是不全面的,而且有些还把些重要的步骤省略了,使我走了很多的弯路,不过最可耻的是,有些书籍上的资料程序是乱抄来的,真是害人不浅呀,我觉得既然觉得要把东西贡献出来就应该些的更全面些,好让初学的兄弟们能少走些弯路,也别影响到他们的信心了。我决定把自己的经验写出来是因为我也是忙忙百度中过来的人。我将写下自己所知道的东西,尽量来让大家成功完成自己的事。
好了,现在我就开始说uclinux的移植了。
有些错误解决和经常会遇到的问题,我将在下篇文章中说到。
我采用的是立宇泰的uClinux-20040408-ARMSYS.patch补丁。
需要准备的软件包:
系统包:uClinux-dist-20040408.tar.gz
下载地址:http://www.uclinux.org/pub/uClinux/dist/uClinux-dist-20040408.tar.gz
补丁包:uClinux-20040408-ARMSYS.patch
下载地址:http://www.hzlitai.com.cn/download/uClinux-20040408-ARMSYS.rar
该补丁的作用是针对s3c44b0x对系统进行配置。
1 解压uClinux-dist-20040408.tar.gz
[root@localhost opt]# tar -zxvf uClinux-dist-20040408.tar.gz
解压后在当前目录下生成uClinux-dist目录。
移植主要涉及到的内容是:
⑴ linux-2.x.x
这个表示要选择的内核版本,目前提供的版本有2.6.x、2.4.x、2.0.x
⑵ linux-2.x.x/arch/armnommu
体系结构为不带mmu的arm,44B0是no memory unit的,因而系统结构(arch)选择的是带nommu的arm,而非arm。
⑶ vendors/Samsung/44B0
44B0是自已创建的文件夹,里面是针对开发板的系统配置文件,这和u-boot的结构相似,相当于u-boot的board,arch/armnommu相当于u-boot的cpu。
/**********************************************************************************
在此说一下uClinux-dist-200nmmdd.tar.gz与linux-2.x.x.tar.bz2的区别
uClinux-dist是一个综合包,里面含有厂商、驱动、内核等文件;而linux-2.x.x只是某个版本的内核,如linux-2.6.9
可以代替uClinux-dist中的linux-2.6.x文件夹;linux-2.x.x是有mmu的内核,
若开cpu没有mmu,则还需要为该内核打上对应的uc0.patch的包,如linux-2.6.9需打上linux-2.6.9-uc0.patch。
**********************************************************************************/
2 将uClinux-20040408-ARMSYS.patch拷到uClinux-dist里
[root@localhost opt]# cp uClinux-20040408-ARMSYS.patch uClinux-dist/
注意:这个包一定要放在uClinux-dist里打,如果uClinux-20040408-ARMSYS.patch放在uClinux-dist外,则会打不进去。
3 创建uClinux-dist/vendors/Samsung/44B0
[root@localhost opt]# cd uClinux-dist
[root@localhost uClinux-dist]# cd vendors/Samsung
[root@localhost Samsung]# mkdir 44B0
[root@localhost Samsung]# cp 4510B/* 44B0/
文件名一定要用44B0,因为patch里指定的是44B0,44B0里的文件是对开发板属性进行配置,config.arch是关于结构体系arm的一些配置
config.linux-2.x.x 是关于2.x.x版本内核的配置
config.uClinux 是关于库的配置,如若用到jng图库时,则需选择该库
config.vendor-2.4.x 是关于主板参数的设置
rc 关于ip的配置
4 打补丁
[root@localhost Samsung]# cd ../../
[root@localhost uClinux-dist]# patch -p1 < uClinux-20040408-ARMSYS.patch
-p1 是123的1而非mnl的l
打完补丁后出现如下提示:
/**********************************************************************************
. . . .
patching file kernel_44b0.cfg
patching file kernel_44b0.cfg.old
patching file kernel_4510.cfg
patching file kernel_4510.cfg.old
patching file Makefile
Hunk #1 FAILED at 5.
Hunk #2 FAILED at 40.
Hunk #3 FAILED at 187.
3 out of 3 hunks FAILED -- saving rejects to file Makefile.rej
patching file linux-2.4.x/arch/armnommu/vmlinux-armv.lds.in
Hunk #1 succeeded at 63 (offset 4 lines).
patching file vendors/Samsung/44B0/Makefile
patch: **** malformed patch at line 16516: @@ -55,23 +57,32 @@
**********************************************************************************/
由上可知出错的文件是vendors/Samsung/44B0/Makefile,所以我们须手动进行修改
所以以下我们将修改补丁错误。
5 修改补丁错误
打开uClinux-20040408-ARMSYS.patch,找到diff -Naur uClinux-dist/vendors/Samsung/44B0/Makefile,然后对照着修改/vendors/Samsung/44B0/Makefile文件。
uClinux-dist//vendors/Samsung/44B0/Makefile 修改后如下:
/---------------------------------------------------------------------------------------------------------------------------
ROMFSIMG = $(IMAGEDIR)/romfs.img
ROMIMAGE = $(IMAGEDIR)/image.rom
RAMIMAGE = $(IMAGEDIR)/image.ram
...
echo "$(VERSIONSTR) -- " `date` > $(ROMFSDIR)/etc/version
cp $(ROOTDIR)/user/ramimage/ramfs2048.img /
$(ROOTDIR)/romfs/etc/ramfs2048.img
image:
[ -d $(IMAGEDIR) ] || mkdir -p $(IMAGEDIR)
genromfs -v -V "ROMdisk" -f $(ROMFSIMG) -d $(ROMFSDIR)
$(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
---------------------------------------------------------------------------------------------------------------------------/
uClinux-dist//vendors/Samsung/44B0/rc修改如下
/---------------------------------------------------------------------------------------------------------------------------
hostname Samsung
/bin/expand /etc/ramfs.img /dev/ram0
/bin/expand /etc/ramfs2048.img /dev/ram1
mount -t proc proc /proc
mount -t ext2 /dev/ram0 /var
mount -t ext2 /dev/ram1 /var
chmod 777 /ramdisk
mkdir /var/config
mkdir /var/tmp
mkdir /var/log
mkdir /var/run
mkdir /var/lock
mkdir /var/empty
ifconfig lo 127.0.0.1
route add -net 127.0.0.0 netmask 255.255.255.0 lo
ifconfig eth0 192.168.1.70 netmask 255.255.255.0 up
cat /etc/motd
---------------------------------------------------------------------------------------------------------------------------/
6 修改uClinux-dist/linux-2.4.x/drivers/block/blkmem.c
在
#ifdef CONFIG_BOARD_SNDS100
extern char romfs_data[];
extern char romfs_data_end[];
#endif
后添加(——注意是添加——)
#ifdef CONFIG_BOARD_MBA44
extern char romfs_data[];
extern char romfs_data_end[];
#endif
将
#ifdef CONFIG_BOARD_MBA44
{0, 0XC7000000,-1}
#endif
改为
#ifdef CONFIG_BOARD_MBA44
{0, romfs_data,-1}
#endif
MBA44是一个板的名称,因为立宇泰这个补丁是针对MBA44来改的;当然不是说我们的开发板一定要是MBA44才行,MBA44只是个模板,相当于u-boot里的B2一样。
7 修改uClinux-dist/linux-2.4.x/drivers/char/Makefile
将
#obj -$(CONFIG_SERIAL_S3C44B0X) += serial_S3C44B0X.o
改为
obj -$(CONFIG_SERIAL_S3C44B0X) += serial_S3C44B0X.o
8 修改uClinux-dist/linux-2.4.x/arch/armnommu/config.in
将
# define_bool CONFIG_SERIAL_S3C44B0X
改为
define_bool CONFIG_SERIAL_S3C44B0X
9 增加bzImage
修改uClinux-dist/Makefile
在TFTPDIR = /tftpboot 后添加
LINUXTARGET = bzImage
10 设置开发板信息
⑴修改串口通信波特率
打开uClinux-dist/vendors/Samsung/44B0/config.arch,将波特率改为与u-boot统一的波特率
CONSOLE_BAUD_RATE =115200
⑵修改uClinux-dist/vendors/Samsung/44B0/config.linux-2.4.x
有可能顺序不同,但只要选项正确就可以
/---------------------------------------------------------------------------------------------------------------------------
#
# System Type
#
# CONFIG_ARCH_DSC21 is not set
# CONFIG_ARCH_C5471 is not set
# CONFIG_ARCH_CNXT is not set
# CONFIG_ARCH_NETARM is not set
# CONFIG_ARCH_TA7S is not set
# CONFIG_ARCH_TA7V is not set
# CONFIG_ARCH_SWARM is not set
CONFIG_ARCH_SAMSUNG=y
# CONFIG_ARCH_ATMEL is not set
# CONFIG_CPU_BIG_ENDIAN is not set
# CONFIG_SET_MEM_PARAM is not set
# CONFIG_RAMKERNEL is not set
# CONFIG_BOARD_SMDK40100 is not set
CONFIG_BOARD_MBA44=y
#CONFIG_ROMKERNEL=y
CONFIG_RAMKERNEL=y
# CONFIG_BOARD_EVS3C4530HEI is not set
# CONFIG_BOARD_S3C2500REFRGP is not set
# CONFIG_BOARD_SMDK2500 is not set
#CONFIG_BOARD_SNDS100=y
CONFIG_NO_PGT_CACHE=y
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
# CONFIG_CPU_4510B=y
CONFIG_CPU_S3C44B0X=y
CONFIG_CPU_ARM710=y
CONFIG_CPU_WITH_CACHE=y
# CONFIG_CPU_WITH_MCR_INSTRUCTION is not set
CONFIG_SET_MEM_PARAM=y
DRAM_BASE=0x0C000000
DRAM_SIZE=0x00800000
FLASH_MEM_BASE=0x01000000
FLASH_SIZE=0x00200000
…
CONFIG_NOFLASH=y
改为
#CONFIG_NOFLASH=y
---------------------------------------------------------------------------------------------------------------------------/
主要修改的几点:
选择开发板:CONFIG_BOARD_MBA44=y
修改CPU型号:CONFIG_CPU_S3C44B0X=y
选择内核模式:CONFIG_RAMKERNEL=y
设置DRAM和FLASH参数:
CONFIG_SET_MEM_PARAM=y
DRAM_BASE=0x0C000000
DRAM_SIZE=0x00800000
FLASH_MEM_BASE=0x01000000
FLASH_SIZE=0x00200000
⑶修改uClinux-dist/vendors/Samsung/44B0/config.vendor-2.4.x
注释掉CONFIG_USER_BUSYBOX_KILLALL=y
#CONFIG_USER_BUSYBOX_KILLALL=y
将
CONFIG_USER_LOGIN_LOGIN=y
改为
CONFIG_USER_LOGIN_LOGIN=n
将
CONFIG_USER_OLD_PASSWORD=y
改为
CONFIG_USER_OLD_PASSWORD=n
将
CONFIG_USER_BUSYBOX_BUSYBOX=y
改为
CONFIG_USER_BUSYBOX_BUSYBOX=n
11.定义二级异常中断矢量表的起始地址
修改文件:uClinux-dist/linux-2.4.x/include/asm-armnommu/proc/system.h
修改内容:
+#ifdef CONFIG_BOARD_MBA44
+#undef vectors_base()
+#define vectors_base() (DRAM_BASE)
+#endif
上面是网上的通用做法,我自己的是,只把vectors_base() 的对应地址为0x0c000000。没动它的结构。
说明:vectors_base()定义了二级异常中断矢量表的起始地址,这个地址与Bootloader中的_IRQ_BASEADDRESS相对应。
11 编译内核
⑴[root@localhost opt]#make distclean
⑵[root@localhost opt]#make menuconfig
①选择CPU
Vendor:Samsung
Product:44B0
② 选择内核
Kernel Version:linux-2.4.x
Libc Version:uClibc
Customize kernel setting:y
Customize vendor/user setting:y
③ 保存设置
④退出
退出后进行参数设置,参数的设置选择会自动按照vendors/Samsung/44B0 里的配置文件来选择。再配置过程会出现如下需要手动选择的:
Timer and CPU usage LEDs (CONFIG_LEDS) [N/y/?] (NEW) y
Timer LED (CONFIG_LEDS_TIMER) [N/y/?] (NEW) y
CPU usage LED (CONFIG_LEDS_CPU) [N/y/?] (NEW) y
FLASH type (NONE, AMD, INTEL) [NONE] (NEW) AMD
defined CONFIG_AMDFLASH
FLASH size (AUTO, 128KB, 1MB, 2MB, 4MB, 6MB, 8MB, 16MB) [AUTO] (NEW) (回车)
defined CONFIG_FLASHAUTO
FLASH bit width (AUTO, 8bit, 16bit, 32bit) [AUTO] (NEW) (回车)
2nd flash in /dev/rom8 (CONFIG_EXTRA_FLASH) [N/y/?] (NEW) N
Serial console device (NULL, UART) [UART] (NEW) (回车)
Anakin serial port support (CONFIG_SERIAL_ANAKIN) [N/y/?] (NEW) N
S3C44B0 serial port support (CONFIG_SERIAL_S3C44B0X) [Y/n/?]
Support for console on S3C44B0 serial port (CONFIG_SERIAL_S3C44B0X_CONSOLE) [Y/n/?]
Default S3C44B0 serial baudrate (CONFIG_S3C44B0_DEFAULT_BAUDRATE) [115200] (NEW) 57600
ARM AMBA serial port support (CONFIG_SERIAL_AMBA) [N/y/?] (NEW) N
CLPS711X serial port support (CONFIG_SERIAL_CLPS711X) [N/y/?] (NEW) N
DC21285 serial port support (CONFIG_SERIAL_21285) [N/y/?] (NEW) N
Excalibur serial port (uart00) support (CONFIG_SERIAL_UART00) [N/y/?] (NEW) N
SA1100 serial port support (CONFIG_SERIAL_SA1100) [N/y/?] (NEW) N
配置完毕后会弹出 kernel setting 和 vendor/user setting的设置窗口,直接按exit保存即可。
⑶ make dep
⑷ make lib_only
⑸ make user_only
[说明] 编译login,boa程序时可能出现 undefined reference to 'crypt_old'的错误,
boa.elf2flt: In function `auth_check_userpass':
/tmp/liming/uClinux-dist/user/boa/src/auth.c:281: undefined reference to `crypt_old'
可以修改
config/.config (uClinux-dist/vendors/Samsung/44B0/config.arch)
注释掉第25行的 CONFIG_USER_OLD_PASSWORDS
如下:
24 CONFIG_USER_LOGIN_LOGIN=y
25 # CONFIG_USER_OLD_PASSWORDS=y
26 # CONFIG_USER_ONLY_ROOT is not set
然后再
cd user/boa/src/
rm *.o
重新编译 make user_only 一下这个目录里面的 obj 文件就可以了。 ⑹ make romfs
⑺ make linux
这个编译会出现 cannot open romfs.o 这个错误提示,不理,因为romfs.o是在下一步产生的
在这里出错误后,把u-boot/tools中的mkimage文件复制到uclinux目录下的tools目录里,再在uclinux目录里搜索gzip文件,然后把它复制到tools目录里面去。然后继续下面的操作。
⑻ make image
这里产生No arch/armnommu/boot/zImage 错误,不理
⑼ make linux
⑽ make image
⑿ make
编译通过后会在uClinux-dist/images 里产生三个文件:
uclinux_ram.bin.gz uclinux_rom.bin romfs.img
uclinux_rom.bin 即是可以移植的。下载它到sdram中,然后bootm 地址,就可以了。
所有的步骤都经过我自己的测试,只要不要输入错误即可成功编译成功。
如果想下载到flash里运行的话,就把下载在sdram中的uclinux_rom.bin复制到flash里
运行 cp.b 地址1 地址2 长度
还有就是要把romfs.img文件复制到u-boot制定的地址上去。
最后,reset,就好了。
原文地址:http://hi.baidu.com/zhengju444/blog/item/4b5dfc71c54a49168601b038.html