热门关键字:  ubuntu  分区  函数  linux系统进程  Fedora

移植uClinux-2.6.9到S3C44B0的过程

来源: 作者: 时间:2007-12-21 Tag: 点击:
接触linux有二个多月了,记得当时公司丢来一个s3c44b0的开发板,叫做一个网络方面的东西。当时第一个想法就是用uc/os-ii来做,可是uc/os-ii没有tcp/ip协议,要移植其他协议,我想不一定很稳定的工作,所以就想到用uclinux了,因为它有稳定的网络协议。当时心里真没有底,毕竟没有接触过uclinux。先到网上搜寻一下uclinux方面的文章,还是有很多相关文章。大概阅览一下,知道uclinux是个怎么回事。回头看看开发板的资料,狂喜,因为光盘上还有uclinux的源代码,可是编译都是错的,郁闷,只好弃之。还有开发板的armboot又没有源代码,以后做产品都不能引导系统。所以决定从头做起。以下操作和方法有些来自网上的做法。
一、u-boot的移植
  先到u-boot的官方网站http://sourceforge.net/projects/u-boot去下载源代码。我用的是u-boot-1.1.4版本。在u-bootB2板就是S3C44B0CPU,所以就对B2板进行修改,不必重新做起。其实修改的地方也不多。主要修改处:
1、  修改u-boot/ include/configs/B2.h文件,B2.h文件是u-boot的配置文件,主要修改
1#define CONFIG_S3C44B0_CLOCK_SPEED      60 (改成自己的主频)
2、除去
/*#define CONFIG_DRIVER_LAN91C96   */
/*#define CONFIG_LAN91C96_BASE          0x04000300  *//* base address
的定义,增加
#define CONFIG_DRIVER_RTL8019
#define RTL8019_BASE            0x06000000   /* net base address */
定义,因为我是用RTL8019的网络芯片,地址为0x06000000
3#define CONFIG_BAUDRATE         115200 (改成自己的波特率)
4#define CONFIG_BOOTARGS "root=/dev/ram0 console=ttyS0,115200" (启动参数,其他在最面的系统运行中,没有这些参数也没问题的)
5、增加
#define CFG_ENV_IS_IN_FLASH     1       /* use EEPROM for environment vars */
#undef CFG_ENV_IS_IN_NOWHERE
#define CFG_ENV_ADDR            (PHYS_FLASH_1+0x20000)
#define CFG_ENV_SECT_SIZE       0x10000
把环境变量放在flash,注译掉I2C EEPROM (STM24C02W6) for environment部分。
以上是B2.h重点要修改的地方,还有一些要改的,根据情况修改。
2、  修改u-boot/cpu/s3c44b0/start.S文件。start.Scpu运行的第一个文件。
1、  注掉
add     pc, pc, #0x0c000000
        add     pc, pc, #0x0c000000
        add     pc, pc, #0x0c000000
        add     pc, pc, #0x0c000000
        add     pc, pc, #0x0c000000
        add     pc, pc, #0x0c000000
        add     pc, pc, #0x0c000000
增加  
 
ldr pc,Undefined_Addr
        ldr pc,SWI_Addr
        ldr pc,Prefetch_Addr
        ldr pc,Abort_Addr
        ldr pc,RESERVE_Addr
        ldr pc,IRQ_Addr
        ldr pc,FIQ_Addr
同时也要在start.S中定义这些符号,如:
Undefined_Addr:
.word 0x0c000004
SWI_Addr:
.word 0x0c000008
Prefetch_Addr:
.word 0x0c00000c
Abort_Addr:
.word 0x0c000010
RESERVE_Addr:
.word 0x0c000014
IRQ_Addr:
.word 0x0c000018
FIQ_Addr:
.word 0x0c00001c
如果不这样做,运行时会出现问题。
2、修改CPU_init_critical registers部分。看其体情况修改初始化寄存器。
经过这步后u-boot可以运行了。但是无法识出我的SST39VF1601,这个折腾我好几天呢。所以要对flash方面的修改。主要是修改u-boot/board/dave/common/flash.c文件,在345行中增加
case (CFG_FLASH_WORD_SIZE)SST_ID_xF1601:
    346                 info->flash_id += FLASH_SST1601;
    347                 info->sector_count = 512;
    348                 info->size = 0x00200000;
349                 break;
因为在value = addr2[CFG_FLASH_READ1];读取flashIDu-boot没有识出我的flash就是没有对39VF1601的定义。在154行也增加
154         case FLASH_SST1601:     printf ("SST39VF1601 (16Mbit,uniform sec        tor size)\n");
这样就基本完成u-boot的移植工作了,最后
cd u-boot
vi Makefile             //修改编译环境,把arm-linux-改为arm-elf-
make B2_config
make
OK了。如果是在FC6中编译的话,还要注意两个编译上的问题。
第一,出现:
isystem /usr/local/arm/bin/../lib/gcc-lib/arm-linux/3.2/include -pipe  -DCONFIG_ARM -D__ARM__ -march=armv4 -mtune=arm7tdmi -msoft-float -mabi=apcs-gnu -Uarm -Wall -Wstrict-prototypes -c -o hello_world.o hello_world.c
cc1: invalid option `abi=apcs-gnu'
修改:
出错的文件是/cpu/s3c44b0/下的config.mk:
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
改成:
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,$(call cc-option,-mabi=apcs-gnu),)
 
第二,出现:
make[1]: *** No rule to make target `hello_world.srec', needed by `all'.  Stop.
make[1]: Leaving directory `/home/mort/src/targa/u-boot/u-boot-TOT/examples'
make: *** [examples] Error 2
 
解决方法:
打开 vi examples/Makefile
  
    119 $(LIB): .depend $(LIBOBJS)
    120         $(AR) crv $@ $(LIBOBJS)
    121
    122 %:      %.o $(LIB)
    123         $(LD) -g $(EX_LDFLAGS) -Ttext $(LOAD_ADDR) \
    124                 -o $@ -e $(<:.o=) $< $(LIB) \
    125                 -L$(gcclibdir) -lgcc
    126 %.srec: %
    127         $(OBJCOPY) -O srec $< $@ 2>/dev/null
    128
    129 %.bin:  %
    130         $(OBJCOPY) -O binary $< $@ 2>/dev/null
   
 126行和129行改为:
     %.srec: %.o
     %.bin: %.o
 
以上是u-boot的移植注意事项。
 
 
二、uclinux的移植
      uclinux的移植真是叫“苦”啊。一开始我并不知道移植uclinux要做什么工作,先到网搜搜吧,看看人家怎么做先。文章还是不少,移植2.6的比2.4的文章还多。发现2.4的补丁很不好找,看了http://blog.iyi.cn/hily/ BLOG上的“uclinux-2.6.14移植到s3c44b0”的文章,这篇文章写得很详细,跟他一步一步做,编译了二次后,终于编译成功。这样才对uclinux有个大致的了解。将得出的images文件:
[root@localhost images]# ll
total 6412
-rw-r--r--    1 root     root      3271472 Feb  8 09:48 image.bin
-rwxr-xr-x    1 root     root        61852 Feb  8 09:48 linux.data
-rwxr-xr-x    1 root     root      2231700 Feb  8 09:48 linux.text
-rw-r--r--    1 root     root       977920 Feb  8 09:47 romfs.img
gzip -9 image.bin命令把image.bin文件压缩,再用u-boot的工具mkimageimage.bin镜像转换成u-boot可引导的格式uImage,命令:
[root@localhost tools]#./mkimage –A arm –O linux –T kernel –C none –a 0x0c008000 –e 0x0c008000 –n “linux-2.6.9” –d /home/uclinux/镜像所在的目录/image.bin uImage
这样就得到u-boot能引导的镜像格式了。烧到flash40000地址上,试运行,结果是:
## Booting image at 00040000 ...
Image Name: uCLinux-2.6.14
Created: 2006-12-25 7:07:23 UTC
Image Type: ARM Linux Kernel Image (gzip compressed)
Data Size: 711789 Bytes = 695.1 kB
Load Address: 0c008000
Entry Point: 0c008000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK

Starting kernel ...
(完了,就死在这里)
这些都是mkimage工具加到内核的信息,没有真正调到内核。在uClinux-dist/Makefile41行加入LINUXTARGET =bzImage uClinux-dist/linux-2.6.x/arch/armnommn/boot目录下得出zImage已压缩的镜像,再试运行,结果是:
U-Boot code: 0C700000 -> 0C719EEC BSS: -> 0C71E990
RAM Configuration:
Bank #0: 0c000000 8 MB
Flash: 2 MB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0
## Booting image at 00040000 ...
Image Name: uClinux-2.6.14
Created: 2007-01-05 7:06:35 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 611748 Bytes = 597.4 kB
Load Address: 0c008000
Entry Point: 0c008000
Verifying Checksum ... OK
OK

Starting kernel ...

Uncompressing Linux............................................... done, booting
the kernel.
有了一点进展,从此信息来看,已经进入uclinux的代码。我用compressed下的一个putrs()函数(这名字忘了)跟踪到 system_timer->init(); system_timer->init();是在start_kernel()函数中time_init(); 调用的)可是我不知道system_timer->init();调用的init()函数放在那里?问题就出在这里了,内核调用time_init();时无法返回。
我把time_init()中的system_timer->init()改为s3c44b0_time_init()后,试运行,结果是:
Starting kernel ...

Uncompressing Linux............................................... done, booting
the kernel.
This is kernel start and init ..............
Linux version 2.6.14-hsc0 (root@localhost.localdomain) (gcc version 2.95.3 20010
315 (release)(ColdFire patches - 20010318 from
http://fiddes.net/coldfire/)(uCli
nux XIP and shared lib patches from
http://www.snapgear.com/)) #38 Tue Jan 9 13:
54:36 CST 2007
CPU: <NULL> [44b07700]
Machine: S3C44B0X Development Board
Memory management: Non-Paged(unused/noMMU)
Built 1 zonelists
Kernel command line:
PID hash table entries: 64 (order: 6, 1024 bytes)
Dentry cache hash table entries: 2048 (order: 1, 8192 bytes)
Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
Memory: 8MB = 8MB total
Memory: 6636KB available (1251K code, 118K data, 72K init)
Mount-cache hash table entries: 512

不过,过了一会系统就完了,再打出:
Stack: (0x0c155e14 to 0x0c156000)
5e00: 0c155e7c 0c155eb8 00000160
5e20: 0c010b70 00000000 40000053 0c158690 0c153d7c 00000001 00000000 0c155f68
5e40: 0c155e78 0c155e7c fffbffff ffdfffff ec000004 400000d3 0c155e7c 0c195e90
5e60: 0c158690 0c155eb8 0c195e90 0c155e94 0c155e7c 0c02c494 0c01f264 0c195d7c
5e80: fffffff4 00000000 0c155eb4 0c155e98 0c0397e4 0c02c488 0c195e90 fffffff2
5ea0: 0c195d60 00800b00 0c155ed0 0c155eb8 0c03983c 0c0397d0 0c155ee0 0c155ec8
5ec0: 0c154000 0c155ee0 0c155ed4 0c039898 0c03982c 0c155f18 0c155ee4 0c026218
5ee0: 0c039890 000000a5 00000000 00000000 00000000 00800b00 00000001 00000000
5f00: 0c155f68 0c16323c 00000000 0c155f5c 0c155f1c 0c026c9c 0c025f44 00000000
5f20: 00000000 00000001 0c16323c e0858000 0c155f64 0c155f40 00000000 0c01a06c
5f40: 0c155f68 00000a00 0c17197c e0858000 0c155fcc 0c155f60 0c01cb38 0c026bb4
5f60: 00000000 00000000 00000000 00000000 0c01a06c 0c029de4 00000000 00000000
5f80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
5fa0: 00000000 0c01cac0 00000013 00000000 01c00000 0c16281c 0c163240 000000b2
5fc0: 0c155fdc 0c155fd0 0c01a01c 0c01cadc 0c155ffc 0c155fe0 0c00876c 0c01a010
5fe0: 0c0082b4 0c1632a8 01c00000 0000000e 00000000 0c156000 0c008208 0c008600
Backtrace: no frame pointer
Code: e3a0b000 e51e7004 e59fc090 e59cc000 (ee01cf10)
<0>Kernel panic - not syncing: Attempted to kill the idle task!
系统死了,不知道是原因。uClinux-2.6.14的内核就搞到此了,无法进展了。放弃uclinux-2.6.14版本。在此期间,彷徨中,不知所措,找网友传来2.4的版本的,可是最后还是有问题。最终决定开始搞uClinux-2.6.9的版本。
 
先到http://opensrc.sec.samsung.com/网上下载:
linux-2.6.9.tar.bz2
linux-2.6.9-hsc0.patch.gz
再到www.uclinux.org去下载uClinux-dist-20041215.tar.gz 大礼包。
解压源码:
tar xzvf uClinux-dist-20041215.tar.gz 
    tar jxvf linux-2.6.9.tar.bz2
    gunzip linux-2.6.9-hsc0.patch.gz
   cd linux-2.6.9
    patch –p1 < linux-2.6.9-hsc0.patch
    mv linux-2.6.9 uClinux-dist
    cd uClinux-dist
    rm -rf linux-2.6.x
    mv linux-2.6.9 linux-2.6.x
增加44b0x相关的目录与文件:
   cd vendors/Samsung
   mkdir 44b0x
   Samsung/4510B下的所有文件(config.linux-2.4.xconfig.vendor-2.4.x除外)copy44b0x目录下。
   cp linux-2.6.x/arch/armnommu/configs/s3c44b0x_defconfig vendors/Samsung/44b0x/config.linux-2.6.x
    修改 44b0x/rc文件,将第2行和第4行中的ram0改成ram1,根据板子情况适当修改其他行。
修改linux-2.6.x/arch/armnommu/boot/compressed/head-s3c44b0.S文件。(280行附近)
  ldr  r2, S3C44B0_PROCESSOR_TYPE
  str  r2,  [r6]
  ldr  r2,  S3C44B0_MACH_TYPE
  str  r2,  [r9]
  改为:
  ldr r6, S3C44B0_PROCESSOR_TYPE
  ldr  r7, S3C44B0_MACH_TYPE
如果不改,板不稳定,有时不能运行系统。
 
romfs文件链入内核中。
uClinux-dist/vendor/Samsung/44B0X目录中的,Makefile文件的
image后添加如:
 63 image:
64 [ -d $(IMAGEDIR) ] || mkdir -p $(IMAGEDIR)
65 genromfs -v -V "ROMdisk" -f $(ROMFSIMG) -d $(ROMFSDIR)
66 arm-elf-ld -r -o $(ROOTDIR)/$(LINUXDIR)/romfs.o -b binary $(ROMFSIMG)
67 $(CROSS_COMPILE)objcopy -O binary --remove-section=.romvec 68 --remove-section=.text --remove-section=.ramvec 69 --remove-section=.init 70 --remove-section=.bss --remove-section=.eram 71 $(ROOTDIR)/$(LINUXDIR)/linux $(IMAGEDIR)/linux.data
最新评论共有 4 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
用户名: 密码:
匿名?
注册