(1) 作业因由
几个月前从朋友那里拿到了一块参阅Micetek EV44b0-II开发板规划的板子,对其bootloader MBL感觉很不错. 朋友说或许是移植 u-boot的.但Micetek并没有供给MBL的源代码, 因而其时没有细心去研讨. 最近公司预备想做依据S3C44B0X CPU的产品,因而购买了杭州立宇泰公司()的armsys-c及armsys-b开发板和.armsys供给的 bootloader 是其公司自己开发的bootloader,觉得其USB这一块做的还能够,但运用USB下载调试uclinux是十分费事的,操作很不爽,其 bootloader也不供给网络下载调试.因而自己方案移植u-boot.
(2) 开端
因为没有触摸过u-boot,因而第一步要做的便是google一些资料.
u-boot官方网站:http://sourceforge.net/projects/u-boot(比较慢)
http://u-boot.sourceforge.net/这个快一些.
DENX U-Boot及Linux运用手册: http://coosign.blogchina.com/coosign/1318487.html, 这是一遍翻译的文档.首要介绍了u-boot编译及运用的指令.但没有触及新板子的移植流程.
到board目录查了一下:
#cd u-boot
#cd board
#find . -exec grep -l 44B0 {} \;
成果是:
./dave/B2/B2.c
B2网站是: ,初初看了B2开发板的介绍,但不详细.包含运用的网络芯片等都没有介绍.
google “u-boot 移植”后查到一篇文章:
“收集了一些关于U-BOOT的文章”
http://www.bloghome.cn/index.php?op=ViewArticle&articleId=2111&blogId=390
里边搜集了不少关于u-boot移植的问题.
里边介绍了”U-Boot 在44B0X 开发板上的移植以及代码剖析”的内容,细心看了看.发现其移植的版别比较低,但对了解u-boot结构是满不错的,因为这个版别不支撑44B0X,因而完全是支撑新CPU的移植.了解到 make XX_config是在Makefile中界说的.
别的”MPC8xx的U-Boot移植领会(ZT) “这一篇对u-boot介绍满详细的.但对移植作业只做了理论性和经验性介绍,没有详细的操作过程.
“依据Atmel at91rm9200的armlinux的bootloader发动代码剖析 “
http://www.linuxfans.org/nuke/modules.php?name=News&file=print&sid=2765
里边介绍了u-boot移植到at91rm9200上的状况,能够参阅一下.
别的便是细心阅读u-boot下的README文件.
(3) 编译一把
看了相关的资料,心动不如举动.先编译一把看看状况.已然只要B2开发板是S3C44B0X CPU的,因而先编译一下B2开发板看看. 详细:
#cd u-boot
#make B2_config
#make
成果顺畅,成功编译.
(4) 开端着手移植
我以B2板子的程序做为模板来做.
#cd board
#cp -r dave wx (自己取个公司名wx)
#cd wx
#mv B2 wx20 (自己取个板子名wx20)
#cd wx20
# mv B2.c wx20.c
修正Makefile及wx20.c, 首要是B2改成wx20.
添加装备文件:
#cd include/configs
#cp B2.h wx20.h
修正Makefile装备文件,添加wx20_config.
1432 wx20_config : unconfig
1433 @./mkconfig $(@:_config=) arm s3c44b0 wx20 wx
[注:前面的数字是文件行号,以下相同].
将board/wx目录下和wx20.h文件中的B2改成wx20或WX20.
这儿其实是最重要的过程,便是依据硬件的状况来修正相关的参数.因为对硬件板子的状况不是太了解,因而此刻最需求的便是耐心肠看看硬件资料.首要修正的当地有:
include/configs/wx20.h —- 装备文件,大部分参数是这儿装备的.
board/wx/wx20/lowlevel_init.S — 内存参数装备
cpu/s3c44b0/serial.c — 串口装备
cpu/s3c44b0/start.S — 程序进口
假如此刻装备悉数正确了,那么咱们就简略的很了.(假如你用我的patch的话,便是如此了!)那么我也就不会细心再去研讨u-boot其他部分了. 困难便是你学习的最好时机!
(5) 开端编译
通过简略的参数修正,编译成功.然后下载u-boot.bin(二进制格局). 此刻你能够用nm看一下u-boot(elf格局)的内容,会有所收成的.
然后用armsys的bootloader将u-boot.bin调入到内存0xc100000运转.成果可想而知,串口没有任何显现,并且死机.bootloader也有必要断电重起.
(6) u-boot流程
原因是比较显着的,便是参数和硬件没有契合.因而接下来做的作业便是细心阅读S3C44B0 CPU的硬件资料,包含内存装备,串口装备这些.我觉得要让串口出信息,最首要的便是CPU的初始化,内存装备和串口装备.别的便是了解u-boot程序运转流程,这个对了解需求设置的参数是十分有协助的.我这儿大致说一下u-boot运转流程.
进口: cpu/s3c44b0/start.S
首要是CPU初始化( cpu_init_crit 200), 调内存装备函数( lowlevel_init 200), 然后判别u-boot是否从flash运转,假如是就把u-boot代码拷贝到TEXT_BASE界说的当地.然后转到 start_armboot.
start_armboot: lib_arm/board.c
进行各种初始化设置,首要有:
cpu_init CPU相关的设置, 详细在./cpu/s3c44b0/cpu.c中.
board_init 板子相关的设置, 详细在board/wx/wx20/wx20.c 中
interrupt_init中止设置,咱们没有用,详细在./cpu/s3c44b0/interrupts.c中
env_init 初始化环境变量, 详细要看用什么介质来存储环境变量,假如用flash来存贮, 程序在common/env_flash.c中.
init_baudrate 设置baud参数
serial_init 串口初始化, 详细在cpu/s3c44b0/serial.c.
console_init_f 控制台设置, 详细在./common/console.c
display_banner 显现标题.
dram_init 可用内存装备, 详细在./board/wx/wx20/wx20.c.
flash_init flash初始化,详细./drivers/cfi_flash.c.
接下来便是环境变量初始化, 网络初始化,最后到main_loop,能够运转各种指令.
(7) 首要参数修正
通过一段时刻调试,总算串口出东西了,这段时刻犯了一个小过错,走了一段冤枉路.其实装备参数或许早已正确,但串口老是乱码,原因是自己的u-boot.bin传下来时目录搞错了,成果老是运转过错的u-boot.bin.这段时刻里首要改的参数有:
include/configs/wx20.h:
#define CONFIG_S3C44B0_CLOCK_SPEED 64
CPU主频,armsys板的是64M
#define PHYS_SDRAM_1 0x0c000000 /* SDRAM Bank #1 */
B2板子里的界说是过错的.还有RAM巨细,flash巨细需求修正,跟B2板不同.
#define CONFIG_DRIVER_RTL8019
#define RTL8019_BASE 0x08000000
装备rtl8019AS网络芯片.
#define CFG_LOAD_ADDR 0x0c008000 /* default load address */
uclinux运转进口地址
lowlevel_init.S:
MEMORY_CONFIG:
.long 0x11010102
.long 0x600
.long 0x7ffc
.long 0x7ffc
.long 0x7ffc
.long 0x7ffc
.long 0x2610
.long 0x18000
.long 0x18000
.long 0x960459
.long 0x10
.long 0x20
.long 0x20
因为对armsys硬件不是太了解,没有办法,只得看armsys bootloader程序,但每个版别又有不同.因而是用AXD调试看bootlaoder发动后0x1c80000中的值定的.
cpu/s3c44b0/serial.c:
#elif CONFIG_S3C44B0_CLOCK_SPEED==64
divisor = 34;
串口设置,这个也是依据bootloader里的公式计算出来的.这儿只界说了115200得值,其他没有去设置.
cpu/s3c44b0/start.S:
ldr r1, =PLLCON
#if CONFIG_S3C44B0_CLOCK_SPEED==66
ldr r0, =0x34031 /* 66MHz (Quartz=11MHz) */
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
ldr r0, =0x610c1 /*B2: Xtal=20mhz Fclk=75MHz */
#elif CONFIG_S3C44B0_CLOCK_SPEED==64
ldr r0, =((M_DIV<<12)+(P_DIV<<4)+S_DIV) //Fin=8MHz,Fout=64MHz
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
#endif
PLLCON的值,也是依据bootlaoder的公式.
board/wx/wx20/wx20.c
首要是PORT装备,详细我不知道有没有影响.
(8) 关于u-boot进口的疑问
因为开端串口没有出内容,因而对u-boot进口发生置疑.在网上也找到一个帖子,碰到相同疑问的人:
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=embedded&Number=563322&page=0&view=collapsed&sb=5&o=0&fpart=
“链接得到的开端地址为什么是TEXT_BASE,而不是0呢,所以现在只能够下载到ram中运转,可是无法烧写道flash中跑,这是怎么回事呢?u-boot中应该是start.S中的这段代码在flash中运转吧,后边就把本身拷贝到ram中TEXT_BASE地址处,为什么在链接文件中指定的_start的开端地址为0x00000000呢? “
后来我了解了:
“链接得到的开端地址为什么是TEXT_BASE,而不是0呢,”
因为u_boot假如从flash运转的话,那么它会将自己的代码拷贝到RAM中,然后运转。u-boot开端部分代码与编译的进口没有关系,而首要的代码是在RAM中运转,因而编译的进口地址是TEXT_BASE.因而u-boot既能够flash运转,也能够ram运转。
“为什么在链接文件中指定的_start的开端地址为0x00000000呢?”
lds文件中的开端地址为0x00000000是不起作用的,由-TTEXT_BASE参数代替的。
刚开端比较疑问的原因是对:
126 relocate: /* relocate U-Boot to RAM */
127 adr r0, _start /* r0 <- current position of code */
adr这条指令没有了解正确,因为把它想成mv r0,_start了,实际上adr这儿的_start是相对的,假如从flash运转的话,r0便是0, 假如从ram运转的话,r0便是C100000。
(9) u-boot显现信息
通过上面的尽力,咱们总算能够看到u-boot的庐山真面目了.当然这还不是终究的成果.但至少离成功不远了.现在咱们能够用printf来调试了.此刻悉数是通过armsys bootloader下载u-boot.bin到0xc100000运转.
现在显现信息是:
Plese wait a moment to start running…i am samfei!
iamsam!
U-Boot 1.1.3 (Jul 1 2005 – 13:46:03)
U-Boot code: 0C100000 -> 0C11A73C BSS: -> 0C11ECF4
RAM Configuration:
Bank #0: 0c000000 8 MB
[flash_get_size, 224] Entering …
[flash_get_size, 232] value=bf
[flash_get_size, 255] value=234b
Flash: 2 MB
*** Warning – bad CRC, using default environment
In: serial
Out: serial
Err: serial
MAC: 26:26:26:26:26:26
Hit any key to stop autoboot: 0
=>
(10) 期望环境变量存贮到flash
B2板缺省的界说是把环境变量存贮到EEPROM上,尽管armsys上也有,但我也搞不清楚它的硬件装备,因而期望把环境变量存贮到flash上.
添加装备: include/configs/wx20.h (从evb4510.h中学来!)
79 #define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
80 CFG_CMD_DATE | \
81 CFG_CMD_ELF | \
82 CFG_CMD_NET | \
83 CFG_CMD_ENV|CFG_CMD_FLASH 200)this.width=200>screen.width/2)this.style.width=screen.width/2;” border=0>
173 #define CFG_ENV_IS_IN_FLASH
174 #undef CFG_ENV_IS_NOWHERE
175
176 #define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x20000) /* environment start address */
177 #define CFG_ENV_SECT_SIZE 0x10000 /* Total Size of Environment Sector */
编译运转, 并操作setenv, saveenv, printenv. 看起来正常.
=> setenv ipaddr 192.168.1.100
=> saveenv
Saving Environment to Flash…
Un-Protected 1 sectors
Erasing Flash…
done
Erased 1 sectors
Writing to Flash… done
Protected 1 sectors
ð printenv
但从头发动机器后,参数没有起作用,仍是缺省的.细心看了环境变量的程序,发现是因为ENV_IS_EMBEDDED界说形成的,而此变量界说是在./tools/envcrc.c中:
# if (CFG_ENV_ADDR >= CFG_MONITOR_BASE) && \
((CFG_ENV_ADDR + CFG_ENV_SIZE) <= (CFG_MONITOR_BASE + CFG_MONITOR_LEN))
# define ENV_IS_EMBEDDED 1
# endif
因而在wx20.h中添加了:
#define CFG_MONITOR_BASE PHYS_SDRAM_1 (我还没搞清楚这个变量干啥的.)
首要是去除ENV_IS_EMBEDDED的界说。
成果的确预备运用flash的环境变量,但每次总是说标志头过错,通过细心调试,终究发现flash写呈现过错,原因是我忘了修正wx/common/flash.c中的CONFIG_B2为CONFIG_WX20. 修正后就正常了.
(11) arm-linux和arm-elf
上面调试一向是arm-elf,原因是以前有问题时置疑编译器问题而修正了,因而没有改动。改用arm-linux编译后:
U-Boot 1.1.3 (Jul 3 2005 – 07:01:36)
U-Boot code: 0C100000 -> 0C117DA0 BSS: -> 0C11C0F0
RAM Configuration:
Bank #0: 0c000000 8 MB
env_init flash_addr=20000
flash_addr=20000 env_ptr=20000 env_ptr->data=bootargs=setenv bootargs root=/dev/ram ip=192.168.1.100:::::eth0:off ether=25,0,0,0,eth0 ethaddr=00:50:c2:1e:af:fb
envptr->crc=1470de2 1470de2
buffer->crc=1470de2
[flash_get_size, 224] Entering …
[flash_get_size, 232] value=bf
[flash_get_size, 255] value=234b
Flash: 2 MB
env_ptr=20000
gd->env_addr=20004 gd->env_valid=1
env_relocate[211] offset = 0x0
env_relocate[229] malloced ENV at 00000000
In:
Out:
Err:
死机!!!
然后改回arm-elf编译:
U-Boot 1.1.3 (Jul 3 2005 – 07:04:48)
U-Boot code: 0C100000 -> 0C119B98 BSS: -> 0C11DCD8
RAM Configuration:
Bank #0: 0c000000 8 MB
env_init flash_addr=20000
flash_addr=20000 env_ptr=20000 env_ptr->data=bootargs=setenv bootargs root=/dev/ram ip=192.168.1.100:::::eth0:off ether=25,0,0,0,eth0 ethaddr=00:50:c2:1e:af:fb
envptr->crc=1470de2 1470de2
buffer->crc=1470de2
[flash_get_size, 224] Entering …
[flash_get_size, 232] value=bf
[flash_get_size, 255] value=234b
Flash: 2 MB
env_ptr=20000
gd->env_addr=20004 gd->env_valid=1
env_relocate[211] offset = 0x0
env_relocate[229] malloced ENV at 0c0dfc08
In: serial
Out: serial
Err: serial
rtl8019 MAC: 2a:2a:2a:2a:2a:2a
Hit any key to stop autoboot: 0
=>
正常!因而最好是用arm-elf编译. 我在看网上查资料时记住有人说过”用arm-linux编译时,malloc回来0,而改成arm-elf编译时就好了”.有个形象,详细帖子不记住在哪里了.所以后来我就一向运用arm-elf编译,没有再去试arm-linux编译.
(12) 网卡调试
剩下来的作业便是调网络了.依据上面装备rtl8019as后,网络依然不同,然后参阅uclinux驱动中的寄存器界说修正,网络就能够了.详细修正是:
drivers/rtl8019.h
36 #define ETH_ADDR_SFT (8)
37 #define EI_SHIFT(x) ((x)<
38
39 #define RTL8019_REG_00 (RTL8019_BASE + EI_SHIFT(0x00))
40 #define RTL8019_REG_01 (RTL8019_BASE + EI_SHIFT(0x01))
……
(13) 开端load uclinux
设置好本机ip地址,服务器ip地址, 下载文件名这些参数后,就能够load uclinux了.
=> tftpboot
eth_init…00:50:c2:1e:af:fb
TFTP from server 192.168.1.25; our IP address is 192.168.1.100
Filename image.bin.
Load address: 0xc008000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
###############################
死机!
原因是咱们现在的u-boot进口地址是C100000,而uclinux内核大约2M,因而load过来就抵触了.因而咱们把u-boot的进口地址改成C300000,详细修正在board/wx/wx20/config.mk:
TEXT_BASE = 0x0C300000
从头编译运转就能够了.
(14) 设置主动运转uclinux
方才咱们是用指令load uclinux并履行的.主动运转需求设置bootcmd环境变量:
=> setenv bootcmd “tftpboot; go 0xc008000” ==》设置过错
## Starting application at 0x0C008000 …
=> setenv bootcmd “tftpboot\; go 0xc008000” ==》需求有个\
=> saveenv
从头开机运转u-boot:
Hit any key to stop autoboot: 0
Unknown command “tftpboot – try help
## Starting application at 0x0C008000 …
成果仍是不能主动下载uclinux和运转.通过调试才发现在设置bootcmd时多加了引号形成的!正确的设法是:
=> setenv bootcmd tftpboot \; go 0xc008000 ==》正确的设置
此刻能够成功主动下载uclinux和运转了.
(15) flash运转
刻录到flash后,运转uclinux呈现问题,运转到:uclinux 开中止后就死机,提示:
Linux version 2.4.24-uc0 (root@samfei) (gcc version 2.95.3 20010315 (release)(ColdFire patches – 20010318 from :http://fiddes.net/coldfire/)(uClinux XIP and shared lib patches from :http://www.snapgear.com/)) #46 Áù 7ÔÂ 2 15:52:55 CST 2005
Processor: Samsung S3C44B0X revision 0
Architecture: S3C44B0X
On node 0 totalpages: 2048
zone(0): 0 pages.
zone(1): 2048 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/rom0 init=/linuxrc
前面一向用armsys的bootloader,将u-boot下载到0xc300000运转,然后再load linux到0xc0080000运转,正常.而将u-boot刻录到flash后运转不正常,通过调试uclinux,到init/main.c中 sti()函数后呈现死机.因而置疑中止向量设置问题.
将cpu/s3c44b0/start.S中代码修正成;
40 .globl _start
41 _start: b reset
42 /*
43 add pc, pc, #0x0c000000
44 add pc, pc, #0x0c000000
45 add pc, pc, #0x0c000000
46 add pc, pc, #0x0c000000
47 add pc, pc, #0x0c000000
48 add pc, pc, #0x0c000000
49 add pc, pc, #0x0c000000
50 */
51 LDR PC, Undefined_Addr
52 LDR PC, SWI_Addr
53 LDR PC, Prefetch_Addr
54 LDR PC, Abort_Addr
55 LDR PC,RESERVE_Addr
56 LDR PC, IRQ_Addr
57 /* subs pc,lr,#4*/
58 LDR PC, IRQ_Addr
59 /* subs pc,lr,#4*/
114 Undefined_Addr:
115 .word 0x0c000004
116 SWI_Addr:
117 .word 0x0c000008
118 Prefetch_Addr:
119 .word 0x0c00000C
120 Abort_Addr:
121 .word 0x0c000010
122 RESERVE_Addr:
123 .word 0x0c000014
124 IRQ_Addr:
125 .word 0x0c000018
126 FIQ_Addr:
127 .word 0x0c00001C
128
129 /*
130 * the actual reset code
131 */
132
133 reset:
后编译,刻录,然后运转.正常了!!!
(16) 补丁制作和测验
[root@samfei u-boot]# make distclean
[root@samfei 44b0]# mv u-boot u-boot.wx
[root@samfei 44b0]# cvs -d200) server:anonymous@cvs.sourceforge.net:/cvsroot/u-boot login
Logging in to server:anonymous@cvs.sourceforge.net:2401/cvsroot/u-boot
CVS password:
[root@samfei 44b0]# cvs -z3 -d200) server:anonymous@cvs.sourceforge.net:/cvsroot/u-boot co -P u-boot
cvs checkout: Updating u-boot
U u-boot/CHANGELOG
U u-boot/COPYING
U u-boot/CREDITS
U u-boot/MAINTAINERS
。。。。。。
[root@samfei 44b0]# diff -Naur u-boot u-boot.wx > uboot-wx-20050703.patch
[root@samfei 44b0]# vi uboot-wx-20050703.patch
去掉没有用的文件.做补丁的优点便是自己能够很清楚的知道哪些文件修正了!做完了,别忘了测验一下.
[root@samfei 44b0]# cd u-boot
[root@samfei u-boot]# patch -p1 < ../uboot-wx-20050703.patch
[root@samfei u-boot]# make wx20_config
[root@samfei u-boot]# make
(17) 跋文
写这份资料化了不少时刻.因为在调试的时分记录了大部分的调试信息,因而不用费脑筋去回想.写完了这个阅历,十分高兴..一则自己能够温故而知新,二则便是与人同享啊.在开源的国际里,与人同享应该是件很高兴的一件作业.