|
|||
http://www.eetop.com.cn/cgi-bin/topic.cgi?forum=18&topic=1329 uboot 在 ARM s3c2410 上移植過程 總述 u-boot是德國DENX小組的開發用於多種嵌入式CPU的bootloader程序,在LINUX下可以通過CVS來得到當前正在開發的u-boot軟件。當前版本號:u-boot 1.0.2,見include/version.h中的定義。 #cvs –dserver:[email protected]:/cvsroot/u-boot login #cvs –z3 –d server:[email protected]:/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處。 |
|