- 建立Workspace:
- suggested project directory layout:
--------------------------------------------------------
bootldr —bootloaders
build-tools —packages needed to build the cross-platform toolchain
build-tools —packages needed to build the cross-platform toolchain
debug —debugging tools
doc —documentation
images —binary images of the bootloader,the kernel and the rootfs
kernel — for the kernel
project —configuration files and setting for this project
rootfs —the root filesystem for the target
sysapps —system applications for the target
tmp —temporary directory
tools —cross-platform toolchain and C library
----------------------------------------------------------------
----------------------------------------------------------------
建立一个脚本prj.sh,以方便以后的工作:
export PROJECT=PROJECT
export PRJROOT=/home/oneyoung/${PROJECT}
export TARGET=arm-unknown-linux
export HOST=i686-cross-linux-gnu
export PREFIX=${PRJROOT}/tools
export PRJROOT=/home/oneyoung/${PROJECT}
export TARGET=arm-unknown-linux
export HOST=i686-cross-linux-gnu
export PREFIX=${PRJROOT}/tools
export TARGET_PREFIX=${PREFIX}/${TARGET}
export PATH=${PREFIX}/bin:${PREFIX}/usr/sbin:${PATH}
cd $PRJROOT
----------------------------------------------------------建立文件夹:
source prj.sh
mkdir bootldr build-tools debug doc images kernel project rootfs sysapps tmp tools
二.Building the cross-platform toolchain
使用crosstool(http://kegel.com/crosstool):
Grab the Crosstool archive and unpack it:
cd $PRJROOT/bulid-tools/
wget http://kegel.com/crosstool/crosstool-0.43.tar.gz
tar -xzvf crosstool-*
cd crosstool-0.43
wget http://kegel.com/crosstool/crosstool-0.43.tar.gz
tar -xzvf crosstool-*
cd crosstool-0.43
由于依赖关系,先安装bison flex
建立一个脚本mytoolchain.sh
------------------------------------------------------
#/bin/bash
#/bin/bash
TARBALLS_DIR=download #where it will save source tarballs
RESULT_TOP=$PRJROOT/tools/ #where it will install the tools
GCC_LANGUAGES="c,c++" #which languages it will make compilers for
eval `cat arm.dat gcc-4.2-20061024-glibc-2.3.6.dat` sh all.sh —notest
-------------------------------------------------------------
运行mytoolchain.sh ……
出错:
--2010-07-17 16:11:59-- ftp://gcc.gnu.org/pub/gcc/snapshots/4.2-20061024/gcc-4.2-20061024.tar.bz2
=> `/home/oneyoung/PROJECT/build-tools/crosstool-0.43/tarballs/gcc-4.2-20061024.tar.bz2'
Resolving gcc.gnu.org... 209.132.180.131
Connecting to gcc.gnu.org|209.132.180.131|:21... connected.
Logging in as anonymous ... Logged in!
==> SYST ... done. ==> PWD ... done.
==> TYPE I ... done. ==> CWD (1) /pub/gcc/snapshots/4.2-20061024 ...
No such directory `pub/gcc/snapshots/4.2-20061024'.
file gcc-4.2-20061024.tar.bz2 not found
将gcc-4.2-20061024-glibc-2.3.6.dat 中,GCC_DIR改为gcc-4.2.0
再次运行,可以继续下载。
编译时出错:
configure: error:
*** These critical programs are missing or too old: as ld
*** Check the INSTALL file for required versions.
是由于as和ld 的版本问题,修改glibc-2.3.6文件夹下的configure文件:
在3920和3981行将2.1[3-9]*) 改为 2.[1-2][0-9]*)
可以继续编译。
再度出错:
inlined from ‘collect_execute’ at /home/oneyoung/project/build-tools/crosstool-0.43/build/arm-unknown-linux-gnu/gcc-4.2.0-glibc-2.3.6/gcc-3.3.6/gcc/collect2.c:1575:
/usr/include/bits/fcntl2.h:51: error: call to ‘__open_missing_mode’ declared with attribute error: open with O_CREAT in second argument needs 3 arguments
make[1]: *** [collect2.o] 错误 1
make[1]:正在离开目录 `/home/oneyoung/project/build-tools/crosstool-0.43/build/arm-unknown-linux-gnu/gcc-4.2.0-glibc-2.3.6/build-gcc-core/gcc'
make: *** [all-gcc] 错误 2
这纯属软件bug,因为使用open函数的时候,如果在第二个参数中使用了 O_CREAT,就必须添加第三个参数:创建文件时赋予的初始权限。而在gcc-3.3.6/gcc/的collect2.c文件中有漏掉第三个参数的错误,而gcc-4.3对语法错误的检查严格是出了名的(4.1就不会因此错误退出),所以就退出了。
这也是可以解决的,就是在gcc-3.3.6/gcc/collect2.c中的第1575行改为:
redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, 0777);
这也是可以解决的,就是在gcc-3.3.6/gcc/collect2.c中的第1575行改为:
redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT, 0777);
可以go on 了
又出错了 T_T:
*** buffer overflow detected ***: arm-unknown-linux-gnu-ar terminated
网上查了,据说是gcc的原因,法克犹!!
把gcc4.4.3换成gcc4.1,
然后重新链接sudo ln -s -f /usr/bin/gcc-4.1 /usr/bin/gcc
再度编译,狗日的还是出错,全部从新解压,在编译
出错:
/gcc-3.3.6-glibc-2.3.2/build-glibc/csu/version_info:2:1: missing terminating " character
第三行也有,打开文件,发现第2,3行最后没有换行符
把第3行删掉,第二行加个 \n” 可以继续
出错:
../sysdeps/generic/s_fmax.c: In function `__fmax':
../sysdeps/generic/s_fmax.c:28: internal compiler error: in elim_reg_cond, at flow.c:3328
找不到解决方法,只好放弃,换一个版本,重新改一下mytoolchain.sh
#/bin/bash
set -ex
TARBALLS_DIR=download #where it will save source tarballs
RESULT_TOP=$PRJROOT/tools/ #where it will install the tools
GCC_LANGUAGES="c,c++" #which languages it will make compilers for
export TARBALLS_DIR RESULT_TOP
export GCC_LANGUAGES
# Really, you should do the mkdir before running this,
# and chown /opt/crosstool to yourself so you don't need to run as root.
eval `cat arm9tdmi.dat gcc-4.1.0-glibc-2.3.2-tls.dat` sh all.sh --notest
echo Done.
。。。还是放弃,问题太多了,还是换一个把
使用buildroot:
下压缩包,复制到build-tools 并解压
然后 make menuconfig
提示没有ncurses libraries
运行:sudo apt-get install libncurses5-dev
make menuconfig
make uclibc-menuconfig
cp .config toolchain/uClibc/uClibc.config-local
或者:cp .config toolchain/uClibc/uClibc.config
之后make
提示:
You must install 'msgfmt' on your build machine
msgfmt is usually part of the gettext package in your distribution
运行:sudo apt-get install gettext
再make提示:
You must install 'makeinfo' on your build machine
makeinfo is usually part of the texinfo package in your distribution
运行:
sudo apt-get install gettext
再make后可以运行了。
一阵漫长的等待之后,出错:
checking for C compiler default output file name... configure: error: C compiler cannot create executables
See `config.log' for more details.
make: *** [/home/oneyoung/project/build-tools/buildroot-2010.05/output/toolchain/elf2flt/.configured] 错误 77
在
/home/oneyoung/project/build-tools/buildroot2010.05/output/toolchain/elf2flt/cofig.log中找到:
gcc version 4.1.3 20080704 (prerelease) (Ubuntu 4.1.2-27ubuntu1)
configure:1811: $? = 0
configure:1813: gcc -V </dev/null >&5
gcc: '-V' option must have argument
configure:1816: $? = 1
configure:1839: checking for C compiler default output file name
configure:1842: gcc -lz conftest.c >&5
/usr/bin/ld: cannot find -lz
collect2: ld returned 1 exit status
configure:1845: $? = 1
configure: failed program was:
运行:
apt-get install zlib1g-dev
run make again,先去吃饭。
回来后,发现已经装好了。
Summery:
1. 先解决依赖问题,装上gettext libncurses5-dev zlib1g-dev
2.make menuconfig
make uclibc-menuconfig
3.cp .config toolchain/uClibc/uClibc.config-local
或者:cp .config toolchain/uClibc/uClibc.config
4.make
Using the toolchain:
create a head file for Makefile:
#Tool names
CROSS_COMPILE=arm-linux-
AS=${CROSS_COMPILE}as
AR=${CROSS_COMPILE}ar
CC=${CROSS_COMPILE}cc
CPP=${CC} -E
LD=${CROSS_COMPILE}ld
NM=${CROSS_COMPILE}nm
OBJCOPY=${CROSS_COMPILE}objcopy
OBJDUMP=${CROSS_COMPILE}objdump
RANLIB=${CROSS_COMPILE}ranlib
READELF=${CROSS_COMPILE}readelf
SIZE=${CROSS_COMPILE}size
STRINGS=${CROSS_COMPILE}strings
STRIP=${CROSS_COMPILE}strip
exoprt CROSS_COMPILE AS AR CC CPP LD NM OBJCOPY OBJDUMP RANLIB READELF SIZE STRINGS STRIP
#Building setting
CFLAGS = -O2 -Wall
HEADER_OPS =
LDFLAGS =
Compile the Kernel:
extract the kernel archive to kernel/ directory:
cd kernel
tar -xvf ../tmp/downloads/linux* kernel
edit the Makefile:
find the ARCH and CROSS_COMPILE,
and change them like to
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
then configure the kernnel:
**remember: before start to configure the kernel ,copy
arch/arm/config/s3c2410_defconfig to .config
arch/arm/config/s3c2410_defconfig to .config
make menuconfig
make zImage
encounter with errors:
error: '__LINUX_ARM_ARCH__' undeclared (first use in this function)
--solution: rerun make menuconfig and select the machine 2440 to mini2440 board.
Then go on:
errors occur:
exec: 219: /home/oneyoung/project/tools/usr/bin/arm-linux-ld.real: not found
--solution:find the *.real file and make a sofe link to it.
ln -s arm-unknown-linux-uclibcgnueabi-ld.real arm-linux-ld.real
error still exits:
drivers/usb/core/hcd.c:145: error: expected expression before '>>' token
drivers/usb/core/hcd.c:145: error: expected expression before '>>' token
drivers/usb/core/hcd.c:166: error: expected expression before '>>' token
drivers/usb/core/hcd.c:166: error: expected expression before '>>' token
drivers/usb/core/hcd.c:189: error: expected expression before '>>' token
drivers/usb/core/hcd.c:189: error: expected expression before '>>' token
--solution: go back to hcd.c and find that LINUX_VERSION_CODE seems been defined but have no value.So edit the hcd.c in line 129 and 130 to:
#define KERNEL_REL ((KERNEL_VERSION(2,6,33) >> 16) & 0x0ff)
#define KERNEL_VER ((KERNEL_VERSION(2,6,33) >> 8) & 0x0ff)
to cheat the compile.
Errors again:
drivers/video/console/vgacon.c: In function 'vgacon_startup':
drivers/video/console/vgacon.c:508: error: 'PCIMEM_BASE' undeclared (first use in this function)
--find information in the web, and find that the chip s3c2440 does not support pci bus, so reconfig the kernel and disable this option.
Waiting a long time,eventually the zImage has been created.
Test the image – failed!!!
--solution:
1.go to arch/arm/tools/mach-types and find s3c2440 replace the last number with 168 (because u-boot set this way)
2.configure machine clock-- edit
arch/arm/mach-s3c2440/mach-smdk2440.c find s3c24xx_init_clocks and set like this:s3c24xx_init_clocks(12000000);
remake and download to the tq2440 board –
booting linux......
decompressing the kernel...
the kernel can unpack and run now!
**then create a bash script to copy the image to the images/ directory:
#/bin/bash
version=$(ls ${PRJROOT}/kernel/ | grep linux | awk -F- '{print $2}')
k_path=${PRJROOT}/kernel/linux-${version}
source ~/prj.sh
cp ${k_path}/arch/arm/boot/zImage ${PRJROOT}/images/zImage-${version}
cp ${k_path}/System.map ${PRJROOT}/images/System.map-${version}
cp ${k_path}/vmlinux ${PRJROOT}/images/vmlinux-${version}
cp ${k_path}/.config ${PRJROOT}/images/${version}.config
Building the kernel modules:
make modules
#Installing the kernel modules:
make ARCH=arm CROSS_COMPILE=arm-linux- INSTALL_MOD_PATH=${PRJROOT}/images/modules-2.6.33.5 modules_install
#build the modules dependency,since depmod in the kernel doesn't support cross-platform
#so using the depmod.pl script which can be found in busybox examples/ directory
#1.copy the depmod.pl to ${PREFIX}/usr/bin
#so using the depmod.pl script which can be found in busybox examples/ directory
#1.copy the depmod.pl to ${PREFIX}/usr/bin
cp ${PRJROOT}/sysapps/busybox*/examples/depmod.pl ${PREFIX}/usr/bin
#go to the kernel path
cd ${PRJROOT}/kernel/linux*
depmod.pl -F ./System.map -b ${PRJROOT}/images/modules-2.6.33.5/lib/modules/ > ${PRJROOT}/images/modules-2.6.33.5/lib/modules/2.6.33.5-oneyoung/modules.dep
#if the directory under lib/modules/ is .6.33.XXX rename it to 2.6.33.XXX
Summary:
1.building the kernel:
cp arch/arm/config/s3c2410_defconfig .config
make menuconfig
make zImage
##NOTE: in TQ2440 default u-boot, the zImage must smaller than 2Mb.
2.building the modules:
make modules
make ARCH=arm CROSS_COMPILE=arm-linux- INSTALL_MOD_PATH=${PRJROOT}/images/modules-2.6.33.5 modules_install
cp ${PRJROOT}/sysapps/busybox*/examples/depmod.pl ${PREFIX}/usr/bin
cd ${PRJROOT}/kernel/linux*
depmod.pl -F ./System.map -b ${PRJROOT}/images/modules-2.6.33.5/lib/modules/ > ${PRJROOT}/images/modules-2.6.33.5/lib/modules/2.6.33.5-oneyoung/modules.dep
#if the directory under lib/modules/ is .6.33.XXX rename it to 2.6.33.XXX
Root filesystem
1.basic root filesystem struct:
cd ${PRJROOT}/rootfs
mkdir bin dev etc lib proc sbin sys tmp usr var
chmod 1777 tmp
mkdir usr/bin usr/lib usr/sbin
mkdir var/lib var/lock var/log var/run var/tmp
chmod 1777 var/tmp
2.Libraries:
for uClibc do below--
cd ${PREFIX}/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
cp -d $file.so.[*0-9] ${PRJROOT}/rootfs/lib
done
or we can copy all lib directory to rootfs because it does not consume to much more space.
3.Kernel Modules:
cp -a ${PRJROOT}/images/modules-2.6.33.5/* ${PRJROOT}/rootfs
#here we use cp -a option to copy in archive mode.
#since we create modules in the above way, we don't need to explicit the lib/modules path to the cp.
#and we may need a /etc/modprobe.conf file
4.Kernel images:
5.Device files:
1)make essential entry in /dev directory:
cd ${PRJROOT}/rootfs/dev
sudo mknod -m 600 mem c 1 1
sudo mknod -m 666 null c 1 3
sudo mknod -m 666 zero c 1 5
sudo mknod -m 644 random c 1 8
sudo mknod -m 600 tty0 c 4 0
sudo mknod -m 600 tty1 c 4 1
sudo mknod -m 600 ttyS0 c 4 64
sudo mknod -m 666 tty c 5 0
sudo mknod -m 600 console c 5 1
#compulsory /dev symbolic links
ln -s /proc/self/fd fd
ln -s fd/0 stdin
ln -s fd/1 stdout
ln -s fd/2 stderr
2)Dynamic way – using busybox mdev
6.Main System Application
BusyBox:
cd ${PRJROOT}/sysapps
tar -xvf busybox*
cd busybox*
#then config the busy box
#be sure to enable the static binary mode
make menuconfig
make
make CONFIG_PREFIX=${PRJROOT}/rootfs install
#TODO:make the busybox binary setuid root
7.Storage Devices
1)installing MTD utilities for the host:
cd ${PRJROOT}/build-tools
git clone git://git.infradead.org/mtd-utils
cd mtd-utils
#solve some packages dependency
sudo apt-get install libacl1-dev zlib1g-dev liblzo2-dev uuid-dev
make
make DESTDIR=${PREFIX} install
2)installing the MTD-utils for the target:
**need to build libz and liblzo
(1)zlib:
cd ${PRJROOT}/build-tools
tar -xvf zlib*
cd zlib*
CC=arm-linux-gcc LDSHARED="arm-linux-ld --share" ./configure -s
#then edit the Makefile, add “-lgcc_s”to CFLAGS
#otherwise error will occur:
#hidden symbol `__aeabi_uidiv' is referenced by DSO
#hidden symbol `__aeabi_uidiv' is referenced by DSO
#final link failed: Nonrepresentable section on output
make
make prefix=${PREFIX} install
cd ${PREFIX}/lib
cp -d libz.so* ${PRJROOT}/rootfs/lib
(2)lzo:
cd ${PRJROOT}/build-tools
wget http://www.oberhumer.com/opensource/lzo/download/LZO-v1/lzo-1.08.tar.gz
tar -xvf lzo*
cd lzo*
CC=arm-linux-gcc ./configure –enable-shared –host
make
make prefix=${PREFIX} install
cp -d ${PREFIX}/lib/liblzo.so* ${PRJROOT}/rootfs/lib
(3)copy the ach.h
tar -xvf acl*
mkdir -pv ${PREFIX}/usr/include/sys
cp acl*/include/acl.h ${PREFIX}/usr/include/sys
(4)install mtd utils:
cd ${PRJROOT}/sysapps/
git clone git://git.infradead.org/mtd-utils
cd mtd-utils
#before compile:
#1.edit the common.mk and add “-static”to CFLAGS
#2.edit the Makefile and comment the “ubi”in the SUBDIRS line
#using without_largefile is because the uClibc I build does support large files.
make CROSS=arm-linux- WITHOUT_LARGEFILE=1 DESTDIR=${PRJROOT}/rootfs install
cd ${PRJROOT}/rootfs/usr/sbin
find -type f -exec arm-linux-strip {} \;
2)Partitioning the NAND flash:
in the file arch/arm/plat-s3c24xx/common-smdk.c
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "U-Boot",
.size = SZ_16K*16,
.offset = 0,
},
[1] = {
.name = "Kernel",
.offset = SZ_2M,
.size = SZ_2M,
},
[2] = {
.name = "NAND_256MB",
.offset = SZ_4M,
.size = SZ_4M*63 - SZ_2M,
},
};
…
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 12,
.twrph0 = 25,
.twrph1 = 12,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
3)create the filesystem image and copy to the board:
cd ${PRJROOT}
mkfs.jffs2 -e 128KiB -p -n -r rootfs/ -o rootfs-jffs2.img
#in the target machine:
#(optional)first there are some devices we must make,create a script named mkdev and add it to the rcS
#!/bin/sh
mknod /dev/ftla b 44 0
for a in `seq 1 15`; do
mknod /dev/ftla$a b 44 `expr 0 + $a`
done
flash_eraseall /dev/mtd2
nandwrite /dev/mtd2 rootfs-jffs2.img
4)enable to boot from jffs2 filesystem:
set bootargs to:
noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0 rootfstype=jffs2 rw
error like:ftl_cs: FTL header not found.
--it seems that the device doesn't support FTL, so in the kernel configure, disable “FTL support”.
8.System initialization
##NOTE:
When I boot the kernel on the NFS, I found the init can't not be execute. The problem lied in the linuxrc file. Since busybox just creat a symbolic link to /bin/busybox, it promote a error like “rcS: applet not found”.
A way to solve this is to set init=/bin/sh. But doing this, will make sh as the init program, and then the rcS script will not be run, and sh can be killed that will make the system crash.
**The solution is create a linuxrc file and add the below:
#!/bin/sh
exec /sbin/init
Script for init(using busybox init):
in rootfs directory--
etc/inittab
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
#ttyS0::respawn:/sbin/getty 115200 ttyS0 vt100
::restart:/sbin/init
::shutdown:/bin/umount -a -r
etc/init.d/rcS(must chmod to make executable)
#/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin
#Remount the root filesystem in read-write mode(require /etc/fstab)
mount -n -o remount,rw /
#for mdev
mount -t proc proc /proc
mount -t sysfs sysfs /sys
#echo /sbin/mdev > /proc/sys/kernel/hotplug
echo /sbin/medv > /sbin/hotplug #according to kernel configure.
etc/fstab
#/etc/fstab
#device directory type option
#
/dev/nfs / nfs defaults
etc/mdev.conf
#/etc/mdev.conf
# support module loading on hotplug
$MODALIAS=.* root:root 660 @modprobe "$MODALIAS"
# null may already exist; therefore ownership has to be changed with command
null root:root 666 @chmod 666 $MDEV
zero root:root 666
full root:root 666
random root:root 444
urandom root:root 444
hwrandom root:root 444
grsec root:root 660
kmem root:root 640
mem root:root 640
port root:root 640
# console may already exist; therefore ownership has to be changed with command
console root:tty 600 @chmod 600 $MDEV
ptmx root:tty 666
pty.* root:tty 660
# Typical devices
tty root:tty 666
tty[0-9]* root:tty 660
vcsa*[0-9]* root:tty 660
ttyS[0-9]* root:uucp 660
# block devices
ram([0-9]*) root:disk 660 >rd/%1
loop([0-9]+) root:disk 660 >loop/%1
sd[a-z].* root:disk 660 */lib/mdev/usbdisk_link
hd[a-z][0-9]* root:disk 660 */lib/mdev/ide_links
md[0-9]* root:disk 660
sr[0-9]* root:cdrom 660 @ln -sf $MDEV cdrom
fd[0-9]* root:floppy 660
# net devices
-net/.* root:root 600 @nameif
tun[0-9]* root:root 600 =net/
tap[0-9]* root:root 600 =net/
# alsa sound devices and audio stuff
pcm.* root:audio 660 =snd/
control.* root:audio 660 =snd/
midi.* root:audio 660 =snd/
seq root:audio 660 =snd/
timer root:audio 660 =snd/
adsp root:audio 660 >sound/
audio root:audio 660 >sound/
dsp root:audio 660 >sound/
mixer root:audio 660 >sound/
sequencer.* root:audio 660 >sound/
# Less typical devices
ttyLTM[0-9] root:dialout 660 @ln -sf $MDEV modem
ttySHSF[0-9] root:dialout 660 @ln -sf $MDEV modem
slamr root:dialout 660 @ln -sf $MDEV slamr0
slusb root:dialout 660 @ln -sf $MDEV slusb0
fuse root:root 666
# dri device
card[0-9] root:video 660 =dri/
# misc stuff
agpgart root:root 660 >misc/
psaux root:root 660 >misc/
rtc root:root 664 >misc/
# input stuff
event[0-9]+ root:root 640 =input/
mice root:root 640 =input/
mouse[0-9] root:root 640 =input/
ts[0-9] root:root 600 =input/
在csdn的blog无故被删了 T.T
回复删除现在把文章都补上了
走了好大一堆弯路,今天今天,看到你的blog了,马上改用buildroot试试!泪如雨下啊!
回复删除