总述
u-boot是德国DENX小组的开发用于多种嵌入式CPU的bootloader程序,在LINUX下能够经过CVS来得到当时正在开发的u-boot软件。当时版本号:u-boot 1.0.2,见include/version.h中的界说。
#cvs –dserver:anonymous@cvs.sourceforge.net:/cvsroot/u-boot login
#cvs –z3 –d server:anonymous@cvs.sourceforge.net:/cvsroot/u-boot checkout –P u-boot
本文叙述S3C2410中u-boot的移植进程:S3C2410的硬件装备是:
l CPU:S3C2410
l NOR: 16M,INTEL EP28F128J3A
l SDRAM:64M, MICRON 48LC16M16A2-75 B
l DM9000AVICOM (10/100M) 网卡
l USB HOST一个
装备自已的主板
l 阅览Makefile文件,在Makefile文件中添加两行:
s3c2410_config: unconfig
@./mkconfig $(@:_config=) arm arm920t s3c2410
其间ARM是CPU的品种, arm920t是ARM CPU对应的代码目录,s3c2410是自已主板对应的目录。
l 在board目录中树立s3c2410目录,smdk2410目录中的内容(cp smdk2410/* s3c2410)。
l 在include/configs/目录下smdk2410.h(cp smdk2410.h s3c2410.h)
l 修正ARM编译器的目录名及前缀
自己ARM编译器的目录是在:/opt/host/armv4l/bin/armv4l-unknown-linux-
把CROSS-COMPILE = arm-linux- 改为实践目录:如
CROSS-COMPILE = /opt/host/armv4l/bin/arm4l-unknown-linux-
l 完结之后,能够测验一下你的装备:
#make s3c2410_config
#make
编译应该在processor.h中犯错
l 修正processor.h中:
union debug_insn
{
u32 arm;
u16 thumb;
}
修正成:
union debug_insn
{
u32 arm_mode;
u16 thumb_mode;
}
l 编译成功,编译好的程序同smdk2410相同。
l 注:假如榜首次修正后编译没有在processor.h中犯错,而在examples目录犯错,仔细查看以上修正(修正的内容不正确),并在 examples目录中运转touch指令(不运转touch还会犯错,或许uboot Makefile没有写好,没查原因),再编译。
生成最基本的u-boot, 没有功用,只能起动
l 修正程序衔接地址:
在board/s3c2410中有一个config.mk文件,用于设置程序衔接的开端地址,由于会在u-boot中添加功用,所以留下6M的空间,修正33F80000为33A00000。
l 为了今后能用uboot的GO指令履行修正过的用loadb或tftp下载的u-boot:在board/s3c2410的memsetup.S中符号符”0:”上参加五句:
l mov r3, pc
l ldr r4, =0x3FFF0000
l and r3, r3, r4 //以上三句得到实践起动的内存地址
l aad r0, r0, r3 //用GO指令调试uboot时,发动地址在RAM
l add r2, r2, r3 //把初始化内存信息的地址,加上实践起动地址
u 0符号符0, 本来存在的符号符)
l 用SJF软件经过jtag口下载编译的u-boot, 发动!读取环境块时CRC犯错,然后进入SMDK#。
l 把MIZI vivi中的PrintHexWord, PrintWord拷过来,这样能够在调试汇编时能够打印一些信息,但其间有的PrintHexNibble中有缺点,ldr r0, [r2, r0] 应改为ldrb r0, [r2, r0],这样能够在四字节对齐的体系中运用。
INTEL nor flash操作功用
l INTEL 的28F128,在board目录中找到CMI主板有此FLASH,把cmi中flash.c拷到s3c2410目录代换本来的flash.c。
l cmi中的flash.c在写入时要交流字节,所以删去它的write_short()和wirte_buff()函数,把ep7312主板目录中 flash.c的wirte_word()和wirite_buff()函数过来。把flash.c中的FLASH_BASE0_PRELIM改为 CFG_FLASH_BASE。把FLASH_BLOCK_SIZE改为0x20000,(E28F128J3A flash中块的巨细是128K)。
l 把s3c2410.h中的flash内容由本来的:
1. #define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
2. #define CFG_FLASH_BASE PHYS_FLASH_1
3. #define CONFIG_AMD_LV400 1
4. #if 0
5. #define CONFIG_AMD_LV800 1
6. #endif
7. #define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
8. #ifdef CONFIG_AMD_LV800
9. #define PHYS_FLASH_SIZE 0x00100000 /* 1MB */
10. #define CFG_MAX_FLASH_SECT (19) /* max number of sectors on one chip */
11. #define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x0F0000) /* addr of environment */
12. #endif
13. #ifdef CONFIG_AMD_LV400
14. #define PHYS_FLASH_SIZE 0x00080000 /* 512KB */
15. #define CFG_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
16. #define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x070000)
改为:
1. #define PHYS_FLASH_1 0x00000000 /* Flash Bank #1 */
2. #define PHYS_FLASH_SIZE 0x01000000 /* 16 MB */
3. ##define CFG_FLASH_PROTECTION
4. define CFG_FLASH_BASE PHYS_FLASH_1
5. #define CFG_MONITOR_BASE PHYS_FLASH_1
6. #define CFG_MAX_FLASH_BANKS 1/* max number of memory banks */
7. #define CFG_MAX_FLASH_SECT 128/* max number of sectors on one chip */
8. #define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
9. #define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
10. #define CFG_ENV_IS_IN_FLASH 1
11. #define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x60000)
12. #define CFG_ENV_SIZE 0x20000 /* Total Size of Environment Sector */
l 把cmd_mem.c中的cmd_get_data_size函数的default_size全改为1, 默许以字节显现,更直观,而且不会呈现地址对齐错(data abort)。而在do_mem_mw()及mod_mem()中参加:
if(addr2info(addr) != NULL)
{
printf(“can’t wirte or modify in flash! Use cp instead./n”);
return 0;
}
以使mw和mm指令不能修正flash中的数据,而只敞开cp修正flash中的数据。
l 改board/s3c2410/flash.c中的flash_erase(),把start = get_timer(0)移到for(), 以去掉flash_erase timeout 过错。
设置FLASH和SDRAM时序
依据28F128J3A-150,这是一150ns的flash, 所以把flash时序设为最慢。把s3c2410设成202.8MHZ, 而且作业在异步形式, 修正memsetup.S。
完成网卡功用
自己的网卡是DM9000,在uboot中没有相应的驱动,所以自已写了一个网卡驱动。
1. 把驱动拷到drivers/dm9000.c
2. 在drivers/Makefile中参加dm9000.o
3. 在lib_arm/board.c中修正CS8900=>DM9000
4. 在include/configs/s3c2410中参加以下几句
#define CONFIG_DRIVER_DM9000 1 /* we have a CS8900 on-board */
#define DM9000_BASE 0x08000000
#define DM9000_BUS16 1 /* the Linux driver does accesses as shorts */
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.2.120
#define CONFIG_SERVERIP 192.168.2.122
完成USB功用
1. 在include/configs/s3c2410中的CONFIG_COMMANDS中参加:
l CFG_CMD_USB |/
l CFG_CMD_FAT |/
2. 并在文件中参加以下设置:
l #define CONFIG_USB_OHCI
l #define CONFIG_USB_STORAGE
l #define CONFIG_USB_KEYBOARD
l #define CONFIG_DOS_PARTITION
l #define CFG_DEVICE_DEREGISTER
l #define CONFIG_SUPPORT_VFAT
l #define LITTLEENDIAN
3. 这时usb start 和 usb info等功用正常,而其它一些功用不正常。
4. 功用fatls 不正常,修正fs/fat/fat.c
l 没有把VFAT的UNICODE字符转化过来,参加UNICODE字符转化函数。Uni2ansi(), 添加slot2str()的cp936版, 添加一个toshort()。
l 参加#define cp936
l 在fat_getenv()中有一个对齐过错,修正fat.h使fatbuff字对齐。
l 在do_fat_read()中参加两句,以消除列根目录过错。
l 在board/cmd_fat.c中参加两句,以消除没有usb storage设备时的过错:
if(!dev_desc)
printf(“Not init storage usb device:/n usb start/n usb info/n usb scan/n”);
5. 修正fs/fat/fat.c
get_cluster()函数中参加 if(size / FS_BLOCK_SIZE > 0), 以防读文件时不能成功读出。
引导LINUX
现在咱们能够引导LINUX了。
l 要引导bzip2的linux核,把CFG_MALLOC_SIZE改为大于4M
l 把编译好的LINUX内存,经过uboot/tools/mkimage转化成uboot格局
1. mkimage -A arm -O linux -T kernel -C bzip2 -a 30000000 -e 30008000 -n linux kernel -d vmlinux1.bz2 c
2. mkimage -A arm -O linux -T kernel -C gzip -a 30000000 -e 30008000 -n linux kernel -d vmlinux.gz b
3. mkimage -A arm -O linux -T ramdisk -C gzip -a 0 -e 0 -n init ramdisk -d ramdisk.image.gz ramdisk
l 在include/configs/s3c2410.h中参加:
1. #define CONFIG_BOOTARGS “initrd=0x30800000,0x200000 root=/dev/ram init=/linuxrc console=ttyS0,115200”
2. #define CONFIG_BOOTFILE “vmlinux_for_uboot.gz”
3. #define CONFIG_BOOTCOMMAND “bootm 0x80000 0x1a0000”
0x80000为内核在flash中的方位。
0x1a0000为ramdisk.image.gz在flash中的内容。
4. #define CFG_LOAD_ADDR 0x30800000 /* default load address */
l 在lib_arm/armlinux.c的do_bootm_linux中参加:
1. memcpy ((char *)CFG_LOAD_ADDR, (char *)data, len);
2. data = CFG_LOAD_ADDR;
把ramdisk到0x30800000方位的RAM中
3. 界说以下装备,把信息传入LINUX中心的TAG区
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
#define CONFIG_CMDLINE_TAG
常用U-BOOT指令介绍
1. ?得到一切指令列表
2. help: help usb, 列出USB功用的运用说明
3. ping:注:只能开发板PING其他机器
4. setenv: 设置互环境变量:
5. setenv serverip 192.168.0.1
6. setenv ipaddr 192.168.0.56
7. setenv bootcmd ‘tftp 32000000 vmlinux; kgo 32000000’
8. saveenv: 保存环境变量
9. 在设置好环境变量今后, 保存变量值
10. tftp: tftp 32000000 vmlinux, 把server(IP=环境变量中设置的serverip)中/tftpdroot/ 下的vmlinux经过TFTP读入到物理内存32000000处。
11. kgo: 起动没有紧缩的linux内核,kgo 32000000
12. bootm:起动UBOOT TOOLS制造的紧缩LINUX内核, bootm 3200000
13. protect: 对FLASH进行写维护或撤销写维护, protect on 1:0-3(便是对榜首块FLASH的0-3扇区进行维护),protect off 1:0-3撤销写维护
14. erase: 删去FLASH的扇区, erase 1:0-2(便是对每一块FLASH的0-2扇区进行删去)
15. cp: 在内存中内容, cp 32000000 0 40000(把内存中0x32000000开端的0x40000字节到0x0处)
16. mw: 对RAM中的内容写操作, mw 32000000 ff 10000(把内存0x32000000开端的0x10000字节设为0xFF)
17. md: 修正RAM中的内容, md 32000000(内存的开端地址)
18. usb:
l usb start: 起动usb 功用
l usb info: 列出设备
l usb scan: 扫描usb storage(u 盘)设备
19. fatls:列出DOS FAT文件体系, 如:fatls usb 0列出榜首块U盘中的文件
20. fatload: 读入FAT中的一个文件,如:fatload usb 0:0 32000000 aa.txt
21. 把USB中的aa.txt 读到物理内存0x32000000处!
22. flinfo: 列出flash的信息
23. loadb: 准备用KERMIT协议接纳来自kermit或超级终端传送的文件。
24. nfs: nfs 32000000 192.168.0.2:aa.txt , 把192.168.0.2(LINUX 的NFS文件体系)中的NFS文件体系中的aa.txt 读入内存0x32000000处。