构建 arm-linux 仿真运行环境 (skyeye + u-boot + arm-linux + NFS)

来源:互联网 发布:arcgis js 点击事件 编辑:程序博客网 时间:2024/05/23 00:07

建议编译u-boot的时候arm-linux-gcc2.95.3 编译2.6内核时用3.4.1

. 安装 Skyeye

我们选定 skyeye 1.2.3 这个版本, 为了能让它上面运行的 arm-linx 能挂接 NFS,
们需要修改 device/net/dev_net_cs8900a.c (修改后的文件在附件里), 再编译 skyeye
操作如下, 先解压源码包:
  #tar xzf skyeye-1.2.3_Rel.tar.gz
  #cd skyeye-1.2.3

请用附件里的 dev_net_cs8900a.c 替换 device/net/dev_net_cs8900a.c 后执行编译:
  #make

编译完后生成的 skyeye binary 下,将其拷贝至 /usr/local/bin/ :
  #cp binary/skyeye /usr/local/bin

. 编译u-boot

2.1 配置板子SDROMFLASH参数为板子实际大小,找到u-boot-1.1.6/include/configs/smdk2410.h,修改其中的PHYS_SDRAM_1_SIZE为板子实际SDRAM大小64MCFG_MAX_FLASH_SECT128,修改PHYS_FLASH_SIZE为板子实际FLASH大小16M。并保存。

如下所示

*-----------------------------------------------------------------------
* Physical Memory Map
*/
#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of DRAM */
#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */
#define PHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */

#define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */

#define CFG_FLASH_BASE PHYS_FLASH_1

/*-----------------------------------------------------------------------
* FLASH and environment organization
*/

#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
#if 0
#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
#endif

#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#ifdef CONFIG_AMD_LV800
#define PHYS_FLASH_SIZE 0x04000000 /* 64MB */
#define CFG_MAX_FLASH_SECT (128) /* max number of sectors on one chip */
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x020000) /* addr of environment */
#endif
#ifdef CONFIG_AMD_LV400
#define PHYS_FLASH_SIZE 0x04000000 /* 64MB */
#define CFG_MAX_FLASH_SECT (128) /* max number of sectors on one chip */
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x020000) /* addr of environment */
#endif

2.2修改uboot目录下的Makefile,将

ifeq ($(ARCH),arm)

CROSS_COMPILE = arm-Linux-

endif

修改成

ifeq ($(ARCH),arm)

CROSS_COMPILE = /opt/host/armv4l/bin/armv4l-unknown-linux-

endif

2.3修改processor.h:

union debug_insn

{

u32 arm;

u16 thumb;

}

修改成:

union debug_insn

{

u32 arm_mode;

u16 thumb_mode;

}
2.4
配置并编译:

make clean

make smdk2410_config

make

经过以上命令则生成两个文件:u-bootu-boot.bin

. 创建一个目录用于存放相关文件。

3.1 如创建TestArm目录:mkdir TestArm

3.2 将前面生成的u-boot文件放在TestArm目录下。

3.3 新建文件命名为skyeye.conf并放在TestArm目录下,文件内容如下

cpu: arm920t

mach: s3c2410x

mem_bank:map=I,type=RW,addr=0x48000000,size=0x20000000

#注意此处的addr一定要与上面smdk2410.h配置的SDRAMFLASH的大小与基地址一定要相同,否则启动不起来,卡在那里。

#下面这一句和FLASH一样

mem_bank:map=M,type=RW,addr=0x00000000,size=0x04000000,file=u-boot.bin,boot=yes

#下面这一句和SDRAM一样

mem_bank:map=M,type=RW,addr=0x30000000,size=0x04000000

完整的skyeye.conf如下:

#skyeye config file sample

cpu: arm920t

mach: s3c2410x

mem_bank: map=M, type=RW, addr=0x00000000, size=0x01000000, file=u-boot.bin, boot=yes

mem_bank: map=M, type=RW, addr=0x30000000, size=0x04000000

mem_bank: map=M, type=RW, addr=0xc0000000, size=0x01000000, file=vmlinux

mem_bank: map=M, type=RW, addr=0xc1000000, size=0x00600000, file=initrd.img

mem_bank: map=M, type=RW, addr=0xc1600000, size=0x00a00000

mem_bank: map=I, type=RW, addr=0x48000000, size=0x20000000

mem_bank: map=I, type=RW, addr=0x19000300, size=0x00000020

net: type=cs8900a, base=0x19000300, size=0x20,int=9, mac=0:4:3:2:1:f, ethmod=tuntap, hostip=10.0.0.1

#lcd:type=s3c2410x,mod=gtk

dbct:state=on

. 运行命令./skyeye如下所示

[Filter@zhoub TestArm]$ skyeye –e u-boot

**************************** WARNING *****************************
If you want to run ELF image, you should use -e option to indicate
your elf-format image filename. Or you only want to run binary image,
you need to set the filename of the image and its entry in skyeye.conf.
***********************************************************************

big_endian is false.
arch: arm
cpu info: armv4, arm920t, 41009200, ff00fff0, 2
mach info: name s3c2410x, mach_init addr 0x8067f58
flash: dump nand.dump
uart_mod:0, desc_in:, desc_out:, converter:
SKYEYE: use arm920t mmu ops
Loaded RAM u-boot
ERROR: s3c2410x_io_write_word(0x4c000000) = 0x00ffffff
ERROR: s3c2410x_io_write_word(0x4c000008) = 0x00048032


U-Boot 1.1.6 (Jun 10 2008 - 08:40:29)

DRAM: 64 MB
Flash: 64 MB
*** Warning - bad CRC, using default environment

In: serial
Out: serial
Err: serial
SMDK2410#

表明已经运行起来了,上面显示有一个警靠我两个ERROR,不知为何,正在查原因。启动ArmLinux

SMDK2410 # go c0000000

编译内核
 
我们选定 linux-2.6.14.tar.bz2 这个版本, 交叉编译器用 arm-linux-gcc 3.4.1 (
2.6
内核用 3.4 以下的版本编译经常会出现问题)。操作步骤如下:

1.假定内核源码包在 /root , 首先解压源码:
  #cd /root
  #tar xjf linux-2.6.14.tar.bz2

2.进入内核目录:
  #cd linux-2.6.14

  修改此目录下的 Makefile,
  ARCH          ?= $(SUBARCH)
  CROSS_COMPILE ?=
 
改为
  ARCH          ?= arm
  CROSS_COMPILE ?= /usr/local/arm/3.4.1/bin/arm-linux-

3.生成默认的内核配置文件(for s3c2410):
  #make smdk2410_defconfig

4.为内核添加 cs8900(见附件) 网卡驱动,以支持 NFS 挂接:
  (1)
复制 cs8900 驱动到 drivers/net/arm 目录
     #cp cs8900.c drivers/net/arm
     #cp cs8900.h drivers/net/arm

  (2)修改 drivers/net/arm 目录下的 Kconfig 文件, 在最后添加:
     config ARM_CS8900
        tristate "CS8900 support"
        depends on NET_ETHERNET && ARM && ARCH_SMDK2410
        help
          Support for CS8900A chipset based Ethernet cards. If you have a network
          (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available
          from as well as .To compile this driver as a module, choose M here and read.
          The module will be called cs8900.o.

     :在运行 make menuconfig 命令时就会出现: [ ] CS8900 support 这一选项

  (3)修改 drivers/net/arm 目录下的Makefile文件,在最后添加如下内容:
     obj-$(CONFIG_ARM_CS8900) += cs8900.o

     注:2.6 版本内核的 Makefile 也与 2.4 的有所不同, 添加以上语句, 就会使内核在
    
编译的时候根据配置将cs8900A的驱动程序以模块或静态的方式编译到内核当中。

  (4)修改 arch/arm/mach-s3c2410/mach-smdk2410.c
    
在此文件中找到 smdk2410_iodesc[] 结构数组,添加如下如下内容:

     {vSMDK2410_ETH_IO,pSMDK2410_ETH_IO, SZ_1M, MT_DEVICE}

     修改之后变成:

     static struct map_desc smdk2410_iodesc[] __initdata = {
     /* nothing here yet */
     /* Map the ethernet controller CS8900A */
     {vSMDK2410_ETH_IO,pSMDK2410_ETH_IO, SZ_1M, MT_DEVICE}
     };

     并且添加一个头文件引用:
     #include <asm-arm/arch-s3c2410/smdk2410.h>

  (5) include/asm-arm/arch-s3c2410 目录下创建文件 smdk2410.h
     #ifndef _INCLUDE_SMDK2410_H_
     #define _INCLUDE_SMDK2410_H_

     #include <linux/config.h>
     #define pSMDK2410_ETH_IO 0x19000000
     #define vSMDK2410_ETH_IO 0xE0000000
     #define SMDK2410_ETH_IRQ IRQ_EINT9

     #endif

5.参照 http://skyeye.wiki.sourceforge.net/Linux 修改内核文件
 
修改 include/asm-arm/arch-s3c2410/map.h
  #define S3C2410_CS6 (0x30000000UL)
  to
  #define S3C2410_CS6 (0xC0000000UL)

  修改 include/asm-arm/arch-s3c2410/memory.h
  #define PHYS_OFFSET (0x30000000UL)
  to
  #define PHYS_OFFSET (0xC0000000UL)

6.添加Nor flash驱动

6.1、分区信息
   HHARM2410-STUDY
开发板使用16bit 8M NOR FLASH,分区信息如下:
   0x00000000-0x00040000 : "bootloader"
   0x00040000-0x00140000 : "kernel"
   0x00140000-0x00540000 : "ramdisk"
   0x00540000-0x00800000 : " jffs2"

6.2、添加配置项
   1
、修改 drivers/mtd/maps/Kconfig文件,添加如下内容:
config MTD_S3C2410
tristate "CFI Flash device mapped on S3C2410"
depends on ARM && MTD_CFI
help
 This enables access to the CFI Flash on the Cogent S3C2410 board.
 If you have such a board, say &apos;Y&apos; here.
   2
、修改 drivers/mtd/maps/Makefile文件,添加如下内容:
   obj-$(CONFIG_MTD_S3C2410)+= s3c2410.o
   3
、复制驱动文件s3c2410.cdrivers/mtd/maps目录下

 

7.裁剪/定制内核
  (1)#make menuconfig
  (2)
设置内核启动参数
     Boot options ---> Default kernel command string:
     mem=32M console=ttySAC0 root=/dev/ram initrd=0xc1000000,0x00600000 ramdisk_size=8192 rw
  (3)
设置 CS8900 的支持
     Device Drivers --->
     Network device support --->
     Ethernet (10 or 100Mbit)  ---> []   CS8900 support
    
选中 [*]   CS8900 support
  (4)
设置 initrd 的支持
     Device Drivers ---> Block devices  ---> [ ] RAM disk support
    
下面三项必须设置:
     1.
确保 RAM disk support 被选中
     2.
相应的将默认的 (4096) Default RAM disk size (kbytes) 改成 8192;
     3.Initial RAM disk (initrd) support
一定要选中, 切记!
  (5)设置 NFS 的支持
     File systems  ---> Network File Systems  --->
    
至少确保下面两项被选中:
     [*] NFS file system support
     [*]   Provide NFSv3 client support
  (6)
设置 ROM file system 的支持
     File systems  ---> [*] ROM file system support
    
确保 [*] ROM file system support 被选中
  (7)
设置 ext2 的支持
     File systems  ---> [*] Second extended fs support
    
确保 [*] Second extended fs support 被选中
 
(8) Memory Technology Devices(MTD)-->
       <*>Memory Technology Device (MTD) support
       [*]MTD partitioning support
       <*>Direct char device access to MTD devices
       <*>Caching block device access to MTD devices
       RAM/ROM/Flash chip drivers-->
           <*>Detect flash chips by Common Flash Interface (CFI) probe
           <*>Support for Inter/Sharp flash chips
       Mapping drivers for chip access-->
           <*>CFI flash device mapped on S3C2410
   Miscellaneous filesystems-->
       <*>Journalling Flash File System v2 (JFFS2) support

7.编译
  #ln –s include/asm-arm include/asm

#make
 
编译完成后会有个 vmlinux 在当前目录下, 这就是我们要的 arm-linux 内核了

 

六、测试

6.1 将编译好的内核文件vmlinux拷贝到TestArm目录

6.2 拷贝一个ramdisk根文件系统到TestArm目录

6.3 skyeye启动u-boot,然后用u-boot引导内核文件

# skyeye –e u-boot

smdk2410# go c0000000

启动内核时候如果出现些错误    Error: unrecognized/unsupported machine ID (r1 = 0x33f60264).Linux内核启动时出现:bad machine ID,原因大致是u-boot传递给内核的machine ID错误,可以手动在内核源代码中添加machine ID.

解决方法:
u-boot命令行中输入bdinfo
查看板卡信息,我的输出如下:
[ ~ljh@GDLC ]# bdinfo
arch_number =
0x000000C1
env_t       = 0x00000000
boot_params = 0x30000100
DRAM bank   = 0x00000000
-> start    = 0x30000000
-> size     = 0x04000000
ethaddr     = 08:00:3E:26:0A:5B
ip_addr     = 10.1.8.245
baudrate    = 115200 bps


修改内核的arch/arm/kernel/head.S,直接将s3c2410的参数赋给内核
# cd linux-2.6.14.1
# vi arch/arm/kernel/head.S +104
----------------------------------------------    
102     __INIT
103     .type       stext, %function
104 ENTRY(stext)
   /********* add here *********/
   mov    r0, #0
   mov    r1, #0xc1
   ldr    r2, =0x30000100
   /********* end add *********/

105     msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode
106     @ and irqs disabled


解决方法二
========================================================
修改u-boot,填写ID
# vi common/cmd_boot.c
----------------------------------------------
31 #if defined(CONFIG_I386)
32 DECLARE_GLOBAL_DATA_PTR;
33 #endif
====>
31 //#if defined(CONFIG_I386)
32 DECLARE_GLOBAL_DATA_PTR;
33 //#endif
   ...
60 #if !defined(CONFIG_NIOS)
        /************** add here ******************/
        if(argc==2)
            rc = ((ulong (*)(int, char *[]))addr) (0, gd->bd->bi_arch_number);
        else

        /*************** add end *****************/
61         rc = ((ulong (*)(int, char *[]))addr) (--argc, &argv[1]);
62 #else
63     /*
64      * Nios function pointers are address >> 1
65      */
66     rc = ((ulong (*)(int, char *[]))(addr>>1)) (--argc, &argv[1]);
67 #endif

 

原创粉丝点击