打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Ubuntu下arm交叉编译环境的创建及基于s3c2410的linux2.6.22移植
Ubuntu下arm交叉编译环境的创建及基于s3c2410的linux2.6.22移植(一)
 
经历近2周的时间,查阅大量的参考资料和贴子,终于成功将linux2.6.22移植到ARM2410上。中间走了不少弯路,不过走弯路也是一种收获,因为可以碰到和解决许多问题,增长知识。因为linux版本问题以及开发平台的不同,网上的很多文章并不完全适合自己的板子,需要自己摸索和修改。写这点东西算是对前一阶段工作的总结,以免将来忘记。
移植大体的步骤主要有:
<!--[if !supportLists]-->(1)       <!--[endif]-->交叉编译环境的建立(我的主机系统是ubuntu7.04);
<!--[if !supportLists]-->(2)       <!--[endif]-->开发板(我用的是博创的2410)NAND flash 分区管理;
<!--[if !supportLists]-->(3)       <!--[endif]-->LCD、网卡驱动的移植;
<!--[if !supportLists]-->(4)       <!--[endif]-->linux内核配置和编译;
<!--[if !supportLists]-->(5)       <!--[endif]-->rootfs的制作;
<!--[if !supportLists]-->(6)       <!--[endif]-->完成linux的启动和文件系统的挂载。
下面我会按照步骤逐一介绍。
<!--[if !supportLists]-->一、   <!--[endif]-->交叉编译环境的建立
建立交叉编译环境就是在宿主机(也就是pc机)的系统上建立一个模拟ARM的工作环境,使得在这个环境下编译产生的程序能够顺利的在ARM上的系统内运行。主要工作包括binutils、gcc以及glibc的编译生成,还有一些环境变量的设置。
<!--[if !supportLists]-->(1)      <!--[endif]-->准备工作:
下载源代码包:    binutils-2.18.tar.bz2,gcc-4.2.1.tar.bz2,glibc-2.6.1.tar.bz2,glibc-ports-2.6.1.tar.gz,linux-2.6.22.tar.bz2
补丁包:              binutils-2.18-genscripts_multilib-1.patch
                            binutils-2.18-posix-1.patch
                            gcc-4.2.1-cross_search_paths-1.patch
                            gcc-4.2.1-posix-1.patch
                            gcc-4.2.1-specs-1.patch
                            glibc-2.6.1-cross_hacks-1.patch
                            glibc-2.6.1-hppa_nptl-1.patch
glibc-2.6.1-libgcc_eh-1.patch
glibc-2.6.1-RTLD_SINGLE_THREAD_P-1.patch
glibc-2.6.1-sysdep_cancel-1.patch
glibc-csu.patch
注:Binutils 是一组开发工具,包括连接器,汇编器和其他用于目标文件和档案的工具;
GCC是C编译器,用来将C代码编译成汇编代码;
Glibc就是gcc编译时需要的库了,glibc-ports是提供glibc对ARM的支持;
Linux-2.6.22.tar.bz2是内核源代码包。
需要注意的是gcc和glibc以及linux内核版本需要保持对应。如果用比较老的编译器去编译新的内核,或者用新的编译器编译老版本的内核,会出现一些莫名其妙的错误。另外补丁包也是必备的,否则编译过程中也会出错。刚开始我就深受其害。
<!--[if !supportLists]-->(2)      <!--[endif]-->工作目录的建立:
目录的结构可以参考《Building.Embedded.Linux.Systems》。推荐整个目录放到/usr/local下,这样所有的用户都有访问权限。我当初没经验,直接放到home下了,后来会有些用户权限的小麻烦。这里给出我的目录结构:
arm  host
其中host是我的普通登陆用户账号目录,arm就是工作目录了。为了方便,我平时用root登陆。
$root@host:/home/arm# mkdir build-tools kernel rootfs tmp tools
其中编译交叉工具时的主要工作都在build-tools目录下完成,kernel目录用来存放内核源代码,rootfs目录是用来建立启动根文件系统的(后面会详细介绍),tmp是临时文件存放目录,tools目录就是最终生成的编译器gcc和glibc存放的地方。
<!--[if !supportLists]-->(3)      <!--[endif]-->设置环境变量:
$root@host:/home/arm# export PRJROOT=/home/arm
$root@host:/home/arm# TARGET=arm-linux
$root@host:/home/arm# PREFIX=${PRJROOT}/tools
$root@host:/home/arm# TARGET_PREFIX=${PREFIX}/${TARGET}
$root@host:/home/arm# PATH=${PREFIX}/bin:${PATH}
其中TARGET定义了交叉工具的工作平台类型,PREFIX指定交叉工具的最终安装目录,PATH指定系统寻找交叉工具可执行文件所在的路径。
<!--[if !supportLists]-->(4)      <!--[endif]-->编译前的准备:
$root@host:/home/arm# cd ${PRJROOT}/build-tools
$root@host:/home/arm/build-tools# mkdir build-binutils build-boot-gcc build-glibc build-gcc build-glibc-headers patch
将源码包放到这个目录下
build-boot-gcc   build-glibc      build-binutils   build-gcc build-glibc-headers patch
binutils-2.18.tar.bz2   gcc-4.2.1.tar.bz2    glibc-2.6.1.tar.bz2  glibc-ports-2.6.1.tar.gz
将补丁放到patch目录下:
binutils-2.18-genscripts_multilib-1.patch      binutils-2.18-posix-1.patch
              gcc-4.2.1-cross_search_paths-1.patch        gcc-4.2.1-posix-1.patch
                  glibc-2.6.1-cross_hacks-1.patch
glibc-2.6.1-hppa_nptl-1.patch                            glibc-2.6.1-libgcc_eh-1.patch
glibc-2.6.1-RTLD_SINGLE_THREAD_P-1.patch
glibc-2.6.1-sysdep_cancel-1.patch                     glibc-csu.patch
将内核源码包放到${PRJROOT}/kernel目录下
linux-2.6.22.tar.bz2
<!--[if !supportLists]-->(5)      <!--[endif]-->开始编译
编译的过程主要有6个步骤;
<!--[if !supportLists]-->a.       <!--[endif]-->内核头文件的生成
<!--[if !supportLists]-->b.       <!--[endif]-->Binary utilties的生成
<!--[if !supportLists]-->c.       <!--[endif]-->Glibc头文件的生成
<!--[if !supportLists]-->d.       <!--[endif]-->第一阶段gcc的生成
<!--[if !supportLists]-->e.       <!--[endif]-->glibc库文件的生成
<!--[if !supportLists]-->f.        <!--[endif]-->完整编译工具的生成
  注:生成第一阶段gcc主要是用来生成glibc库文件。
<!--[if !supportLists]-->1、 <!--[endif]-->生成内核头文件
$root@host:/home/arm/kernel# tar xvjf linux-2.6.22.tar.bz2
make ARCH=arm CROSS_COMPILE=arm-linux- menuconfig
其中menuconfig指定了配置界面,可用的还有config(全字符界面) xconfig(xwindow下的图形界面)。Ubuntu需要安装tk8.4以支持xconfig。另外需要将mawk卸载,安装gawk。(mawk有bug)
linux2.6的内核提供了对s3c2410的支持。在system中选上s3c2410系列就可以了。配置完毕退出保存。
version.h autoconf.h
这2个文件在后面的编译中会用到。如果没有,退到内目录下make version.h就可以了。
下面建立链接:
$root@host:/home/arm/kernel/linux-2.6.22/include# ln -s asm/arch-s3c2410 asm/arch
将内核头文件拷贝到最终安装目录下:
$root@host:/home/arm/kernel/linux-2.6.22/include# mkdir –p ${TARGET_PREFIX}/include
cp –r asm- ${TARGET_PREFIX}/include
$root@host:/home/arm/kernel/linux-2.6.22/include# cp –r linux ${TARGET_PREFIX}/include
$root@host:/home/arm/kernel/linux-2.6.22/include# cp –d asm ${TARGET_PREFIX}/include

至此内核头文件建立完毕。
<!--[if !supportLists]-->2、 <!--[endif]-->建立Binary utilities:
binutils是一些二进制工具的集合,其中常用的是as ,ar和ld。
$root@host:/home/arm/kernel/include# cd ${PRJROOT}/build-tools
$root@host:/home/arm/build-tools# tar xvjf binutils-2.18.tar.bz2
patch –Np1 –i /home/arm/build-tools/patch/binutils-2.18*
../binutils-2.18/configure --target=${TARGET} –prefix=${PREFIX}
${PREFIX}/bin下应该生成一些以arm-linux开头的文件
<!--[if !supportLists]-->3、 <!--[endif]-->生成glibc头文件:
$root@host:/home/arm/build-tools/# tar xvjf glibc-2.6.1.tar.bz2
tar xvzf glibc-ports-2.6.1.tar.gz --directory ./glibc-2.6.1/
$root@host:/home/arm/build-tools/glibc-2.6.1# mv glibc-ports-2.6.1 ports –v
打上补丁:
patch –Np1 –i /home/arm/build-tools/patch/glibc-2.6.1-*patch
$root@host:/home/arm/build-tools/# cd build-glibc-headers
这里需要添加对NPTL线程库的支持:
echo “libc_cv_forced_unwind=yes”>>config.cache
echo “libc_cv_c_cleanup=yes”>>config.cache
echo “libc_cv_arm_tls=yes”>>config.cache
注:如果编译中出现”cannot compute long double size”,添加:
echo “ac_cv_sizeof_long_double=12”>>config.cache
../glibc-2.6.1/configure --host=${TARGET} --prefix=”/usr” --enable-add-ons
--with-headers=${TARGET_PREFIX}/include --cache-file=config.cache
make cross-compiling=yes install_root=${TARGET_PREFIX} prefix=””
install-headers
mkdir –p ${TARGET_PREFIX}/include/gnu
touch ${TARGET_PREFIX}/include/gnu/stubs.h
注:如果编译过程中出现找不到头文件的错误,可以根据错误提示的文件名用touch命令在相应目录下建立一个空文件,一般就可以编译通过了。
<!--[if !supportLists]-->4、 <!--[endif]-->生成第一阶段gcc:
$root@host:/home/arm/build-tools/# tar xvjf gcc-4.2.1.tar.bz2
打补丁:
patch –Np1 –i /home/arm/build-tools/patch/gcc-4.2.1-*
../gcc-4.2.1/configure --target=${TARGET} --prefix=${PREFIX}  --with-headers=${TARGET_PREFIX}/include
--with-newlib --enable-languages=c --disable-threads --disable-shared
在${PREFIX}/bin下会生成 arm-linux-开头的文件:
<!--[if !supportLists]-->5、 <!--[endif]-->生成glibc库文件:
$root@host:/home/arm/build-tools/build-glibc# CC=arm-linux-gcc ../glibc-2.6.1/configure --host=$TARGET --prefix=”/usr”
      --enable-add-ons --with-headers=${TARGET_PREFIX}/include
--cache-file=config.cache
这里的config.cache与前面编译glibc头文件时的config.cache完全相同。
make install_root=${TARGET_PREFIX} prefix=”” install
对libc.so作出修改:
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( /lib/libc.so.6 /lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux.so.2 ) )
将GROUP这一行的内容改为:
GROUP ( libc.so.6 libc_nonshared.a  AS_NEEDED ( ld-linux.so.2 ) )
              $root@host:/home/arm/tools/arm-linux/lib#  cat libpthread.so
              /* GNU ld script
            Use the shared library, but some functions are only in
            the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-littlearm)
GROUP ( /lib/libpthread.so.0 /lib/libpthread_nonshared.a )
              将GROUP这一行的内容改为:
              GROUP (libpthread.so.0  libpthread_nonshared.a )
<!--[if !supportLists]-->6、 <!--[endif]-->生成完整的编译工具:
$root@host:/home/arm/tools/arm-linux/lib# cd ${PRJROOT}/build-tools/build-gcc
../gcc-4.2.1/configure --target=$TARGET --prefix=${PREFIX}  --enable-shared
--enable-languages=c,c++ --with-threads=posix
              $root@host:/home/arm/build-tools/build-glibc# make all
              $root@host:/home/arm/build-tools/build-glibc# make install
       (待续....)
 
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/templarzq/archive/2007/10/12/1821594.aspx
 
Ubuntu下arm交叉编译环境的创建及基于s3c2410的linux2.6.22移植(二)
 
<!--[if !supportEmptyParas]--> (续)<!--[endif]-->
<!--[if !supportLists]-->二、 <!--[endif]-->NAND flash 分区管理
这块2410板自带了vivi,启动之后可以进到vivi的提示符下:
vivi>
查看分区情况:
vivi> part show
mtdpart info. (6 partitions)
<!--[if !supportEmptyParas]--> <!--[endif]-->
name                            offset                           size                       flag 
vivi                              :0x00000000                 0x00020000           0            128k
param                       :0x00020000                 0x00010000           0            64k
kernel                        :0x00030000                 0x00200000           0            2M
root                            :0x00230000                 0x00300000           4            3M
yaffs                           :0x00530000                 0x03a00000           8            58M
使用part命令可以添加、删除各个mtd分区。
另外还有一种分区格式:BON,具体用法参照bon命令帮助即可。2.6内核对mtd分区格式支持的很好,所以这里采用了mtd分区方式。
       其中vivi是bootloader区,param是存放启动参数设置区,kernel是内核镜像文件区,root是启动文件系统区,yaffs是文件系统区,可以视情况修改这些区域的大小。
<!--[if !supportLists]-->三、  <!--[endif]-->网卡和LCD驱动的移植
<!--[if !supportLists]-->1.  <!--[endif]-->网卡驱动移植:
这块板使用的是DM9000的网卡芯片,驱动的源代码在内核源代码的目录中可以找到:
$root@host:/home/arm/#  cd kernel/linux-2.6.22
dm9000.c              dm9000.h
修改dm9000.c:
      找到函数:
static int dm9000_probe(struct platform_device *pdev)
{
       ……….
       int ret=0;
       int iosize;
       int i;
       u32 idval
//添加下面数组,前6个数作为网卡的mac地址,注意不能和现有的网卡冲突
       unsigned char ne_defethadder[]={0x08,0x08,0x08,0x08,0x12,0x27,0}
       ………………………….
       ………………………….
       /* Set Node Address */
       for (i = 0; i < 6; i++)
              ndev->dev_addr[i] = db->srom[i];
<!--[if !supportEmptyParas]--> <!--[endif]-->
       if (!is_valid_ether_addr(ndev->dev_addr)) {
              /* try reading from mac */
<!--[if !supportEmptyParas]--> <!--[endif]-->
              for (i = 0; i < 6; i++)
              //修改mac地址
              //     ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
                     ndev->dev_addr[i]=ne_defethaddr[i];
              ………………………
              ……………………….
       }
退出保存。
修改smdk2410.c:
vi mach-smdk2410.c
在mach-smdk2410.c中添加如下内容:
…………
#include <asm/plat-s3c24xx/common-smdk.h>
//添加:
#include <linux/dm9000.h>
…………
………….
#define UCON S3C2410_UCON_DEFAULT
#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
//添加:
<!--[if !supportEmptyParas]--> <!--[endif]-->
static struct resource s3c_d9k_resource[]=
{
       [0]={
              .start      =0x10000000,
              .end =0x10000000,
              .flags=IORESOURCE_MEM
       },
       [1]={
              .start      =0x10000000+0x2,
              .end =0x10000000+0x2,      
              .flags=IORESOURCE_MEM
       },
       [2]={
              .start      =IRQ_EINT2,             
              .end =IRQ_EINT2,
              .flags     =IORESOURCE_IRQ
       }
};
static struct dm9000_plat_data s3c_device_d9k_platdata = {
        .flags= DM9000_PLATF_16BITONLY
};
<!--[if !supportEmptyParas]--> <!--[endif]-->
struct platform_device s3c_device_d9k = {
        .name= "dm9000",
        .id= 0,
        .num_resources= ARRAY_SIZE(s3c_d9k_resource),
        .resource= s3c_d9k_resource,
        .dev= {
                .platform_data = &s3c_device_d9k_platdata,
        }
};
………………….
………………….
static struct platform_device *smdk2410_devices[] __initdata = {
       &s3c_device_usb,
       //启动lcd
       &s3c_device_lcd,
       &s3c_device_wdt,
       &s3c_device_i2c,
       &s3c_device_iis,
       //添加
       &s3c_device_d9k
       //&s3c_device_ts,
};
需要注意的是起始地址和中断号的选择。这块板上DM9000芯片的INT引脚接的是EINT2,CMD引脚接的是A1,CS引脚接的是nGCS2,所以DM9000的index端口地址是0x10000000,data端口地址是0x10000000+0x00000002,据此设置结构resource s3c_d9k_resource中的参数。最后在内核编译时加上对DM9000驱动的支持就可以了,具体见内核配置和编译。
<!--[if !supportLists]-->2.  <!--[endif]-->LCD驱动移植:
继续在mach-smdk2410.c中添加如下内容:
………….
#include <asm/arch/fb.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-lcd.h>
………….
………….
static struct s3c2410fb_mach_info smdk2410_lcdcfg __initdata={
       .type=S3C2410_LCDCON1_TFT,
       .fixed_syncs= 0,
       .regs={
              .lcdcon1=       S3C2410_LCDCON1_TFT16BPP|
                            S3C2410_LCDCON1_TFT |
                            S3C2410_LCDCON1_CLKVAL(0X01),     /*HCLK/4*/
              .lcdcon2=       S3C2410_LCDCON2_VBPD(18)|       /*19*/
                            S3C2410_LCDCON2_LINEVAL(479)|
                            S3C2410_LCDCON2_VFPD(10)|       /*11*/
                            S3C2410_LCDCON2_VSPW(14),      /*15*/
              .lcdcon3=       S3C2410_LCDCON3_HBPD(43)|
                            S3C2410_LCDCON3_HOZVAL(639)|       /*640*/
                            S3C2410_LCDCON3_HFPD(115),     /*116*/
              .lcdcon4=       S3C2410_LCDCON4_MVAL(0)  |
                            S3C2410_LCDCON4_HSPW(95),      /*96*/
              .lcdcon5=       S3C2410_LCDCON5_FRM565   |
                            S3C2410_LCDCON5_INVVLINE|
                            S3C2410_LCDCON5_INVVFRAME|
                            S3C2410_LCDCON5_PWREN|
                            S3C2410_LCDCON5_HWSWP,
       },
       .lpcsel=   ((0XCE6)&~7)|1<<4,//0x0,
       .gpccon= 0xAA8002A8,//0xaaaaaaaa,
       .gpccon_mask=     0xFFC003FC,//0xffffffff,
       .gpcup=         0xF81E,//0xffffffff,
       .gpcup_mask=      0xF81E,//0xffffffff,
       .gpdcon= 0xAA80AAA0,//0xaaaaaaaa,
       .gpdcon_mask=    0xFFC0FFF0,//0x0,
       .gpcup=         0xF8FC,//0xffffffff,
       .gpcup_mask=      0xF8FC,//0xffffffff,
      
       .width=          640,//240,
       .height= 480,//320,
       .xres=            {640,640,640},//{240,240,240}, .min .max .defval
       .yres=            {480,480,480},//{320,320,320},
       .bpp=             {16,16,16},   //{16,16,16}, 
};
……………
……………
static void __init smdk2410_init(void)
{
       s3c24xx_fb_set_platdata(&smdk2410_lcdcfg);
       platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
       smdk_machine_init();
}
………………..
注:注释掉drivers\char\vt.c的blank_screen_t(unsigned long dummy)的函数内容,否则lcd会在10分钟左右关掉显示。“
最后在内核编译时需要选中对LCD的支持,具体见内核配置和编译。
  (待续.....)
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/templarzq/archive/2007/11/07/1871783.aspx
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
如何为嵌入式开发建立交叉编译环境
建立针对arm
ARM cross Linux-PAM-0.75
Cross Toolchain-交叉编译工具链
交叉编译模拟环境sbox2的使用
建立ARM交叉编译环境 (arm
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服