博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

Tekkaman Ninja

Linux我的梦想,我的未来! 专注linux内核和驱动!本博客的原创文章的内容会不定期更新或修正错误! 转载文章都会注明出处,若有侵权,请即时同我联系,我一定马上删除!! 原创文章版权所有!如需转载,请注明出处: tekkman.cublog.cn ,谢谢合作!!!!!
  tekkman.cublog.cn

关于作者
姓名:Tekkaman  Ninja
职业:ARM9+Linux
年龄:25
位置:福建龙岩
个性介绍:钻研嵌入式Linux技术
E-Mail:tekkamanninja@163.com
|| << >> ||
我的分类


移植U-Boot.1.2.0到博创2410-S(S3C2410A)补:AX88796驱动移植
移植U-Boot.1.2.0到博创2410-S(S3C2410A)
补:AX88796驱动移植
 引言:
     一个Bootloader没有tftp的支持,那么移植内核实在是痛苦的事。因为你要不断的用串口烧写内核到SDRAM里,时间少则2分多钟,多则4分多钟,错了还要重烧!在实现这个驱动前,我用U-Boot就是这么痛苦。
    在移植完Linux2.6.22.2的AX88796的驱动之后,我决心一定要把AX88796移植到U-Boot上,一劳永逸。借助移植Linux下的AX88796的经验,我首先看懂了/drivers下的ne2000.c的驱动,再参考了一些RTL8019的移植记录(都是NE2000兼容网卡),在痛苦了三四天后,驱动成功,ping和tftp成功,高兴得差点跳起来!以下介绍驱动的移植和U-Boot下网卡驱动移植、编写的一般方法。


本次驱动移植的参考资料:
1、AX88796L Datasheet
2、《NE2000 网卡芯片驱动程序》巨龙公司系统集成开发部 杨屹 2002/10/20
3、《REALTEK8019as 芯片资料翻译》也就是RTL8019网卡的中文资料
4、
zcx3000的关于网卡驱动的一系列文章,特别对于网卡初始化的顺序讲解的很细,必看。URL:http://blog.csdn.net/zcx3000/category/237774.aspx
5、
《嵌入式系统接口设计与Linux驱动程序开发》(刘淼 编著)第十五章:以太网接口与Linux网络驱动程序设计
6、《ARM嵌入式常用模块与综合系统设计实例精讲》 张绮文 谢建雄 谢劲心 编著 电子工业出版社  第16章 以太网控制器模块设计


 U-Boot下网卡驱动框架:
   U-Boot的
/drivers文件夹包含了许多U-Boot可能用到的驱动,其中包括:nand flash和网卡。(如果你有修改过nand flash驱动,你一定来过这。)这些驱动基本上都是最底层的硬件驱动。网卡驱动也不例外,它并不包含协议层,只实现网卡初始化、读写、停止等等功能,所以移植起来比较容易。
U-Boot网卡驱动的接口函数由以下四个函数组成:

int eth_init(bd_t *bd):完成网卡初始化的过程:热复位、相应寄存器的赋值、设置MAC地址等等
void eth_halt() :停止网卡运行
int eth_rx() :接收网络数据
int eth_send(volatile void *packet, int length) :发送数据

U-Boot在进行网络操作时,调用的就是这四个函数。所以移植时,只要集中精力在这四个函数,使它们对网卡的操作是正确的,移植就成功了。知道以上的知识,再学习一些网卡和网络的知识,看看成功的网卡驱动,要是以后出现U-boot不支持的网卡,也可以自己写驱动了!

U-Boot下AX88796网卡移植过程
    U-Boot下的AX88796网卡(NE2000寄存器兼容)驱动是使用NE2000的驱动,用到的文件是在/drivers文件夹下的8390.hne2000.cne2000.h

    首先说明一个关键问题,U-Boot的NE2000驱动是为8位总线写的,而博创的2410-S实验箱的AX88796的硬件连接适合16位总线的网卡驱动。所以必须将NE2000驱动该写成16位总线的驱动。(也许你会想:我也可以把2410的总线宽度改成8位,来使用8位的驱动。但是请你注意看看AX88796的数据手册的第51页和实验箱原理图的网卡部分,你就会知道:即使你用8位的驱动,你也必须使用16位 的总线,而且数据会处理更加麻烦。)还有就是没有修改过的驱动有BUG,没有修正是无法正常使用的。


 (1)修改
ne2000.c
......
#define DEBUG 0


#if DEBUG & 1
#define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0)
#define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0)
#else
#define DEBUG_FUNCTION() do {} while(0)
#define DEBUG_LINE() do {} while(0)
#endif

#include "ne2000.h"
//将8390的头文件上移到此,因为前面就要用到
#include "8390.h"

#if DEBUG & 1
#define PRINTK(args...) printf(args)
#else
#define PRINTK(args...)
#endif

static dp83902a_priv_data_t nic; /* just one instance of the card supported */

//添加从U-Boot的参数区读取MAC地址的函数
static int
ne2000_read_mac_addr(unsigned char * enaddr)
{
    int ii;
    char *s, *e;

    s = getenv ("ethaddr");
    if (s == NULL){
        return -1;
    }
    else{
        for(ii = 0; ii < 12; ii+=2) {
            enaddr[ii] =enaddr[ii+1]= s ? simple_strtoul (s, &e, 16) : 0;
            if (s){
                s = (*e) ? e + 1 : e;
            }
        }
    }
    return 0;
}
......

static void
dp83902a_start(unsigned char * enaddr)
{
    dp83902a_priv_data_t *dp = &nic;
    cyg_uint8 *base = dp->base;
    int i;

    DEBUG_FUNCTION();

    DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */
    DP_OUT(base, DP_DCR, 0x49); //将网卡的总线宽度改为16位
    DP_OUT(base, DP_RBCH, 0);        /* Remote byte count */

......

DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP);
    DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */
    DP_OUT(base, DP_RCR, DP_RCR_AB);  /* Accept broadcast, no errors, no multicast */
    DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
    dp->running = true;
}

......

static void
dp83902a_send(unsigned short *data, int total_len, unsigned long key)
{
......

    DP_OUT(base, DP_ISR, DP_ISR_RDC);  /* Clear end of DMA */
    {
        /* Dummy read. The manual sez something slightly different, */
        /* but the code is extended a bit to do what Hitachi's monitor */
        /* does (i.e., also read data). */
/*    //屏蔽无用的语句
        cyg_uint16 tmp;
        int len = 1;

        DP_OUT(base, DP_RSAL, 0x100-len);
        DP_OUT(base, DP_RSAH, (start_page-1) & 0xff);
        DP_OUT(base, DP_RBCL, len);
        DP_OUT(base, DP_RBCH, 0);
        DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START);
        DP_IN_DATA(dp->data, tmp);
*/    }

......

#if DEBUG & 4
    printf(" sg buf %08lx len %08x\n ", (unsigned long) data, len);
    dx = 0;
#endif
    while (len > 1) {
#if DEBUG & 4
        printf(" %04x", *data);
        if (0 == (++dx % 16)) printf("\n ");
#endif
        DP_OUT_DATA(dp->data, *data++);
        len-=2;
    }
#if DEBUG & 4
   
    if (len==1)     printf(" %04x", (*data)&0xff);
    printf("\n");
#endif
   
    if (len==1)     {DP_OUT_DATA(dp->data, (*data++)&0xff);    total_len++;    }

    if (total_len < pkt_len) {
#if DEBUG & 4
        printf("  + %d bytes of padding\n", pkt_len - total_len);
#endif
        /* Padding to 802.3 length was required */
        for (i = total_len;  i < pkt_len;) {
           
i+=2;
            DP_OUT_DATA(dp->data, 0);
        }
    }

......
}

/*
  This function is called when a packet has been received.  It's job is
  to prepare to unload the packet from the hardware.  Once the length of
  the packet is known, the upper layer of the driver can be told.  When
  the upper layer is ready to unload the packet, the internal function
  'dp83902a_recv' will be called to actually fetch it from the hardware.
*/
static void
dp83902a_RxEvent(void)
{
    struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic;
    cyg_uint8 *base = dp->base;
    unsigned char rsr;
    unsigned short rcv_hdr[2];
    int i, len, pkt, cur;
......
        DP_OUT(base, DP_RBCL, 4);
        DP_OUT(base, DP_RBCH, 0);
        DP_OUT(base, DP_RSAL, 0);
        DP_OUT(base, DP_RSAH, pkt);
        if (dp->rx_next == pkt) {
            if (cur == dp->rx_buf_start)
                DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
            else
                DP_OUT(base, DP_BNDRY, cur-1); /* Update pointer */
            return;
        }
        dp->rx_next = pkt;
        DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
        DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
        CYGACC_CALL_IF_DELAY_US(10);
#endif

        for (i = 0;  i < sizeof(rcv_hdr);) {
            DP_IN_DATA(dp->data, rcv_hdr[i++]);
        }

#if DEBUG & 5
        printf("rx hdr %04x %04x \n",
               rcv_hdr[0], rcv_hdr[1]);
#endif
        len = rcv_hdr[1] - 4;
        uboot_push_packet_len(len);
        if (((rcv_hdr[0] >>8)&0xff) == dp->rx_buf_start)
            DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1);
        else
            DP_OUT(base, DP_BNDRY, ((rcv_hdr[0] >>8)&0xff)-1); /* Update pointer */
    }
}

/*
  This function is called as a result of the "eth_drv_recv()" call above.
  It's job is to actually fetch data for a packet from the hardware once
  memory buffers have been allocated for the packet.  Note that the buffers
  may come in pieces, using a scatter-gather list.  This allows for more
  efficient processing in the upper layers of the stack.
*/
static void
dp83902a_recv(unsigned short *data, int len)
{
    ......

    /* Read incoming packet data */
    DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START);
    DP_OUT(base, DP_RBCL, len & 0xFF);
    DP_OUT(base, DP_RBCH, (len >> 8)& 0xFF);
    DP_OUT(base, DP_RSAL, 4);        /* Past header */
    DP_OUT(base, DP_RSAH, dp->rx_next);
    DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */
    DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START);
#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA
    CYGACC_CALL_IF_DELAY_US(10);
#endif

    saved = false;
    for (i = 0;  i < 1;  i++) {
        if (data) {
            mlen = len;
#if DEBUG & 4
            printf(" sg buf %08lx len %08x \n", (unsigned long) data, mlen);
            dx = 0;
#endif
            while (0 < mlen) {
                /* Saved byte from previous loop? */
                if (saved) {
                    *data++ = saved_char;
                    mlen--;
                    saved = false;
                    continue;
                }

                {
                    cyg_uint16 tmp;
                    DP_IN_DATA(dp->data, tmp);
#if DEBUG & 4
                    printf(" %04x", tmp);
                    if (0 == (++dx % 16)) printf("\n ");
#endif
                    *data++ = tmp;
                    mlen-=2;
                    if (mlen==1) {
                            DP_IN_DATA(dp->data, tmp);
                            tmp = tmp & 0xff;
#if DEBUG & 4
                            printf(" %04x", tmp);
#endif
                            *data++ = tmp;
                            mlen--;
                            }
                }
            }
#if DEBUG & 4
            printf("\n");
#endif
        }
    }
}

......
//添加自定义的AX88796硬件信息,在这里定义了如果网卡的MAC地址的前三个为

//0x08, 0x08, 0x08,那就是AX88796。如果你要修改MAC地址 ,
//最好前三个要和这三个一样,不然驱动会认不到网卡。

static hw_info_t hw_info[] = {
 ......
    { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
    { /* AX88796 */ 0x0ff0, 0x08, 0x08, 0x08, 0 },
    { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
......
};

......

static void pcnet_reset_8390(void)
{
    int i, r;

    PRINTK("nic base is %lx\n", nic_base);

#if 1
    n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
    PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
    n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD);
    PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
    n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
    PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD));
#endif
    n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);

    n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET);  
//低级错误,严重的BUG,没有修改无法实现网卡的热复位,晕死。


    for (i = 0; i < 100; i++) {
        if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0)
            break;
        PRINTK("got %x in reset\n", r);
        my_udelay(100);
    }
    n2k_outb(0xff, EN0_ISR); /* Ack intr. */

    if (i == 100)
        printf("pcnet_reset_8390() did not complete.\n");
} /* pcnet_reset_8390 */

static hw_info_t * get_prom(void ) {
    unsigned char prom[32];
    char ethaddr[20];    //tekkaman
    int i, j, tekkaman;    //tekkaman
    unsigned char ne_defethaddr[]={0x08,0x08,0x08,0x08,0x12,0x27,0};//tekkaman

    ......

    pcnet_reset_8390();

    mdelay(10);

    for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
        n2k_outb(program_seq[i].value, program_seq[i].offset);

    tekkaman=ne2000_read_mac_addr(prom);
    if (tekkaman)    {
        printf("ethaddr in nand is not found ,loading ne_defethaddr:");
        for (i = 0; i < 12; i++) {
            prom[i] = ne_defethaddr[i/2];
            printf(" %02x", prom[i]);
        }
    }
    prom[28] = prom[30] = 0x57;

    PRINTK("\n");
    for (i = 0; i < NR_INFO; i++) {
        if ((prom[0] == hw_info[i].a0) &&
            (prom[2] == hw_info[i].a1) &&
            (prom[4] == hw_info[i].a2)) {
            PRINTK("matched board %d\n", i);
            break;
        }
    }
    if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
        for (j = 0; j < 6; j++)
            dev_addr[j] = prom[j<<1];
        PRINTK("on exit i is %d/%ld\n", i, NR_INFO);
        PRINTK("MAC address is %02x:%02x:%02x:%02x:%02x:%02x\n",
               dev_addr[0],dev_addr[1],dev_addr[2],dev_addr[3],dev_addr[4],dev_addr[5]);
        return (i < NR_INFO) ? hw_info+i : &default_info;
   
        if (tekkaman) {
        sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
         dev_addr[0], dev_addr[1],
         dev_addr[2], dev_addr[3],
         dev_addr[4], dev_addr[5]) ;
        printf("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
        setenv ("ethaddr", ethaddr);
        }
    }
    return NULL;
}

/* U-boot specific routines */

#define NB 5

static unsigned short *pbuf = NULL;
static int plen[NB];
static int nrx = 0;

static int pkey = -1;

void uboot_push_packet_len(int len) {
    PRINTK("pushed len = %d, nrx = %d\n", len, nrx);
    if (len>=2000) {
        printf("NE2000: packet too big\n");
        return;
    }
    if (nrx >= NB) {
        printf("losing packets in rx\n");
        return;
    }
    plen[nrx] = len;
    dp83902a_recv(&pbuf[nrx*1000], len);
    nrx++;
}

void uboot_push_tx_done(int key, int val) {
    PRINTK("pushed key = %d\n", key);
    pkey = key;
}

int eth_init(bd_t *bd) {
    static hw_info_t * r;
//    char ethaddr[20];

    PRINTK("### eth_init\n");

    if (!pbuf) {
        pbuf = malloc(NB*1000);
        if (!pbuf) {
            printf("Cannot allocate rx buffers\n");
            return -1;
        }
    }

#ifdef CONFIG_DRIVER_NE2000_CCR
    {
        volatile unsigned char *p =  (volatile unsigned char *) CONFIG_DRIVER_NE2000_CCR;

        PRINTK("CCR before is %x\n", *p);
        *p = CONFIG_DRIVER_NE2000_VAL;
        PRINTK("CCR after is %x\n", *p);
    }
#endif

    nic_base = CONFIG_DRIVER_NE2000_BASE;
    nic.base = (cyg_uint8 *) CONFIG_DRIVER_NE2000_BASE;

    r = get_prom();
    if (!r)
        return -1;
/*//屏蔽无用的语句
    sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
         dev_addr[0], dev_addr[1],
         dev_addr[2], dev_addr[3],
         dev_addr[4], dev_addr[5]) ;
   PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr);
    setenv ("ethaddr", ethaddr);
*/

#define DP_DATA        0x10
    nic.data = (unsigned short *) (nic.base + DP_DATA);
    nic.tx_buf1 = 0x40;
    nic.tx_buf2 = 0x46;
    nic.rx_buf_start = 0x4C;
    nic.rx_buf_end = 0x80;
   
    dp83902a_start(dev_addr);
    if (dp83902a_init() == false)
        return -1;
    return 0;
}

void eth_halt() {

    PRINTK("### eth_halt\n");

    dp83902a_stop();
}

int eth_rx() {
    int j, tmo;
    volatile uchar * inpkt
    PRINTK("### eth_rx\n");

    tmo = get_timer (0) + TOUT * CFG_HZ;
   
    while(1) {
        dp83902a_poll();
        if (nrx > 0) {
            for(j=0; j<nrx; j++) {
                inpkt = (uchar *) &pbuf[j*1000];


                NetReceive(inpkt, plen[j]);//这句的作用就是将接收到的数据

                                           //送到MAC层以上的协议层
            }
            nrx = 0;
            return 1;
        }
        if (get_timer (0) >= tmo) {
            printf("timeout during rx\n");
            return 0;
        }
    }
    return 0;
}

int eth_send(volatile void *packet, int length) {
    int tmo;

    PRINTK("### eth_send\n");

    pkey = -1;

    dp83902a_send((unsigned short *) packet, length, 666);
    tmo = get_timer (0) + TOUT * CFG_HZ;
    while(1) {
        dp83902a_poll();
        if (pkey != -1) {
            PRINTK("Packet sucesfully sent\n");
            return 0;
        }
        if (get_timer (0) >= tmo) {
            printf("transmission error (timoeut)\n");
            return 0;
        }

    }
    return 0;
}

#endif

ne2000.c修改完毕




 (2)修改ne2000.h
NE2000驱动的低级错误
第45行:
 at http://sources.redhat.com/ecos/ecos-license/ */

改为:
 at http://sources.redhat.com/ecos/ecos-license/

就是去掉“*/”   ,   真是TNND汗死!!!!


......

#define DP_IN(_b_, _o_, _d_)  (_d_) = *( (volatile unsigned char *) ((_b_)+(_o_)))
#define DP_OUT(_b_, _o_, _d_) *( (volatile unsigned char *) ((_b_)+(_o_))) = ((unsigned char) (_d_))

#define DP_IN_DATA(_b_, _d_)  (_d_) = *( (volatile unsigned short *) ((_b_)))
#define DP_OUT_DATA(_b_, _d_) *( (volatile unsigned short *) ((_b_))) = ((unsigned short) (_d_))


/* here is all the data */

#define cyg_uint8 unsigned char
#define cyg_uint16 unsigned short
#define bool int

#define false 0
#define true 1

#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 1
#define CYGACC_CALL_IF_DELAY_US(X) my_udelay(X)

typedef struct dp83902a_priv_data {
    cyg_uint8* base;
    cyg_uint16* data;
    cyg_uint8* reset;
    int tx_next;           /* First free Tx page */
    int tx_int;            /* Expecting interrupt from this buffer */
    int rx_next;           /* First free Rx page */
    int tx1, tx2;          /* Page numbers for Tx buffers */
    unsigned long tx1_key, tx2_key;   /* Used to ack when packet sent */
    int tx1_len, tx2_len;
    bool tx_started, running, hardwired_esa;
    cyg_uint8 esa[6];
    void* plf_priv;

    /* Buffer allocation */
    int tx_buf1, tx_buf2;
    int rx_buf_start, rx_buf_end;
} dp83902a_priv_data_t;

......



(3)修改8390.h

......
/*
 *    Only generate indirect loads given a machine that needs them.
 *      - removed AMIGA_PCMCIA from this list, handled as ISA io now
 */

#define n2k_inb(port)   (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)))
#define n2k_outb(val,port)  (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)) = ((unsigned char) val))

#define EI_SHIFT(x)    (x)
......




网卡驱动程序的修改到此结束,以下是总线参数的修改:

修改/board/tekkaman/tekkaman2410/lowlevel_init.S文件(参数都是参考 刘淼 的书):

#define B1_BWSCON    (DW16) /*@tekkaman*/
#define B2_BWSCON    (DW16 + UBLB)
#define B3_BWSCON    (DW16) 
/*@tekkaman*/

......

#define B2_Tacs    0x3 /*  4clk tekkaman*/
#define B2_Tcos    0x3 /*  4clk tekkaman*/

#define B2_Tacc    0x7 /*  14clk */
#define B2_Tcoh    0x3 /*  4clk tekkaman*/
#define B2_Tah    0x3 /*  4clk tekkaman*/
#define B2_Tacp    0x3 /*  6clk tekkaman*/

#define B2_PMC    0x0 /* normal */

......


在/include/configs/tekkaman2410.h文件中加上AX88796网卡驱动的信息:
/*
 * Hardware drivers
 */
//#define CONFIG_DRIVER_CS8900 1 /* we have a CS8900 on-board */
//#define CS8900_BASE  0x19000300
//#define CS8900_BUS16  1 /* the Linux driver does accesses as shorts */
#define CONFIG_DRIVER_NE2000  1
#define CONFIG_DRIVER_NE2000_BASE (0x10000000+0x200)



U-Boot下的AX88796移植结束了,我有复查过,应该在编译网卡驱动的时候连警告都不会有,所以如果您遇到了问题,在检查是否按照上面步骤移植后,还不能解决,可以联系我,QQ:78027228。不过我建议:最好是在看过我介绍的资料后再来移植,出了问题你自己就可以解决了。下一步的目标是U-Boot和Linux下的LCD驱动。以下附上我启动时和运行的输出信息(请注意U-Boot环境变量的设定):

U-Boot 1.2.0 (Sep 25 2007 - 14:59:27)

U-Boot code: 33F80000 -> 33F98BC0  BSS: -> 33F9D3C0
DRAM:  64 MB
NAND:    64 MB
In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0
[Tekkaman2410]# printenv
bootdelay=3
baudrate=115200
ethaddr=08:08:08:08:12:27
netmask=255.255.255.0
bootfile=zImage.img
loadaddr=0x30008000
bootargs=root=/dev/nfs rw nfsroot=192.168.1.22:/home/tekkaman/working/rootfs ip=192.168.1.2:192.168.1.22::255.255.255.0 console=ttySAC0,115200 init=/linuxrc mem=64M
bootcmd=tftp;bootm
ipaddr=192.168.1.2
serverip=192.168.1.22
stdin=serial
stdout=serial
stderr=serial

Environment size: 382/65532 bytes


U-Boot 1.2.0 (Sep 25 2007 - 14:59:27)

U-Boot code: 33F80000 -> 33F98BC0  BSS: -> 33F9D3C0
DRAM:  64 MB
NAND:    64 MB
In:    serial
Out:   serial
Err:   serial
Hit any key to stop autoboot:  0
### eth_init
matched board 31
AX88796 - tekkmana ESA: 08:08:08:08:12:27
TFTP from server 192.168.1.22; our IP address is 192.168.1.2
Filename 'zImage.img'.
Load address: 0x30008000
Loading: #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #############
done
Bytes transferred = 1727136 (1a5aa0 hex)
## Booting image at 30008000 ...
   Image Name:   tekkamanninja
   Created:      2007-09-25   9:28:11 UTC
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    1727072 Bytes =  1.6 MB
   Load Address: 30008000
   Entry Point:  30008040
   Verifying Checksum ... OK
   XIP Kernel Image ... OK

Starting kernel ...

Uncompressing Linux................................................................................................................ done, booting the kernel.
Linux version 2.6.22.2 (root@Tekkaman-Ninja) (gcc version 4.1.0) #5 Tue Sep 25 15:43:11 CST 2007
CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
Machine: Tekkaman2410
Memory policy: ECC disabled, Data cache writeback
CPU S3C2410A (id 0x32410002)
S3C2410: core 202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHz
S3C24XX Clocks, (c) 2004 Simtec Electronics
CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets
Built 1 zonelists.  Total pages: 16256
Kernel command line: root=/dev/nfs rw nfsroot=192.168.1.22:/home/tekkaman/working/rootfs ip=192.168.1.2:192.168.1.22::255.255.255.0 console=ttySAC0,115200 init=/linuxrc mem=64M
irq: clearing pending ext status 00000100
irq: clearing subpending status 00000002
(以下略)


主机Host的tftp服务:
    在Linux下运行tftp服务,你可以参考《 嵌入式linux下的tftp开发环境建立 》,很不错。我没找到原文地址,在这里发两个链接:
http://linux.ccidnet.com/art/310/20060818/844093_1.html
http://tech.ddvip.com/2007-03/117369682820963.html
 
    你如果想在Windows下开发(不推荐),你可以使用tftpd32.exe,官方下载网页:http://tftpd32.jounin.net/tftpd32_download.html

回目录 移植U-Boot.1.2.0到博创2410-S(S3C2410A)

发表于: 2007-09-27,修改于: 2007-10-29 22:57,已浏览2011次,有评论0条 推荐 投诉


网友评论
网友: flylonglong 时间:2007-11-24 17:12:01 IP地址:202.115.65.★
为什么完全照着你的做的

一、在U-Boot中建立自己的开发板类型,并测试编译。
中的第四小步
4 测试编译能否成功
$make tekkaman2410_config
执行以上命令之后 出现以下提示:

Configuring for tekkaman2410 board...
ln:正在创建连至'asm-arm'的符号连接'asm':不允许的操作
make:***[ebest2410-config] Error 1

我昨天在编译内核的时候也出现了
ln:正在创建连至'asm-arm'的符号连接'asm':不允许的操作
这条错误
不知道怎么回事情
使用chmod命令也修改不了'asm-arm'文件的属性(它的属性是不可读写的)
不知道该怎么办了 不知道楼主知道否?????

PS:我开发环境是 vmware+redhat9.0

Blog作者的回复:
不知是不是权限问题,你试试用root配置一下


网友: flylonglong 时间:2007-11-24 18:04:06 IP地址:202.115.65.★
上面问题好象是解决了
不过还是在$make tekkaman2410_config 通过之后
在执行 $make 的时候
一堆英文过后
最后一行提示 make:*** [uboot] Error 1
诶 可能是我的开发环境和博主的不同吧
但是又实在找不出错在哪
真苦闷啊

Blog作者的回复:
flylonglong 您好!上面的问题我还从来没碰过。我猜想可能的原因有两个:1、你的编译器没有制作好。2、你的开发系可能老了点。我建议你自己制作一个编译器看看 ,第一个问题的可能性比较大。


网友: jscorps 时间:2007-12-28 18:14:38 IP地址:211.23.177.★
很冒昧的請問一下 , 在u-boot 1.2.0中, 原本就有sbc2410x的board 設定. 它如果用在friendly -arm上的sbc2410x , 是不是就可以從NAND FLASH上面啟動呢? 還是u-boot 1.2.0 中的sbc2410x 本來就沒有支援NAND flash boot up.

Thanks

Blog作者的回复:
sbc2410x源码不支持NAND启动,也要通过类似2410-S的一些修改来实现。


网友: jscorps 时间:2007-12-31 16:16:13 IP地址:210.202.45.★
我了解了 , 謝謝您的回覆.....
有問題 , 再跟您請教...^_^

网友: heufkk 时间:2007-12-31 16:18:08 IP地址:218.7.43.★
你好,参照你的文章我移植1.1.5,遇到如下问题
/root/u-boot-1.1.5/include/configs/fk2410.h:220:1: warning: this is the location of the previous definition
/root/bin/arm-uclinux-tool/bin/arm-uclinux-gcc -g  -Os   -fno-strict-aliasing  -fno-common -ffixed-r8 -msoft-float -malignment-traps -D__KERNEL__ -DTEXT_BASE=0x33F80000  -I/root/u-boot-1.1.5/include -fno-builtin -ffreestanding -nostdinc -isystem /root/bin/arm-uclinux-tool/lib/gcc/arm-uclinux/3.4.0/include -pipe  -DCONFIG_ARM -D__ARM__ -march=armv4 -mapcs-32 -Wall -Wstrict-prototypes -c -o env_dataflash.o env_dataflash.c
/root/bin/arm-uclinux-tool/bin/arm-uclinux-gcc -g  -Os   -fno-strict-aliasing  -fno-common -ffixed-r8 -msoft-float -malignment-traps -D__KERNEL__ -DTEXT_BASE=0x33F80000  -I/root/u-boot-1.1.5/include -fno-builtin -ffreestanding -nostdinc -isystem /root/bin/arm-uclinux-tool/lib/gcc/arm-uclinux/3.4.0/include -pipe  -DCONFIG_ARM -D__ARM__ -march=armv4 -mapcs-32 -Wall -Wstrict-prototypes -c -o env_flash.o env_flash.c
env_flash.c:70: error: `CFG_FLASH_BASE' undeclared here (not in a function)
env_flash.c: In function `saveenv':
env_flash.c:330: warning: implicit declaration of function `flash_sect_protect'
env_flash.c:334: warning: implicit declaration of function `flash_sect_erase'
env_flash.c:338: warning: implicit declaration of function `flash_write'
make[1]: *** [env_flash.o] 错误 1
make[1]: Leaving directory `/root/u-boot-1.1.5/common'
make: *** [common/libcommon.a] 错误 2
你前面把CFG_FLASH_BASE'注释掉了,那么我遇见这样的问题是怎么回事?
感谢你的回答

Blog作者的回复:
env_flash 是使用nor flash。2410-S没有nor flash ,所以我移植时,将一些关于nor flash 的源码删除或是不去理会。可能是这里出了问题,你要参考一下有关nor flash 移植的资料。


网友: freeubuntu 时间:2008-01-08 12:04:50 IP地址:58.60.126.★
我完全按照你的方法修改uboot1.2.0,gpio和内存地址分配参考开发商提供的bootloader
编译时保错,主要原因是在修改中删除了很多define,很多东西都没有定义了
flash.c: In function 'flash_init':
flash.c:64: error: 'CFG_MAX_FLASH_BANKS' undeclared (first use in this function)
flash.c:64: error: (Each undeclared identifier is reported only once
flash.c:64: error: for each function it appears in.)
flash.c:67: error: 'flash_info' undeclared (first use in this function)
flash.c:75:2: error: #error "Unknown flash configured"
flash.c:77: error: 'PHYS_FLASH_SIZE' undeclared (first use in this function)
flash.c:78: error: 'CFG_MAX_FLASH_SECT' undeclared (first use in this function)
flash.c:81: error: 'PHYS_FLASH_1' undeclared (first use in this function)
flash.c:113: warning: implicit declaration of function 'flash_protect'
flash.c:113: error: 'FLAG_PROTECT_SET' undeclared (first use in this function)
flash.c:114: error: 'CFG_FLASH_BASE' undeclared (first use in this function)
flash.c:119: error: 'CFG_ENV_ADDR' undeclared (first use in this function)
flash.c: At top level:
flash.c:127: error: expected ')' before '*' token
flash.c:172: error: expected ')' before '*' token
flash.c:293: error: expected ')' before '*' token
flash.c:371: error: expected ')' before '*' token
你有碰到过这些问题吗?

Blog作者的回复:
出现这种情况的原因很可能是nor flash 的驱动造成的。如果你的板上有nor flash ,请参考我移植SBC2440V4的文章,那个板子有nor flash ,而且在nor flash方面两个芯片的基本代码一样。
如果你不使用nor flash ,那就是你没有将nor flash的驱动清干净,比如:修改/include/configs/tekkaman2410.h时漏了什么。

最后出现
flash.c:127: error: expected ')' before '*' token
flash.c:172: error: expected ')' before '*' token
flash.c:293: error: expected ')' before '*' token
flash.c:371: error: expected ')' before '*' token
有可能是语法错误,可能是你手误,多删或少删了什么,比如“;”或“)”等等。
移植到2410的那篇文章我复查过应该不会有问题。


网友: freeubuntu 时间:2008-01-09 16:37:35 IP地址:58.60.126.★
上个问题解决了,可还是有错误,报错如下:
common/libcommon.a(env_nand.o): In function `saveenv':
/home/freedom/Desktop/uboot/u-boot-1.2.0/common/env_nand.c:212: undefined reference to `nand_info'
make: *** [u-boot] Error 1
看了上面的解答,知道应该是nor flash的问题,nor flash删除了一些什么内容呢?我再看一下

Blog作者的回复:
可能是你在:
10 修改common/env_nand.c时,漏了extern nand_info_t nand_info[CFG_MAX_NAND_DEVICE];

你仔细看看10 修改common/env_nand.c这部分,看看有没有漏改了什么。


网友: kamiuouc 时间:2008-03-24 21:15:34 IP地址:60.209.103.★
我用的是uboot1.1.4的版本,s3c2410 dm9000编译提示错误:
flash.c:113: undefined reference to `flash_protect'
flash.c:118: undefined reference to `flash_protect'
make: *** [u-boot] 错误 1
请你帮忙啊,谢谢!

Blog作者的回复:
我对以前的版本不太熟,你可以把完整的出错信息和/cpu/arm920T中的文件发邮件给我看看 


网友: milkmilk 时间:2008-04-15 11:13:50 IP地址:58.48.110.★
[hek@localhost u-boot-1.2.0]$ make hhek2410_config
make: arm-linux-gcc:命令未找到
Configuring for hhek2410 board...
[hek@localhost u-boot-1.2.0]$ make CROSS_COMPILE=arm-9tdmi-linux-gnu-
for dir in tools examples post post/cpu ; do make -C $dir _depend ; done
make[1]: Entering directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/tools'
make[1]: Nothing to be done for `_depend'.
make[1]: Leaving directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/tools'
make[1]: Entering directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/examples'
make[1]: Nothing to be done for `_depend'.
make[1]: Leaving directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/examples'
make[1]: Entering directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/post'
make[1]: Nothing to be done for `_depend'.
make[1]: Leaving directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/post'
make[1]: Entering directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/post/cpu'
make[1]: Nothing to be done for `_depend'.
make[1]: Leaving directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/post/cpu'
make -C tools all
make[1]: Entering directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/tools'
gcc -g -Wall -pedantic -idirafter /home/hek/haha/yizhiuboot/u-boot-1.2.0/include -idirafter /home/hek/haha/yizhiuboot/u-boot-1.2.0/include2 -idirafter /home/hek/haha/yizhiuboot/u-boot-1.2.0/include -DTEXT_BASE=0x33F80000 -DUSE_HOSTCC -O -c -o envcrc.o envcrc.c
gcc -g  -idirafter /home/hek/haha/yizhiuboot/u-boot-1.2.0/include -idirafter /home/hek/haha/yizhiuboot/u-boot-1.2.0/include2 -idirafter /home/hek/haha/yizhiuboot/u-boot-1.2.0/include -DTEXT_BASE=0x33F80000 -DUSE_HOSTCC -c -o environment.o environment.c
gcc -Wall -pedantic -idirafter /home/hek/haha/yizhiuboot/u-boot-1.2.0/include -idirafter /home/hek/haha/yizhiuboot/u-boot-1.2.0/include2 -idirafter /home/hek/haha/yizhiuboot/u-boot-1.2.0/include -DTEXT_BASE=0x33F80000 -DUSE_HOSTCC -O -o envcrc envcrc.o crc32.o environment.o
make[1]: Leaving directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/tools'
make -C examples all
make[1]: Entering directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/examples'
arm-9tdmi-linux-gnu-gcc -g  -Os   -fno-strict-aliasing  -fno-common -ffixed-r8 -msoft-float  -D__KERNEL__ -DTEXT_BASE=0x33F80000  -I/home/hek/haha/yizhiuboot/u-boot-1.2.0/include -fno-builtin -ffreestanding -nostdinc -isystem /home/hek/haha/toolchains/gcc-4.1.1-glibc-2.3.2/arm-9tdmi-linux-gnu/lib/gcc/arm-9tdmi-linux-gnu/4.1.1/include -pipe  -DCONFIG_ARM -D__ARM__ -march=armv4 -mabi=apcs-gnu -Wall -Wstrict-prototypes -c -o hello_world.o hello_world.c
In file included from /home/hek/haha/yizhiuboot/u-boot-1.2.0/include/common.h:105,
                 from hello_world.c:24:
/home/hek/haha/yizhiuboot/u-boot-1.2.0/include/flash.h:36: error: 'CFG_MAX_FLASH_SECT' undeclared here (not in a function)
make[1]: *** [hello_world.o] 错误 1
make[1]: Leaving directory `/home/hek/haha/yizhiuboot/u-boot-1.2.0/examples'
make: *** [examples] 错误 2

高手帮忙啊.我是按照你的方法做的,但出现了'CFG_MAX_FLASH_SECT'未声明的情况不知道是怎么回事啊?
我用的是gcc-4.1.1-glibc-2.3.2的交叉编译工具,但前几行[hek@localhost u-boot-1.2.0]$ make hhek2410_config
make: arm-linux-gcc:命令未找到
Configuring for hhek2410 board...
这是怎么回事啊?

Blog作者的回复:
你的Makefile中的编译器路径不正确。你核对一下。


网友: 本站网友 时间:2008-05-21 21:36:06 IP地址:222.79.245.★
完全按你的步骤做完,make后:
for dir in tools examples post post/cpu ; do make -C $dir _depend ; done
make[1]: Entering directory `/biyesheji/u-boot-1.2.0/tools'
ln -s ../common/environment.c environment.c
ln -s ../lib_generic/crc32.c crc32.c
make[1]: Leaving directory `/biyesheji/u-boot-1.2.0/tools'
make[1]: Entering directory `/biyesheji/u-boot-1.2.0/tools'
make[1]: Nothing to be done for `_depend'.
make[1]: Leaving directory `/biyesheji/u-boot-1.2.0/tools'
make[1]: Entering directory `/biyesheji/u-boot-1.2.0/examples'
armv4l-unknown-linux-gcc: hello_world.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: stubs.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
make[1]: *** [.depend] Error 1
make[1]: Leaving directory `/biyesheji/u-boot-1.2.0/examples'
make[1]: Entering directory `/biyesheji/u-boot-1.2.0/post'
armv4l-unknown-linux-gcc: cache_8xx.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: cache.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: codec.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: cpu.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: dsp.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: ether.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: i2c.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: memory.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: post.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: rtc.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: spr.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: sysmon.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: tests.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: uart.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: usb.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: watchdog.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
make[1]: *** [.depend] Error 1
make[1]: Leaving directory `/biyesheji/u-boot-1.2.0/post'
make[1]: Entering directory `/biyesheji/u-boot-1.2.0/post/cpu'
armv4l-unknown-linux-gcc: asm.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: cmp.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: cmpi.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: two.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: twox.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: three.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: threex.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: threei.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: andi.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: srawi.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: rlwnm.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: rlwinm.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: rlwimi.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: store.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: load.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: cr.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: b.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: multi.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: string.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
armv4l-unknown-linux-gcc: complex.o: ?????????
armv4l-unknown-linux-gcc: unrecognized option `-MQ'
make[1]: *** [.depend] Error 1
make[1]: Leaving directory `/biyesheji/u-boot-1.2.0/post/cpu'
make: *** [depend] Error 2

请问会是什么原因。

网友: tcsswlw 时间:2008-06-03 17:09:13 IP地址:218.58.71.★
出现了好多nand_legacy.c中的错误是怎么回事啊??

网友: tcsswlw 时间:2008-06-03 19:29:09 IP地址:218.58.71.★
博主在不在啊??
按照你的方法移植,出现了好多nand_legacy.c中的错误呢,而且这些错误好象是不应该存在的啊,这个文件又没有改动!!

 发表评论