u-boot-2010.03在LT2440上的移植详解 (七)
郑重声明,这系列文章改写自博客园 黄刚先生的《嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解》
转载时请注明出处
文章出处:
http://www.lt-net.cn
编译系统
Ubuntu10.04
交叉编译器
arm-linux-gcc 4.3.3
硬件设备
LT2440开发板
测试软件
u-boot-2010.03
依赖库
无
uboot下载地址:
http://ftp.denx.de/pub/u-boot/u-boot-2010.03.tar.bz2本次移植在u-boot-2010.03原有功能的基础上增加如下特性:
1.支持2KB page Nand Flash读写
2.支持Nand/Nor Flash启动自动识别
3.支持DM9000AEP 10M/100M自适应网卡
4.支持yaffs文件系统烧写
5.支持USB下载功能
6.支持一键式菜单
7.支持启动Logo
8.支持ubifs(待续)
上接:u-boot-2010.03在LT2440上的移植详解 (六)
USB 驱动的移植比较麻烦,它涉及到S3C2440的中断,还有 S3C2440 USB device的驱动首先我们增加USB device的驱动,驱动有19个文件,
请到下面的链接下载
http://blogimg.chinaunix.net/blog/upfile2/101209120345.bz2解压之后会有一个device目录,请将这个目录放到 drivers/usb目录下
修改根目录下Makefile ,加入USB device 驱动的编译支持
#gedit Makefile //根目录下Makefile
LIBS += drivers/usb/phy/libusb_phy.a
LIBS += drivers/usb/device/libusb_device.a //大约244行
LIBS += drivers/video/libvideo.a
LIBS += drivers/watchdog/libwatchdog.a
还需要一个数据类型定义文件,内容如下,请保存为
def.h 文件,放到
include 目录下
- #ifndef __DEF_H__
- #define __DEF_H__
- #ifndef U32
- #define U32 unsigned int
- #endif
- #ifndef U16
- #define U16 unsigned short
- #endif
- #ifndef S32
- #define S32 int
- #endif
- #ifndef S16
- #define S16 short int
- #endif
- #ifndef U8
- #define U8 unsigned char
- #endif
- #ifndef S8
- #define S8 char
- #endif
- typedef unsigned char BOOL;
- typedef unsigned char UCHAR;
- typedef UCHAR *PUCHAR;
- typedef unsigned long DWORD;
- typedef DWORD *PDWORD;
- typedef unsigned long LDWORD;
- typedef DWORD *LPDWORD;
- typedef unsigned char BYTE;
- typedef unsigned short WORD;
- typedef unsigned long ULONG;
- typedef ULONG *PULONG;
- typedef unsigned short USHORT;
- typedef USHORT *PUSHORT;
- typedef BYTE *LPBYTE;
- typedef void *PVOID;
- typedef char* LPSTR;
- #ifndef NULL
- #define NULL 0
- #endif
- #define TRUE 1
- #define FALSE 0
- #endif /*__DEF_H__*/
复制代码
现在 include/configs/lt2440.h 添加一个使能USB设备的宏定义并且使能中断。
#gedit
include/configs/lt2440.h
#define USE_920T_MMU 1 #define CONFIG_USB_DEVICE 1
#ifdef CONFIG_USB_DEVICE
#define CONFIG_USE_IRQ 1
#endif
修改u-boot关于s3c2440的中断的文件,使其适应LT2440板子要求
gedit cpu/arm920t/s3c24x0/interrupts.c
#gedit cpu/arm920t/s3c24x0/interrupts.c
#if 0
#include
#include
#include void do_irq (struct pt_regs *pt_regs)
{
struct s3c24x0_interrupt *irq = s3c24x0_get_base_interrupt();
u_int32_t intpnd = readl(&irq->INTPND);}
#endif
#gedit lib_arm/interrupts.c
int interrupt_init (void)
{
/*
* setup up stacks if necessary
*/
#ifdef CONFIG_USE_IRQ
IRQ_STACK_START = _armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4;
FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
FREE_RAM_END = FIQ_STACK_START - CONFIG_STACKSIZE_FIQ - CONFIG_STACKSIZE;
FREE_RAM_SIZE = FREE_RAM_END - PHYS_SDRAM_1;
#else
FREE_RAM_END = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4 - CONFIG_STACKSIZE;
FREE_RAM_SIZE = FREE_RAM_END - PHYS_SDRAM_1;
#endif return 0 ;// return arch_interrupt_init();
}
上面有两个宏没有声明也没有定义FREE_RAM_END , FREE_RAM_SIZE 下面给出声明和定义
#gedit include/asm-arm/u-boot-arm.h
extern ulong IRQ_STACK_START; /* top of IRQ stack */
extern ulong FIQ_STACK_START; /* top of FIQ stack */
extern ulong FREE_RAM_END; /* top of free ram */
extern ulong FREE_RAM_SIZE; /* size of free ram */
#gedit cpu/arm920t/start.S
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start
_bss_start:
.word __bss_start
.globl _bss_end
_bss_end:
.word _end
.globl FREE_RAM_END
FREE_RAM_END:
.word 0x0badc0de
.globl FREE_RAM_SIZE
FREE_RAM_SIZE:
.word 0x0badc0de
#gedit lib_arm/bootm.c
#ifdef CONFIG_USB_DEVICE
{
extern void udc_disconnect (void);
// udc_disconnect (); //注释掉这一行
}
#endif
#gedit lib_arm/board.c
/* enable exceptions */ // 约388行
Port_Init();
enable_interrupts ();
usb_init();
这些做好了之后,USB驱动已经可以正常加载了,下面加入USB下载的命令
#gedit common/cmd_usbslave.c
#include
#include
#include
#include
#ifdef CONFIG_USB_DEVICE
int g_bUSBWait = 1;
u32 g_dwDownloadLen = 0;
extern int download_run;
extern volatile U32 dwUSBBufBase;
extern volatile u32 dwUSBBufSize;
extern __u32 usb_receive(char *buf, size_t len, U32 wait);
int do_usbslave (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int i;
size_t len = ~0UL;
char buf[32];
download_run = 1;
switch (argc) {
case 1:
{
break;
}
case 2:
{
g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
break;
}
case 3:
{
g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
load_addr = simple_strtoul(argv[2], NULL, 16);
download_run = 0;
break;
}
default:
{
printf ("Usage:/n%s/n", cmdtp->usage);
return 1;
}
}
dwUSBBufBase = load_addr;
dwUSBBufSize = (FREE_RAM_SIZE&(~(0x80000-1)));
if (g_bUSBWait)
len = FREE_RAM_SIZE;
g_dwDownloadLen = usb_receive(dwUSBBufBase, len, g_bUSBWait);
sprintf(buf, "%X", g_dwDownloadLen);
setenv("filesize", buf);
return 0;
}
U_BOOT_CMD(
usbslave, 3, 0, do_usbslave,
"usbslave - get file from host(PC)/n",
"[wait] [loadAddress]/n"
"/"wait/" is 0 or 1, 0 means for return immediately, not waits for the finish of transferring/n"
);
#endif
修改common目录下Makefile
#gedit common/Makefile
//在约155行加入下面一句
COBJS-y += cmd_usbslave.o
s3c2440 USB控制器与s3c2410有区别,还有多了一个GPIO口 J 口,安装下面修改,增加支持
#gedit include/asm-arm/arch-s3c24x0/s3c24x0.h
struct s3c24x0_usb_device {
#ifdef __BIG_ENDIAN
u8 res1[3];
u8 FUNC_ADDR_REG;
u8 res2[3];
u8 PWR_REG;
u8 res3[3];
u8 EP_INT_REG;
u8 res4[15];
u8 USB_INT_REG;
u8 res5[3];
u8 EP_INT_EN_REG;
u8 res6[15];
u8 USB_INT_EN_REG;
u8 res7[3];
u8 FRAME_NUM1_REG;
u8 res8[3];
u8 FRAME_NUM2_REG;
u8 res9[3];
u8 INDEX_REG;
u8 res10[7];
u8 MAXP_REG;
u8 res11[3];
u8 EP0_CSR_IN_CSR1_REG;
u8 res12[3];
u8 IN_CSR2_REG;
u8 res13[7];
u8 OUT_CSR1_REG;
u8 res14[3];
u8 OUT_CSR2_REG;
u8 res15[3];
u8 OUT_FIFO_CNT1_REG;
u8 res16[3];
u8 OUT_FIFO_CNT2_REG;
#else /* little endian */
u8 FUNC_ADDR_REG;
u8 res1[3];
u8 PWR_REG;
u8 res2[3];
u8 EP_INT_REG;
u8 res3[15];
u8 USB_INT_REG;
u8 res4[3];
u8 EP_INT_EN_REG;
u8 res5[15];
u8 USB_INT_EN_REG;
u8 res6[3];
u8 FRAME_NUM1_REG;
u8 res7[3];
u8 FRAME_NUM2_REG;
u8 res8[3];
u8 INDEX_REG;
u8 res9[7];
u8 MAXP_REG;
u8 res10[3];
u8 EP0_CSR_IN_CSR1_REG;
u8 res11[3];
u8 IN_CSR2_REG;
u8 res12[7];
u8 OUT_CSR1_REG;
u8 res13[3];
u8 OUT_CSR2_REG;
u8 res14[3];
u8 OUT_FIFO_CNT1_REG;
u8 res15[3];
u8 OUT_FIFO_CNT2_REG;
u8 res16[3];
#endif /* __BIG_ENDIAN */
u32 res17[8];
struct s3c24x0_usb_dev_fifos fifo[5];
u32 res18[11];
struct s3c24x0_usb_dev_dmas ep1;
struct s3c24x0_usb_dev_dmas ep2;
u8 res19[16];
struct s3c24x0_usb_dev_dmas ep3;
struct s3c24x0_usb_dev_dmas ep4;
};
//增加J口支持
/* I/O PORT (see manual chapter 9) */
struct s3c24x0_gpio {
#ifdef CONFIG_S3C2400
u32 PACON;
u32 PADAT;
u32 PBCON;
u32 PBDAT;
u32 PBUP;
u32 PCCON;
u32 PCDAT;
u32 PCUP;
u32 PDCON;
u32 PDDAT;
u32 PDUP;
u32 PECON;
u32 PEDAT;
u32 PEUP;
u32 PFCON;
u32 PFDAT;
u32 PFUP;
u32 PGCON;
u32 PGDAT;
u32 PGUP;
u32 OPENCR;
u32 MISCCR;
u32 EXTINT;
#endif
#ifdef CONFIG_S3C2410
u32 GPACON;
u32 GPADAT;
u32 res1[2];
u32 GPBCON;
u32 GPBDAT;
u32 GPBUP;
u32 res2;
u32 GPCCON;
u32 GPCDAT;
u32 GPCUP;
u32 res3;
u32 GPDCON;
u32 GPDDAT;
u32 GPDUP;
u32 res4;
u32 GPECON;
u32 GPEDAT;
u32 GPEUP;
u32 res5;
u32 GPFCON;
u32 GPFDAT;
u32 GPFUP;
u32 res6;
u32 GPGCON;
u32 GPGDAT;
u32 GPGUP;
u32 res7;
u32 GPHCON;
u32 GPHDAT;
u32 GPHUP;
u32 res8;
u32 MISCCR;
u32 DCLKCON;
u32 EXTINT0;
u32 EXTINT1;
u32 EXTINT2;
u32 EINTFLT0;
u32 EINTFLT1;
u32 EINTFLT2;
u32 EINTFLT3;
u32 EINTMASK;
u32 EINTPEND;
u32 GSTATUS0;
u32 GSTATUS1;
u32 GSTATUS2;
u32 GSTATUS3;
u32 GSTATUS4;
#if defined (CONFIG_S3C2440)
u32 res9[3];
u32 MSLCON;
u32 GPJCON;
u32 GPJDAT;
u32 GPJUP;
#endif
#endif
};
#gedit include/asm-arm/arch-s3c24x0/s3c24x0.h
//在文件末尾增加下面定义
#define _ISR_STARTADDRESS ((unsigned)isr_handle_array)
#define ISR_EINT0_OFT 0
#define ISR_EINT1_OFT 1
#define ISR_EINT2_OFT 2
#define ISR_EINT3_OFT 3
#define ISR_EINT4_7_OFT 4
#define ISR_EINT8_23_OFT 5
#define ISR_NOTUSED6_OFT 6
#define ISR_BAT_FLT_OFT 7
#define ISR_TICK_OFT 8
#define ISR_WDT_OFT 9
#define ISR_TIMER0_OFT 10
#define ISR_TIMER1_OFT 11
#define ISR_TIMER2_OFT 12
#define ISR_TIMER3_OFT 13
#define ISR_TIMER4_OFT 14
#define ISR_UART2_OFT 15
#define ISR_LCD_OFT 16
#define ISR_DMA0_OFT 17
#define ISR_DMA1_OFT 18
#define ISR_DMA2_OFT 19
#define ISR_DMA3_OFT 20
#define ISR_SDI_OFT 21
#define ISR_SPI0_OFT 22
#define ISR_UART1_OFT 23
#define ISR_NOTUSED24_OFT 24
#define ISR_USBD_OFT 25
#define ISR_USBH_OFT 26
#define ISR_IIC_OFT 27
#define ISR_UART0_OFT 28
#define ISR_SPI1_OFT 29
#define ISR_RTC_OFT 30
#define ISR_ADC_OFT 31
#endif /*__S3C2410_H__*/
#gedit cpu/arm920t/s3c24x0/Makefile
//注释掉如下两行,它与USB device 驱动冲突
COBJS-y += speed.o
COBJS-y += timer.o
#COBJS-y += usb.o
#COBJS-y += usb_ohci.o
重新编译,重新烧写u-boot。重启LT2440开发板,可以使用 usbslave 命令传输文件了
有两个格式:
# usbslave //下载到板子内存的地址由DNW决定
# usbslave 1
0x30000000 //下载到板子内存的地址由后面的地址参数决定
打开DNW,可以发现USB已经OK了

下面使用usbslave命令做测试,下载Linux内核
LT2440 #
usbslave 1 0x30000000
USB host is connected. Waiting a download.
Now, Downloading [ADDRESS:30000000h,TOTAL:2223646]
RECEIVED FILE SIZE: 2223646 (723KB/S, 3S)
LT2440 #
说明USB功能调试成功,可以使用USB device传输数据了
下接:u-boot-2010.03在LT2440上的移植详解 (八)