2007-07-21
今天把vivi编译了一下,顺便解决了几个问题。算是初步工作吧,下一步打算读vivi的源代码,然后改造一下,最后争取自己完成一个小的bootloader。
准备工作(这些都是基于EDUKIT-III教学平台,虽然开发工具上有些不同,但是原理和流程上是相同的。相信理解了嵌入式系统开发流程之后,对这些就会有很清晰的认识):
1)下载Nand_Prog.ide.bin到nor flash。这步工作是为烧写nand flash做准备的。为什么不利用仿真器直接烧写nand flash呢?理解了JTAG的原理后,对这步工作不难理解。nand flash和nor flash是不同的,nand flash的烧写需要ECC算法等,比较复杂。现在的这个仿真器不支持,所以就不能利用JTAG来直接烧写了。当然,如果在仿真器支持软件中加入对nand flash烧写的支持,这步工作就省去了。就我所知,国内foxICE已经可以支持直接烧写nand flash了。
2)开发环境
还是windowsXP+VMware+redhat 9。原来学习at91rm9200的时候,开发环境都已经搭建好了,开发工具也比较齐全。
3)目标
移植好的vivi能支持从nand flash启动,测试内置的命令正常,利用开发板原来的内核映象和文件系统能够跑起来。vivi毕竟是一个比较小巧的bootloader,功能有限,使用上可能有不方便的地方,所以,可以考虑在此基础上,读源代码,然后增加tftp下载功能。
开始工作
1)下载vivi
我使用EDUKIT-III光盘中提供的vivi-20060929.tar.gz。解压不必细说,下面就开始修改。下面的修改方案是基于网上帖子,因为还没有仔细分析源代码,所以有些地方还不能理解清晰,这里的移植是为了获得直观的印象,如果要想得到技术水平的提升,那还是得深入分析vivi源代码,看看这一切究竟是如何完成的。
2)修改Makefile
因为国内大部分S3C2410的设计都是抄袭smdk2410,所以vivi的移植相对来说,工作量很小,只需要更改开发工具的几个宏就可以了。当然,如果想要增加功能,则改动可能会大一点。
只要更改如下:
LINUX_INCLUDE_DIR -- 更改为交叉编译器的include文件夹
CROSS_COMPILE -- 交叉编译器的可执行文件的路径
ARM_GCC_LIBS -- 交叉编译器的lib库文件的路径
################## Modified Start #################################### # Data : 2007-07-21 # Modified by Liu Qingmin <piaoxiangxinling@163.com>
# # change this to point to the Linux include directory #
# orginal setup #LINUX_INCLUDE_DIR = /opt/host/armv4l/include/
# my setup LINUX_INCLUDE_DIR = /usr/local/arm/2.95.3/include
################# Modified End ######################################
|
################## Modified Start #################################### # Data : 2007-07-21 # Modified by Liu Qingmin <piaoxiangxinling@163.com>
# orginal setup #CROSS_COMPILE = /opt/host/armv4l/bin/armv4l-redhat-linux- #CROSS_COMPILE = /opt/host/armv4l/bin/armv4l-unknown-linux-
# my setup CROSS_COMPILE = /usr/local/arm/2.95.3/bin/arm-linux-
################# Modified End ######################################
|
################## Modified Start #################################### # Data : 2007-07-21 # Modified by Liu Qingmin <piaoxiangxinling@163.com>
# # Location of the gcc arm libs. #
# orginal setup #ARM_GCC_LIBS = /opt/host/armv4l/lib/gcc-lib/armv4l-unknown-linux/2.95.2 #ARM_GCC_LIBS = /opt/host/armv4l/lib/gcc-lib/armv4l-redhat-linux/2.95.3
# my setup ARM_GCC_LIBS = /usr/local/arm/2.95.3/lib/gcc-lib/arm-linux/2.95.3
################# Modified End ######################################
|
这些都比较简单。
3)修改arch/s3c2410/smdk.c
主要是修改nand flash分区信息。
#ifdef CONFIG_S3C2410_NAND_BOOT mtd_partition_t default_mtd_partitions[] = { { name: "vivi", /* 128K, 1-8 sector */ offset: 0, size: 0x00020000, flag: 0 }, { name: "param", /* 64K, 9-12 sector */ offset: 0x00020000, size: 0x00010000, flag: 0 }, { name: "kernel", /* 2M+832K, 12-192 setctor */ offset: 0x00030000, size: 0x002d0000, flag: 0 }, { name: "root", /* 29M, 193-2048 sector */ offset: 0x00300000, size: 0x01d00000, flag: MF_BONFS } };
|
这里遇到了bon分区与mtd分区的疑惑,在分析vivi源代码时在深入分析。上面文件配置的只是mtd分区,这个可以用part show来查看。
4)编译烧写
写个简单的批处理脚本procedure。以便后续工作的方便。【后来发现,vivi本身就提供了这样的操作,所以这个小的脚本是没有必要编写的。这一点会在Makefile分析时给出】
[root@lqm vivi]# cat procedure #!/bin/sh
make myboard_config && make oldconfig && make vivi && cp -f vivi /mnt/hgfs/common/
|
烧写vivi,正常。但是蜂鸣器一直在响。于是想在vivi中添加代码,关掉蜂鸣器,同时利用开发板上的四个指示灯做一个跑马灯的小程序。于是修改arch/s3c2410/head.S:
@@@@@@@@@@@@@@@@@@ Modified Start @@@@@@@@@@@@@@@@@@@@@ mov r0, #10 @ rotate 10 times loop: mov r2, #0xdf @ D1205 led on str r2, [r1, #oGPIO_DAT] bl delay
mov r2, #0x7f @ D1207 led on str r2, [r1, #oGPIO_DAT] bl delay
mov r2, #0xef @ D1204 led on str r2, [r1, #oGPIO_DAT] bl delay
mov r2, #0xbf @ D1206 led on str r2, [r1, #oGPIO_DAT] bl delay
subs r0, r0, #1 bne loop
mov r2, #0x0f @ all leds on str r2, [r1, #oGPIO_DAT]
@ buzzer off ldr r1, =0x56000010 @ GPBCON ldr r2, =0x155559 str r2, [r1] ldr r2, =0x7ff str r2, [r1, #8] orr r2, r2, #0x01 @ buzzer off when high voltage(PWM1) str r2, [r1, #4] @@@@@@@@@@@@@@@@@@ Modified End @@@@@@@@@@@@@@@@@@@@@@@@@
|
/* * subroutines */
@@@@@@@@@@@@@@@@@@ Modified Start @@@@@@@@@@@@@@@@@@@@@ @ @ led delay @ delay: ldr r3, =0x00080000 wait: subs r3, r3, #1 bne wait
mov pc, lr
@@@@@@@@@@@@@@@@@@ Modified End @@@@@@@@@@@@@@@@@@@@@
|
通过source insight查看代码,可以分析出第一条打印信息的来源init/version.c。这样,just for fun,可以添加自己的启动信息。主要的参数都是有Makefile来完成的,读一下Makefile的代码,不难发现。
[root@lqm init]# cat version.c /* * vivi/lib/version.c */
#include "version.h" #include "compile.h"
const char *vivi_banner = "\n\r\t\t^_^ Well done, boy! Go on --> \n\r\n\r" "VIVI version " VIVI_RELEASE " (" VIVI_COMPILE_BY "@" VIVI_COMPILE_HOST ") (" VIVI_COMPILER ") " UTS_VERSION "\n\r";
|
【注:这里还有个小问题。就是在这里添加的时候,\n\r要合起来用,不能只用\n。原因如下:
计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。
于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。
这就是“换行”和“回车”的来历,从它们的英语名字上也可以看出一二。
后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以。于是,就出现了分歧。Unix 系统里,每行结尾只有“<换行>”,即“\n”;Windows系统里面,每行结尾是“<换行><回车>”,即“\ n\r”;Mac系统里,每行结尾是“<回车>”。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。
这几个地方我都遇到过,不过一直没有搞清楚。现在才算是找到根源了。】
添加完成,重新执行procedure。完成烧写,测试如下:
^_^ Well done, Go on -->
VIVI version 0.1.4 (root@lqm) (gcc version 2.95.3 20010315 (release)) #0.1.4 日 7月 22 10:15:15 CST 2007 MMU table base address = 0x33DFC000 Succeed memory mapping. NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T) Could not found stored vivi parameters. Use default vivi parameters. Press Return to start the LINUX now, any other key for vivi type "help" for help. vivi> part show mtdpart info. (4 partitions) name offset size flag ------------------------------------------------ vivi : 0x00000000 0x00020000 0 128k param : 0x00020000 0x00010000 0 64k kernel : 0x00030000 0x002d0000 0 2M+832k root : 0x00300000 0x01d00000 4 29M vivi>
|
然后执行bon分区:
vivi> bon part 0 192K 3M doing partition offset = 0 flag = 0 offset = 196608 flag = 0 offset = 3145728 flag = 0 check bad block part = 0 end = 196608 part = 1 end = 3145728 part = 2 end = 33554432 part0: offset = 0 size = 196608 bad_block = 0 part1: offset = 196608 size = 2949120 bad_block = 0 part2: offset = 3145728 size = 30392320 bad_block = 0 vivi>
|
重新烧写vivi,注意这个时候不要断电。
vivi> load flash vivi x Ready for downloading using xmodem... Waiting...
正在开始 xmodem 传输。 按 Ctrl+C 取消。 正在传输 vivi... 100% 67 KB 6 KB/s 00:00:10 0 错误
Downloaded file at 0x30000000, size = 69376 bytes Found block size = 0x00014000 Erasing... ... done Writing... ... done Written 69376 bytes vivi>
|
检查分区情况:
vivi> part show mtdpart info. (4 partitions) name offset size flag ------------------------------------------------ vivi : 0x00000000 0x00020000 0 128k param : 0x00020000 0x00010000 0 64k kernel : 0x00030000 0x002d0000 0 2M+832k root : 0x00300000 0x01d00000 4 29M vivi> bon part show BON info. (3 partitions) No: offset size flags bad --------------------------------------------- 0: 0x00000000 0x00030000 00000000 0 192k 1: 0x00030000 0x002d0000 00000000 0 2M+832k 2: 0x00300000 0x01cfc000 00000000 0 28M+1008k vivi>
|
其中,part show显示的是mtd分区信息,跟smdk.c文件的配置相同。bon part show显示的bon分区信息,注意到最后一个分区少了一个扇区16K,因为bon命令把bon分区信息表存储在最后一个扇区了。
烧写内核映象和文件系统:
vivi> load flash kernel x Ready for downloading using xmodem... Waiting...
正在开始 xmodem 传输。 按 Ctrl+C 取消。 正在传输 zImage... 100% 646 KB 7 KB/s 00:01:25 0 错误
Downloaded file at 0x30000000, size = 661760 bytes Found block size = 0x000a4000 Erasing... ... done Writing... ... done Written 661760 bytes vivi> ?
^_^ Well done, Go on -->
VIVI version 0.1.4 (root@lqm) (gcc version 2.95.3 20010315 (release)) #0.1.4 日 7月 22 10:15:15 CST 2007 MMU table base address = 0x33DFC000 Succeed memory mapping. NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T) Found saved vivi parameters. Press Return to start the LINUX now, any other key for vivi Copy linux kernel from 0x00030000 to 0x30008000, size = 0x002d0000 ... done zImage magic = 0x016f2818 Setup linux parameters at 0x30000100 linux command line is: "noinitrd root=/dev/bon/2 init=/linuxrc console=ttyS0" MACH_TYPE = 193 NOW, Booting Linux...... Uncompressing Linux............................................... done, booting the kernel. Linux version 2.4.18-rmk7-pxa1 (root@lqm) (gcc version 2.95.3 20010315 (release)) #1 Fri Jul 20 15:12:44 CST 2007 CPU: ARM/CIRRUS Arm920Tsid(wb) revision 0 Machine: Embest EduKit II (S3C2410x) On node 0 totalpages: 16384 zone(0): 16384 pages. zone(1): 0 pages. zone(2): 0 pages. Kernel command line: noinitrd root=/dev/bon/2 init=/linuxrc console=ttyS0 DEBUG: timer count 15626 Console: colour dummy device 80x30 Calibrating delay loop... 99.94 BogoMIPS Memory: 64MB = 64MB total Memory: 62880KB available (1229K code, 296K data, 60K init) Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes) Inode-cache hash table entries: 4096 (order: 3, 32768 bytes) Mount-cache hash table entries: 1024 (order: 1, 8192 bytes) Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes) Page-cache hash table entries: 16384 (order: 4, 65536 bytes) POSIX conformance testing by UNIFIX Linux NET4.0 for Linux 2.4 Based upon Swansea University Computer Society NET3.039 Initializing RT netlink socket CPU clock = 200.000 Mhz, HCLK = 100.000 Mhz, PCLK = 50.000 Mhz Starting kswapd devfs: v1.10 (20020120) Richard Gooch (rgooch@atnf.csiro.au) devfs: boot_options: 0x1 ttyS%d0 at I/O 0x50000000 (irq = 52) is a S3C2410 ttyS%d1 at I/O 0x50004000 (irq = 55) is a S3C2410 ttyS%d2 at I/O 0x50008000 (irq = 58) is a S3C2410 Console: switching to colour frame buffer device 30x40 Installed S3C2410 frame buffer pty: 256 Unix98 ptys configured s3c2410-ts initialized S3C2410 Real Time Clock Driver v0.1 block: 128 slots per queue, batch=32 eth0: cs8900 rev K(3.3 Volts) found at 0xd0000300 cs89x0 media RJ-45, IRQ 37 NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T) bon0: 00000000-00030000 (00030000) 00000000 bon1: 00030000-00300000 (002d0000) 00000000 bon2: 00300000-01ffc000 (01cfc000) 00000000 NET4: Linux TCP/IP 1.0 for NET4.0 IP Protocols: ICMP, UDP, TCP, IGMP IP: routing cache hash table of 512 buckets, 4Kbytes TCP: Hash tables configured (established 4096 bind 4096) NET4: Unix domain sockets 1.0/SMP for Linux NET4.0. NetWinder Floating Point Emulator V0.95 (c) 1998-1999 Rebel.com cramfs: wrong magic FAT: bogus logical sector size 65535 Kernel panic: VFS: Unable to mount root fs on 61:02
vivi> load flash root x Ready for downloading using xmodem... Waiting...
正在开始 xmodem 传输。 按 Ctrl+C 取消。 正在传输 root.cramfs... 100% 1104 KB 7 KB/s 00:02:22 0 错误
Downloaded file at 0x30000000, size = 1130496 bytes Found block size = 0x00114000 Writing... size = 1130496 bad_block = 0 ... done Written 1130496 bytes vivi>
vivi>
^_^ Well done, Go on -->
VIVI version 0.1.4 (root@lqm) (gcc version 2.95.3 20010315 (release)) #0.1.4 日 7月 22 10:15:15 CST 2007 MMU table base address = 0x33DFC000 Succeed memory mapping. NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T) Found saved vivi parameters. Press Return to start the LINUX now, any other key for vivi Copy linux kernel from 0x00030000 to 0x30008000, size = 0x002d0000 ... done zImage magic = 0x016f2818 Setup linux parameters at 0x30000100 linux command line is: "noinitrd root=/dev/bon/2 init=/linuxrc console=ttyS0" MACH_TYPE = 193 NOW, Booting Linux...... Uncompressing Linux............................................... done, booting the kernel. Linux version 2.4.18-rmk7-pxa1 (root@lqm) (gcc version 2.95.3 20010315 (release)) #1 Fri Jul 20 15:12:44 CST 2007 CPU: ARM/CIRRUS Arm920Tsid(wb) revision 0 Machine: Embest EduKit II (S3C2410x) On node 0 totalpages: 16384 zone(0): 16384 pages. zone(1): 0 pages. zone(2): 0 pages. Kernel command line: noinitrd root=/dev/bon/2 init=/linuxrc console=ttyS0 DEBUG: timer count 15626 Console: colour dummy device 80x30 Calibrating delay loop... 99.94 BogoMIPS Memory: 64MB = 64MB total Memory: 62880KB available (1229K code, 296K data, 60K init) Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes) Inode-cache hash table entries: 4096 (order: 3, 32768 bytes) Mount-cache hash table entries: 1024 (order: 1, 8192 bytes) Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes) Page-cache hash table entries: 16384 (order: 4, 65536 bytes) POSIX conformance testing by UNIFIX Linux NET4.0 for Linux 2.4 Based upon Swansea University Computer Society NET3.039 Initializing RT netlink socket CPU clock = 200.000 Mhz, HCLK = 100.000 Mhz, PCLK = 50.000 Mhz Starting kswapd devfs: v1.10 (20020120) Richard Gooch (rgooch@atnf.csiro.au) devfs: boot_options: 0x1 ttyS%d0 at I/O 0x50000000 (irq = 52) is a S3C2410 ttyS%d1 at I/O 0x50004000 (irq = 55) is a S3C2410 ttyS%d2 at I/O 0x50008000 (irq = 58) is a S3C2410 Console: switching to colour frame buffer device 30x40 Installed S3C2410 frame buffer pty: 256 Unix98 ptys configured s3c2410-ts initialized S3C2410 Real Time Clock Driver v0.1 block: 128 slots per queue, batch=32 eth0: cs8900 rev K(3.3 Volts) found at 0xd0000300 cs89x0 media RJ-45, IRQ 37 NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T) bon0: 00000000-00030000 (00030000) 00000000 bon1: 00030000-00300000 (002d0000) 00000000 bon2: 00300000-01ffc000 (01cfc000) 00000000 NET4: Linux TCP/IP 1.0 for NET4.0 IP Protocols: ICMP, UDP, TCP, IGMP IP: routing cache hash table of 512 buckets, 4Kbytes TCP: Hash tables configured (established 4096 bind 4096) NET4: Unix domain sockets 1.0/SMP for Linux NET4.0. NetWinder Floating Point Emulator V0.95 (c) 1998-1999 Rebel.com VFS: Mounted root (cramfs filesystem). Mounted devfs on /dev Freeing init memory: 60K mount /etc as ramfs re-create the /etc/mtab entries init started: BusyBox v1.00 (2005.06.09-02:02+0000) multi-call binary Starting pid 17, console /dev/console: '/etc/init.d/rcS' Embest Embedded Linux Development Paltform. Default board ip: 192.192.192.190 To change the ip addr: ifconfig eth0 new_board_ip Start the web server: http://(board_ip)/index.htm
To connect the NFS server, please type like: mkdir /etc/var/nfs mount -t nfs nfs_server_ip:/home/app /etc/var/nfs -o nolock To use the USB disc(insert first), please type like: mount /dev/sda /mnt/udisk _OR_ mount /dev/sda1 /mnt/udisk
Please press Enter to activate this console. Starting pid 42, console /dev/console: '/bin/sh' ~ # ls bin etc linuxrc proc tmp var dev lib mnt sbin usr ~ #
|
一切正常。
|