1. 程式人生 > >在U-boot中新增Cubieboard(全志A10)乙太網驅動

在U-boot中新增Cubieboard(全志A10)乙太網驅動

當定義CONFIG_CMD_NET和CONFIG_CMD_PING,編譯之後執行ping命令,告警沒有找到乙太網。

因此,需要開啟U-boot的網路功能, u-boot-sunxi-sunxi中沒有找到明顯的網路驅動程式碼,或許有通用的驅動,但可以獲得資料的途徑有限,再說我是個初學者,平時工作屬於自動控制類,網路方面很菜,因此想通過修改一個網路驅動,進行一次初步學習,想到就開工...

邊做邊寫,恐怕會比較亂。

開發環境:   1、筆記本RHEL5,安裝編譯器arm-none-eabi-版本4.7.2; 編輯器Vim;minicom2.1

                     2、桌上型電腦XPsp3,安裝SourceInsight3.5

基本思路:  1、找到u-boot內網路程式碼執行的軌跡,初始化、資料交換的驅動介面等等

                     2、實現一個驅動,加入到這個執行軌跡中,裝置初始化,資料讀寫等等

準備工作:   1、找到晶片資料,這個比較坑,只能找到RTL8021CP的PDF,至於CPU晶片資料,

                            ×,那簡直不能稱為資料,看看三星處理器資料,為啥別人能做大,不是沒有原因的。

                     2、Cubieboard原理圖一份,這個好弄,人手一份呀

                     3、網線準備了兩根,一個常用上網的,一根交叉線。路由器一隻。

                            在沒有研究清楚硬體連線之前,這樣準備應該比較充足了。

                     4、下個新版本編譯器,找了一個arm-none-eabi-的編譯器,版本4.7.2,估計是目前最高版本。

                            選擇arm處理器,linux版本,點進去之後需要用郵箱註冊,下載地址會發到郵箱。

                     5、因為沒有CPU資料,需要尋找一個A10的網路驅動程式碼,在支援Cubieboard的核心中找到了。

                            這個驅動是linux下的,需要修改一下或參考其操作硬體的過程,以便在u-boot內執行。

一、環境建立,初步編譯

        考慮到這次需要參考其他開發板或CPU的網路驅動,因此用SourceInsight3.5建立一個u-boot-sunxi-sunxi的工程,建立關聯關係,方便程式碼查閱。建立方法很簡單,不懂的可以網上搜索一下。建立工程時不要刪除其他程式碼,全部使用。

        linux下編譯環境設定,將下載的編譯器解壓到 /usr/local/arm/目錄,解壓之後目錄是arm-2012.09

        設定環境變數,在RHEL5系統內,在/ect/profile的末尾加上一句:

        export   PATH=$PATH:/usr/local/arm/arm-2012.09/bin

        儲存之後,執行:source /ect/profile 或者logout,或者重啟機器。

        回到bash,輸入arm再按Tab鍵,可以看到編譯工具鏈列出來了,執行

        arm-none-eabi-gcc   -v,可以看到版本是4.7.2

        其他系統編譯器安裝設定可以在網上搜索,有很多文章會提到。

        進入u-boot-sunxi-sunxi目錄,修改Makefile內容,找到 CROSS_COMPILE ?=  這一行

        改為:CROSS_COMPILE ?= arm-none-eabi-

        進入 u-boot-sunxi-sunxi/arch/arm,修改config.mk內容,也是這一句 CROSS_COMPILE ?= 

        改為:CROSS_COMPILE ?= arm-none-eabi-

       回到u-boot-sunxi-sunxi目錄,執行:

       make  distclean                     //清除之前編譯的內容

       make  cubieboard_config     //設定板子

       make  -j4                                //編譯,-j4表示多執行緒編譯,可以使用-j2,如果是虛擬機器可以不用這個引數,

                                                       //如果電腦配置比較好,可以使用 -j8

      等待一會,不出意外,編譯完成,寫入SD卡,到板子上執行,可以看到串列埠輸出資訊。

二、U-boot網路模組分析

      1、網路初始化

       之前曾經分析過主迴圈,在主迴圈main_loop()呼叫之前就是初始化。

       在檔案\u-boot-sunxi-sunxi\arch\arm\lib\board.c, 函式board_init_r()內:

       ...........

        #if defined(CONFIG_CMD_NET)
        puts("Net:   ");
        eth_initialize(gd->bd);
        #if defined(CONFIG_RESET_PHY_R)
        debug("Reset Ethernet PHY\n");
        reset_phy();
        #endif
        #endif

        ...........

       這一段程式碼可以看出,要執行網路初始化,需要定義CONFIG_CMD_NET

       因此在\u-boot-sunxi-sunxi\include\configs\sunxi-common.h 末尾加一句:

       #define  CONFIG_CMD_NET

      再來看看函式eth_initialize() 的內容,在檔案 \u-boot-sunxi-sunxi\net\eth.c內:

       .................

       if (board_eth_init != __def_eth_init) {
             if (board_eth_init(bis) < 0)
             printf("Board Net Initialization Failed\n");
       } else if (cpu_eth_init != __def_eth_init) {
             if (cpu_eth_init(bis) < 0)
                    printf("CPU Net Initialization Failed\n");
       } else
             printf("Net Initialization Skipped\n");

       .................

       如果只定義CONFIG_CMD_NET,在上電時就會列印 Net Initialization Skipped,執行了最後一個else的內容,因此,需要完成網路初始化,需要實現函式board_eth_init()或者cpu_eth_init()

看程式碼,這兩個函式誰等於__def_eth_init就執行誰,在看看__def_eth_init是啥,也在eth.c這個檔案內

       static int   __def_eth_init(bd_t *bis)
       {
              return -1;
       }
       int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
       int board_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));

       可見,實現__def_eth_init的“alias  ”,bash命令裡面有個alias,如果你用過就明白這是什麼意思了,實現它,就可以進行初始化啦。

       乙太網模組在A10內,A10的手冊稱之為WEMAC模組,因此,我們需要實現cpu_eth_init函式,表明eathnet模組在CPU內部。

       在檔案\u-boot-sunxi-sunxi\arch\arm\cpu\armv7\sunxi\board.c內增加函式cpu_eth_init,內容如下:

      #ifdef   CONFIG_SUN4I_WEMAC

       int cpu_eth_init(bd_t *bis)
       {
              return   sun4i_wemac_initialize(bis);
       }
       #endif

      2、如何實現網路模組

      網路模組已經成熟了,我們並不需要增加很多程式碼,只需要實現對硬體的操作就可以了。

      基本的操作大約就幾個:初始化、開啟、關閉、接收、傳送、掛起

      分析\u-boot-sunxi-sunxi\net目錄內的程式碼,發現網路的資料結構定義在\u-boot-sunxi-sunxi\include\net.h內

      struct eth_device {
           char name[16];                                                                              //網路名
           unsigned char enetaddr[6];                                                         //乙太網地址
           int iobase;                                                                                       //io基址?
           int state;                                                                                          //裝置狀態

           int  (*init) (struct eth_device *, bd_t *);                                       //網路裝置初始化
           int  (*send) (struct eth_device *, void *packet, int length);     //傳送資料
           int  (*recv) (struct eth_device *);                                                  //接收資料
           void (*halt) (struct eth_device *);                                                 //掛起
           #ifdef CONFIG_MCAST_TFTP
           int (*mcast) (struct eth_device *, u32 ip, u8 set);
           #endif
           int  (*write_hwaddr) (struct eth_device *);                                 //寫硬體地址?這個是啥?
           struct eth_device *next;
           int index;
           void *priv;
      };

       struct eth_device結構體定義了網路裝置的基本操作,從面向物件的角度來說,只要在驅動程式碼內將struct eth_device的init,send,recv,halt,write_hwaddr這幾種方法實現,就可以實現網路的操作了,至於資料收回來之後在上層的解析方式那就不是驅動關心的了。任務變得簡單了,實現這幾種操作便可

      再看struct eth_device結構體下面這幾個函式:

      extern int eth_initialize(bd_t *bis); /* Initialize network subsystem */
      extern int eth_register(struct eth_device* dev);/* Register network device */
      extern int eth_unregister(struct eth_device *dev);/* Remove network device */
      extern void eth_try_another(int first_restart); /* Change the device */
      extern void eth_set_current(void);  /* set nterface to ethcur var */

      都在\u-boot-sunxi-sunxi\net\eth.c內實現,分析一下eth_register這個函式(其他的就不多說了),如下,

      int  eth_register( struct eth_device  *dev )
      {
             struct eth_device *d;
             static int index;

             assert( strlen(dev->name)  <  sizeof(dev->name) );

             if (!eth_devices) {  

             //註冊之前eth_devices應該初始化為NULL,在當前檔案的函式int  eth_initialize( bd_t *bis ) 中,

             //開始幾句程式碼就這樣初始化了,但是這個函式eth_initialize將呼叫我們自己寫的cpu_eth_init(),

             //並未呼叫eth_register,因此可以預見,自己寫的函式cpu_eth_init將要呼叫eth_register對網路進行註冊,

             //實際工作還是要自己實現
                   eth_current = eth_devices = dev;
                   eth_current_changed();
              } else {
                   for (d = eth_devices; d->next != eth_devices; d = d->next)
                         ;
                   d->next = dev;
              }

              dev->state  =  ETH_STATE_INIT;     //網路裝置狀態為初始化
              dev->next    =  eth_devices;               //連結串列的下一個指向自己,為啥呢?
              dev->index  =  index++;                       //裝置個數增加了

              return 0;
       }

三、實現網路驅動

      這些內容都將實現在sun4i_wemac.c和sun4i_wemac.h內。這兩個檔案都在\u-boot-sunxi-sunxi\driver\net\目錄下。      

     1、資料結構

      經過上面分析,可以瞭解到,假設自己定義一個網路裝置的資料結構,那麼這個結構大致如下,下面直接寫一個,實際程式碼還要推敲推敲:

      struct   sun4i_wemac_dev {
 

             void   *wemac_base;    // A10內部wemac模組的基地址

             void   *gpio_base;          //wemac模組使用的gpio的基地址,去看看原理圖,實際使用A10的PA口

             //接收發送buffer管理,使用佇列

             unsigned int  rx_head;
             unsigned int  rx_tail;
             unsigned int  tx_head;
             unsigned int  tx_tail;

             void   *rx_buffer;
             void   *tx_buffer;

             struct   eth_device   netdev;      //這就是上面的乙太網裝置,這個一定要有
             unsigned short     phy_addr;    //PHY地址,就是板子上RTL8201CP的地址
       };

       有的人又問啦,為什麼要自己定義一個數據結構呢?net.h裡面不是已經有一個struct eth_device了嗎?仔細想一下,struct eth_device是u-boot定義的資料結構,裡面的每一個成員可能在u-boot的其他網路模組程式碼中被使用修改,我們並不完全知道所有程式碼對struct eth_device的操作,因此需要自己定義一個結構,提供這個介面就可以了。用一句話總結就是:struct eth_device是定義給u-boot的網路模組使用的,使用者得定義自己的裝置,以此隔離了驅動程式碼與u-boot程式碼。

       2、實現初始化

       就是上面提到的cpu_eth_init()內呼叫的sun4i_wemac_initialize()函式,只寫一個思路,具體程式碼還需要推敲: 

       int   sun4i_wemac_initialize(  bd_t  *bis  )

       {

            struct   sun4i_wemac_dev  *wemac_dev;    //自己定義的結構

            struct   eth_device   *netdev;                            //u-boot已經定義的結構

           wemac_dev  =  malloc( sizeof ( struct sun4i_wemac_dev  ) );   //分配記憶體
           if ( wemac_dev  ) {
                  printf("Error: Failed to allocate memory for WEMAC\n");
                  return -1;
           }
           memset(wemac_dev , 0, sizeof( struct    sun4i_wemac_dev  ));            

           netdev = &wemac_dev ->netdev;

          /*****************************/

          初始化傳送、接收管理佇列

          若還需要其他功能,可以增加到資料結構struct   sun4i_wemac_dev中,並在此初始化,

         寫文章時,程式碼還沒寫,留待後續補全

          /*****************************/

          wemac_dev ->wemac_base =  (void *)EMAC_BASE;

          wemac_dev ->gpio_base      =  (void *)PA_BASE;

          wemac_dev ->phy_addr        = WEMAC_PHY;

          //以下就是要實現的網路裝置結構體內的“方法”,就是驅動程式碼中主要的幾個函式,

          //可以參考從核心拷貝過來的驅動是如何實現的:

           netdev->init                      = sun4i_wemac_init;      //注意這個初始化函式跟當前函式是不同的,這個函式

                                                                                                  //主要初始化wemac模組和RTL8201晶片
           netdev->halt                     = sun4i_wemac_halt;
           netdev->send                  = sun4i_wemac_send;
           netdev->recv                    = sun4i_wemac_recv;
           netdev->write_hwaddr   = sun4i_wemac_write_hwaddr;

           .....................其他初始化...........

           eth_register( netdev );    // 最後將網路設備註冊,這樣u-boot就能使用驅動程式啦

                                                       // 註冊之後,eth.c內的全域性變數eth_current 指向wemac_dev ->netdev,

                                                       //這是在u-boot任何程式碼使用eth_current,

                                                       // 都表示使用的是現在初始化的模組

            return 0;

       }
      

       3、其他模組的實現

       看看eth.c內怎麼實現接收和傳送介面的,就可以知道驅動程式碼應該怎麼寫了

       int eth_send(void *packet, int length)
       {
             if ( !eth_current )                         //eth_current是全域性指標,指向驅動初始化的結構體wemac_dev ->netdev
                  return -1;

            return eth_current->send(eth_current, packet, length);  //註冊之後,實際呼叫就是sun4i_wemac_send;
       }

       int eth_rx(void)
       {
            if (!eth_current)
                   return -1;

             return eth_current->recv(eth_current);  //註冊之後,實際呼叫就是sun4i_wemac_recv;

       }

       因此,可以知道,驅動程式碼實現的接收發送形式如下:

      static  int   sun4i_wemac_send( struct  eth_device  *dev,  void  *packet,   int  length )

      {

             struct   sun4i_wemac_dev  wemac_dev  =  to_wemac(dev);            

             //功能如何實現,可以參考核心程式碼的驅動。

      } 

     
      static  int   sun4i_wemac_recv( struct  eth_device   *dev )

      {

              struct   sun4i_wemac_dev  wemac_dev  =  to_wemac(dev); 

              //功能如何實現,可以參考核心程式碼的驅動。

      }

      由於我們自己定義的結構體是struct   sun4i_wemac_dev,而傳過來的引數是全域性指標eth_current,

      根據上面的分析,eth_current指向struct   sun4i_wemac_dev結構內的struct   eth_device   netdev,

      因此要獲得指向struct   sun4i_wemac_dev的指標需要使用linux核心常用的手段,“容器”的概念就出來了,

      看程式碼定義: 

      struct   sun4i_wemac_dev  wemac_dev  =  container_of(  dev ,  struct   sun4i_wemac_dev ,  netdev);

      就可以獲得註冊之前申請的結構體的首地址,如何辦到的呢?

      來看看這個在linux核心中常用的巨集:

      #define   container_of( ptr, type, member )       ( {   \
                                                                                           const typeof( ((type *)0)->member ) *__mptr  =  (ptr); \
                                                                                           (type *)( (char *)__mptr - offsetof(type,member) ); }  )

     #define   offsetof( TYPE, MEMBER )     ( (size_t)  & ((TYPE *)0)->MEMBER )

      這是一個很神奇的巨集,可以把它用於自己以後的C程式碼開發中,如果使用其他編譯器,這裡面的關鍵字要改一下。

      意思就是,dev指向的記憶體地址,減掉它在struct   sun4i_wemac_dev中的偏移量,就獲得了初始化時定義的

struct   sun4i_wemac_dev 指標

      偏移量的獲取很簡單 (( struct   sun4i_wemac_dev *) 0)->netdev  就是偏移量;我們知道使用 -> 操作時,獲得指向當前結構體的某一個成員的地址, 而這個成員的地址與結構體首地址的差值,就是它在結構體內的偏移量,如果把結構體的首地址設定為0,結果妙不可言。

      由於很多函式都要用到這個巨集,因此可以再寫成下面這樣:

      #define  to_wemac(_nd)    container_of( _nd,  struct   sun4i_wemac_dev, netdev)

      上面的定義就可以這樣:  struct   sun4i_wemac_dev  wemac_dev  =  to_wemac(dev);    

       另外3個個函式,實現方式也是一樣,先去分析eth.c內呼叫,一併都分析一下吧:

       int eth_init(bd_t *bis)
       {
              struct eth_device *old_current, *dev;

              if (!eth_current) {                   //必須註冊成功之後,否則這裡判斷失敗,將列印找不到ethernet
                      puts("No ethernet found.\n");
                      return -1;
              }

             /* Sync environment with network devices */
             dev = eth_devices;
             do {
                    uchar env_enetaddr[6];

                    if ( eth_getenv_enetaddr_by_index( "eth",   dev->index,  env_enetaddr))                               

                             memcpy(dev->enetaddr, env_enetaddr, 6);  

                             //這裡就是獲取IP地址了,從哪裡獲取呢?這是u-boot解決的問題啦                                        

                             //熟悉情況的人這時會想起一個檔案,就是u-boot移植時說的引數配置檔案

                             //uEnv.txt或boot.scr,怎麼獲得,需要進一步追查程式碼流程,這不是網路驅動關心的。

                    dev = dev->next;
             } while ( dev  !=  eth_devices );          // CB上只有一個乙太網裝置,因此迴圈一次就會結束

            old_current = eth_current;
            do {
                       debug("Trying %s\n", eth_current->name);

                       if ( eth_current->init( eth_current, bis )  >=  0 ) { //實際呼叫的就是函式sun4i_wemac_init ,

                                                                                                            //對WEMAC模組和PHY晶片進行初始化
                              eth_current->state = ETH_STATE_ACTIVE;    //初始化成功,處於活動狀態標誌

                              return 0;    //成功就返回啦
                      }
                      debug("FAIL\n");

                      eth_try_another(0);  //不成功,試試另一個,不用分析,這個函式可定會嘗試改變全域性指標eth_current
             } while (old_current != eth_current);

             return -1;
      }

      還有一個疑問,那又是什麼地方呼叫int eth_init(bd_t *bis)這個函式呢?藉助強大的Source Insight,很快就能找到呼叫它的地方啦,搜尋工程,出來一大片,只需關心檔案net.c的呼叫即可,其他呼叫是不會被編譯進來的,以下兩個函式呼叫了這個初始化,從名字就能看出其大概功能了

      int  NetLoop( enum   proto_t protocol );  //這就是讀取網路資料的主迴圈

      void  NetStartAgain( void );                        //這個是net重新開始,當然要初始化

      再來看看ping命令幹了啥,在檔案\u-boot-sunxi-sunxi\common\cmd_net.c

      #if defined(CONFIG_CMD_PING)
      int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
      {
            if (argc < 2)
                 return -1;

            NetPingIP = string_to_ip(argv[1]);
            if (NetPingIP == 0)
                   return CMD_RET_USAGE;

            if (NetLoop(PING) < 0) {    //這裡呼叫了NetLoop函式,再呼叫eth_init,再呼叫自己寫的sun4i_wemac_init 
                   printf("ping failed; host %s is not alive\n", argv[1]);
                   return 1;
            }

            printf("host %s is alive\n", argv[1]);

            return 0;
        }

        U_BOOT_CMD(
                                     ping, 2, 1, do_ping,
                                    "send ICMP ECHO_REQUEST to network host",
                                    "pingAddress"
        );
        #endif

        至於NetLoop內如何實現資料打包,如何解析,有興趣的可以繼續深入。

      void eth_halt(void)
      {
              if (!eth_current)
              return;

              eth_current->halt(eth_current);  //實際就是呼叫sun4i_wemac_halt,網路裝置掛起

              eth_current->state = ETH_STATE_PASSIVE; //標誌變化
      }

     int eth_write_hwaddr(struct eth_device *dev, const char *base_name,  int eth_number)
     {
              unsigned char env_enetaddr[6];
              int ret = 0;

              eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr);

              if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6)) {
                      if (memcmp(dev->enetaddr, "\0\0\0\0\0\0", 6) &&  memcmp(dev->enetaddr, env_enetaddr, 6)) {
                                printf("\nWarning: %s MAC addresses don't match:\n", dev->name);
                                printf("Address in SROM is         %pM\n", dev->enetaddr);
                                printf("Address in environment is  %pM\n", env_enetaddr);
                      }

                      memcpy(dev->enetaddr, env_enetaddr, 6);
              } else if (is_valid_ether_addr(dev->enetaddr)) {
                      eth_setenv_enetaddr_by_index(base_name, eth_number,  dev->enetaddr);
                       printf("\nWarning: %s using MAC address from net device\n", dev->name);
              }

              if (dev->write_hwaddr &&  !eth_mac_skip(eth_number)) {
                      if (!is_valid_ether_addr(dev->enetaddr))
                               return -1;

                     ret = dev->write_hwaddr(dev);//實際就是呼叫sun4i_wemac_write_hwaddr,將IP地址寫入硬體??
              }

             return ret;
      }

      這三個函式形式如下:

      int     sun4i_wemac_init ( struct eth_device *, bd_t * );
      void  sun4i_wemac_halt( struct eth_device * );
      int     sun4i_wemac_write_hwaddr( struct eth_device * );             

      具體內容如何實現,在沒有詳細CPU手冊的情況下,參考核心驅動程式碼是最好的選擇,如果熟悉核心驅動程式設計就更好了,那是下一個目標。

四、驅動完成之後的初步測試

      測試ping命令

      測試tftp命令-----這個命令還沒有,下一次學習的目標。

      程式碼還沒寫,留待後續補全

相關推薦

U-boot新增Cubieboard(A10)乙太網驅動

當定義CONFIG_CMD_NET和CONFIG_CMD_PING,編譯之後執行ping命令,告警沒有找到乙太網。 因此,需要開啟U-boot的網路功能, u-boot-sunxi-sunxi中沒有找到明顯的網路驅動程式碼,或許有通用的驅動,但可以獲得資料的途徑有限,再說我

u-boot新增mtdparts支援以及Linux的分割槽設定

閱讀目錄(Content) 簡介 作者:彭東林 u-boot版本:u-boot-2015.04 Linux版本:Linux-3.14 硬體平臺:tq2440, 記憶體:64M   NandFlash: 256MB 下面我們分兩部分,u-boot和k

U-boot新增乙太網驅動

版權宣告:本文為博主原創文章,未經博主允許不得轉載。    https://blog.csdn.net/mao0514/article/details/17523803 當定義CONFIG_CMD_NET和CONFIG_CMD_PING,編譯之後執行ping命令,告警沒有

u-boot 增加自定義命令hjlcmd2------(新增檔案來定義)

1,在 "[email protected]:/home/hjl/Downloads/uboot/common#" 目錄中新增檔案 cmd_hjl.c ,加上標頭檔案     #include <common.h>    &nbs

u-bootnand相關命令使用---- ubi, ubifsls, ubifsmount, ubifsumount

轉載地址:https://blog.csdn.net/voice_shen/article/details/8425763  [Version: 2013-01-rc2] [Author: Bo Shen <[email protected]>] 1. &

u-boot 增加自定義命令hjlcmd1

在uboot/common資料夾下找到command.c檔案,進入編輯: 對照隨便一個命令,如: do_version (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { extern char version_strin

u-boot:rm:無法刪除 "asm":是一個目錄

轉自:http://blog.163.com/zhangyingxin_/blog/static/218307222201331291755998/ uboot移植編譯小問題 ———rm:無法刪除 "asm":是一個目錄 我之前所做的uboot移植工作都快要完成了,想要拷貝

修改A10 開機第一屏logo

按照以往 的經驗。是要去linux/driver/video/logo下 改下面或替換圖片。 但是全志A10第一屏的logo圖片是叫linux.bmp我搜到在trunk\A10_TVD_VERSION1.4\lichee\tools\pack\chips\sun4i\wbo

U-BOOT實現讀取電池電量

platform: s3c2440 + u-boot 1.1.4 + linux 2.6.18       為了防止低電開機啟動到一半的時候系統down掉,所以有必要在 u-boot 中加入電池電量的偵測。 偵測電池電量只需讀 AN0 口上的 AD 值就可以了,當電量少於 5

u-bootmkimage工具的具體使用

通常,u-boot為kernel提供一些kernel無法知道的資訊,比如ramdisk在RAM中的地址。Kernel也必須為U-boot提供必要的資訊,如通過mkimage這個工具(在u-boot程式碼的tools目錄中)可以給zImage新增一個header,也就是使得通常

u-bootmakefile的執行步驟

本文分析的uboot版本是2013.04.主要目的是通過分析uboot頂目錄下的makefile檔案,瞭解uboot的大致執行步驟和順序。 簡而言之就是先讀取makefile檔案;然後讀取include包含的檔案;重建已讀取makefile檔案的規則;展開變數和函式等。

U-BootMAC地址設定及往核心傳遞

一、核心引數的傳遞 U-Boot向Linux驅動傳遞引數的方式有兩種,一為在系統啟動的時候由bootloader傳入,還有一種是將驅動編譯成模組,將引數作為模組載入的引數傳入。 核心通過setup介面接受Bootloader傳入的引數。方式如下: st

A10/A20 Bootloader載入過程分析

【轉】A10/A20 Bootloader載入過程分析 轉自:http://blog.csdn.net/allen6268198/article/details/12905425 A10/A20 Bootloader載入過程分析 注:由於全志A10和A20在載入Bootlo

android(A10 4.0.4)版本系統編譯說明.pdf

以上是連結地址,點選即可進入下載地址: 剛整理完畢,現提交上來供大家分享,4.0.4與2.3.4區別在打包上區別較大!近期看到很多想繼續瞭解a10的朋友在部落格留言,現在我在維護www.a10bbs.com這個技術論壇,很多一手資料可能都在這裡整理,大家可以到這裡下載!

u-bootfdt命令的使用

[u-boot: v2012.10] [Author: Bo Shen <[email protected]>] 依linux community的要求,從linux-3.5後,新提交的code必須對device tree進行支援。下面介紹如何使u-

JTable 表頭新增 JCheckBox 選 反向選擇 功能

public class TestFrame extends JFrame {     private JPanel contentPane;     private JTable table;     /**      * Launch the application.      */     public

U-boot通過ENV設定顯示裝置(如LCD)引數的方法與格式

對於一個移植比較完善的U-boot來說,顯示裝置一般也是可以使用的。在嵌入式中的LCD液晶屏一般由晶片的內建的LCD控制器或者VPSS(視訊處理子系統)來控制。在U-boot中已經實現了類似framebuffer的機制,只要在移植的時候完成對LCD控制等顯示裝置的初始化,並

u-bootmmc命令使用

[u-boot: v2013.01] [Author: Bo Shen <[email protected]>] mmc命令的幫助資訊如下: U-Boot> mmc      mmc - MMC sub system Usage: mmc

A10 Bootload載入過程分析

A10的啟動過程大概可分為5步:BootRom,SPL,Uboot,Kernel,RootFileSystem。本文只關注映象的載入過程,分析RootRom->SPL->Uboot的啟動流程。 系統上電後,ARM處理器在復位時從地址0x000000開始執行

在linux系統通過fw_printenv檢視和設定u-boot的環境變數

uboot下可以通過命令訪問和修改環境變數,但是如果需要在Linux系統下訪問這些資料該怎麼辦呢?其實uboot早就幫我們想好了。      1、編譯fw_printenv工具     在你使用的uboot程式碼中用以下編譯指令:     make env     這樣就可