移植环境
1,主机环境:VMare下CentOS 5.5 ,1G内存。
2,集成开发环境:Elipse IDE
3,编译编译环境:arm-linux-gcc v4.4.3,arm-none-eabi-gcc v4.5.1。
4,开发板:mini2440,2M nor flash,128M nand flash。
5,u-boot版本:u-boot-2009.08
6,参考文章:
8.1,实现u-boot的usb slave下载功能
友善自带的dnw下的usb下载功能真的很好用,于是也想实现此功能,现参考博文为u-boot-2009.08 添加 dnw usb下载功能,操作如下(红色字体部分为修改或添加的代码):
【1】复制usb slave驱动源代码,源码下载uboot-usb_slave.tar.bz2 下载在 http://www.linuxidc.net/thread-2238-1-1.html
下载后将源码解压到u-boot-2009.08/drivers/usb/目录下:
[root@localhost ~]# cd ./u-boot-test/u-boot-2009.08/drivers/usb
[root@localhost usb]# tar -jxf /root/100109001526.bz2
[root@localhost usb]# ls
gadget host musb slave
[root@localhost usb]#
【2】用gedit打开u-boot-2009.08/Makefile,定位到243行附近,修改如下:
LIBS += drivers/usb/host/libusb_host.a
LIBS += drivers/usb/musb/libusb_musb.a
LIBS += drivers/usb/slave/libusb_slave.a
LIBS += drivers/video/libvideo.a
【3】打开/lib_arm/board.c,定位到423行附近,修改如下:
#if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
misc_init_r ();
#endif
extern void port_init(void);
port_init();
/* enable exceptions */
enable_interrupts ();
#if defined(CONFIG_USB_DEVICE)
extern int usb_init_slave(void);
usb_init_slave();
#endif
/* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_TI_EMAC
这里要强调下hugerat 博主说得很对,usb_init() 应改为 usb_init_slave()。详情请参见mini2440 实现u-boot的usb slave下载功能。
【4】打开/include/configs/mini2440.h,定位到48行附近,注释掉下面代码:
#define USE_920T_MMU 1
//#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
定位到173行附近,加入如下代码:
/* valid baudrates */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
#define CONFIG_SYS_CONSOLE_IS_IN_ENV //It's important to serial console !
//Define this if you want stdin, stdout &/or stderr to be set to usbtty
/*
USB device support
*/
#define CONFIG_USB_DEVICE 1
#ifdef CONFIG_USB_DEVICE
#define CONFIG_USE_IRQ 1
#endif
/*-----------------------------------------------------------------------
* Stack sizes
注意,#define CONFIG_SYS_CONSOLE_IS_IN_ENV 配置非常重要,不配置此项,只能看到控制台信息在LCD上的显示,而在串口终端没有输出!
【5】打开/cpu/arm920t/s3c24x0/interrupts.c,定位到文件末尾处添加arch_interrupt_init函数定义:
void do_irq (struct pt_regs *pt_regs)
{
S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT();
u_int32_t intpnd = irq->INTPND;
}
int arch_interrupt_init (void)
{
return 0;
}
【6】/cpu/arm920t/start.S,定位到625行附近,加入下面代码:
#ifdef CONFIG_USE_IRQ
.align 5
irq:
/*
get_irq_stack
irq_save_user_regs
bl do_irq
irq_restore_user_regs
*/
/* use IRQ for USB and DMA */
sub lr, lr, #4 @ the return address
ldr sp, IRQ_STACK_START @ the stack for irq
stmdb sp!, { r0-r12,lr } @ save registers
ldr lr, =int_return @ set the return addr
ldr pc, =IRQ_Handle @ call the isr
int_return:
ldmia sp!, { r0-r12,pc }^ @ return from interrupt
.align 5
fiq:
get_fiq_stack
/* someone ought to write a more effiction fiq_save_user_regs */
irq_save_user_regs
bl do_fiq
irq_restore_user_regs
#else
【7】打开/include/s3c24x0.h,定位到330行附近,修改如下:
S3C24X0_REG8 MAXP_REG;
S3C24X0_REG8 res10[3]; //S3C24X0_REG8 res10[7];
S3C24X0_REG8 EP0_CSR_IN_CSR1_REG;
S3C24X0_REG8 res11[3];
S3C24X0_REG8 IN_CSR2_REG;
S3C24X0_REG8 res12[7]; //S3C24X0_REG8 res12[3];
S3C24X0_REG8 OUT_CSR1_REG;
S3C24X0_REG8 res13[3]; //S3C24X0_REG8 res13[7];
S3C24X0_REG8 OUT_CSR2_REG;
S3C24X0_REG8 res14[3];
S3C24X0_REG8 OUT_FIFO_CNT1_REG;
S3C24X0_REG8 res15[3];
S3C24X0_REG8 OUT_FIFO_CNT2_REG;
S3C24X0_REG8 res16[3];
#endif /* __BIG_ENDIAN */
//S3C24X0_USB_DEV_FIFOS fifo[5];
//S3C24X0_USB_DEV_DMAS dma[5];
S3C24X0_REG32 res17[8];
S3C24X0_USB_DEV_FIFOS fifo[5];
S3C24X0_REG32 res18[11];
S3C24X0_USB_DEV_DMAS ep1;
S3C24X0_USB_DEV_DMAS ep2;
S3C24X0_REG8 res19[16];
S3C24X0_USB_DEV_DMAS ep3;
S3C24X0_USB_DEV_DMAS ep4;
} /*__attribute__((__packed__))*/ S3C24X0_USB_DEVICE;
【8】添加usbslave命令
在/common/目录下创建文件cmd_usbslave.c,然后将下面内容粘贴进去:
#include
#include
#include
#ifdef CONFIG_USB_DEVICE
#ifdef CONFIG_USE_IRQ
#define IRQ_STACK_START (_armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4)
#define FIQ_STACK_START (IRQ_STACK_START - CONFIG_STACKSIZE_IRQ)
#define FREE_RAM_END (FIQ_STACK_START - CONFIG_STACKSIZE_FIQ - CONFIG_STACKSIZE)
#define FREE_RAM_SIZE (FREE_RAM_END - PHYS_SDRAM_1)
#else
#define FREE_RAM_END (_armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4 - CONFIG_STACKSIZE)
#define FREE_RAM_SIZE (FREE_RAM_END - PHYS_SDRAM_1)
#endif
int g_bUSBWait = 1;
u32 g_dwDownloadLen = 0;
extern int download_run;
extern volatile unsigned int dwUSBBufBase;
extern volatile unsigned int dwUSBBufSize;
extern __u32 usb_receive(char *buf, size_t len, unsigned int 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时表示将文件保存在USB Host发送工具dnw指定的位置
* download_run为0时表示将文件保存在参数argv[2]指定的位置
* 要下载程序到内存,然后直接运行时,要设置download_run=1,这也是这个参数名字的来由
*/
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%sn", 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 transferringn"
);
#endif
打开/common/Makefile,定位到163行,加入下面代码:
# others
COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o
COBJS-$(CONFIG_HWCONFIG) += hwconfig.o
COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
COBJS-y += flash.o
COBJS-$(CONFIG_CMD_KGDB) += kgdb.o
COBJS-$(CONFIG_KALLSYMS) += kallsyms.o
COBJS-$(CONFIG_LCD) += lcd.o
COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
COBJS-$(CONFIG_UPDATE_TFTP) += update.o
COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
COBJS-$(CONFIG_USB_DEVICE) += cmd_usbslave.o
COBJS := $(sort $(COBJS-y))
【9】打开/include/s3c2410.h,定位到198行附近,加入下面代码:
#define BIT_TICK (0x1<<8)
#define BIT_WDT (0x1<<9)
#define BIT_WDT_AC97 (0x1<<9)
#define BIT_TIMER0 (0x1<<10)
#define BIT_TIMER1 (0x1<<11)
【10】编译报错:undefined reference to `udc_disconnect'
打开/lib_arm/bootm.c定位到124行,udc_disconnect ();此句也要注释掉:
/* we assume that the kernel is in place */
printf ("nStarting kernel ...nn");
#ifdef CONFIG_USB_DEVICE
{
extern void udc_disconnect (void);
//udc_disconnect ();
}
#endif
否则编译报错。