请稍侯

Pine64运行uboot

pine A64 是一款类似 RaspberryPi 的开源单板计算机(Single Board Computer , SBC),搭载了全志的 A64(Cortex A53)四核处理器,1GB DDR3 内存,GPU双核Mali-400,支持4K HDMI输出,有千兆网口、两个I/O扩展槽、两个USB 2.0端口,蓝牙4.0、无线801.11 b/g/n以及一个可扩展的MicroSD插槽。总共有三种型号,分别是 512MB、1GB、2GB 内存。本文使用的是 512MB 版本。

全志的 CPU 都比较“自私”,除了简单的芯片手册和用户指南外,基本上只能从官方获取到很少的信息。能获取的信息来源主要包括 PINE64 的 wiki 和 linux-sunxi.org,而网上的信息比较杂、旧,很多信息都是错误的。

我使用了Uboot 官方源,当前版本(2017.03)已经包含了 pine64 的配置文件(pine64_plus_defconfig),编译使用了 Linaro 提供的 armv8 64bit 编译器aarch64-elf。编译过程如下:

make pine64_plus_deefconfig
make -j8 CROSS_COMPILE=aarch64-elf-

编译后会生成多个 bin 文件,我们只需要使用其中的两个 spl/sunxi-spl.binu-boot.bin。接下来重头戏——烧写 bin 文件到 SD 卡。

A64 的启动模式有多种,包括 USB OTG,eMMC,SD卡,NAND Flash 等,pine64 没有板载存储设备,所以只能从 SD 卡启动,而A64 并不能像树莓派 bcm 283x 或 nanopi 的 s5p4418 从 SD 卡上的文件系统加载uboot。A64 是按照 sector 从SD 卡读取数据。

上电后,A64 的 ROM 会从 SD 卡的 第8个 sector 开始读取 sunxi-spl.bin 进行简单的初始工作,然后 spl 会从第80个 sector 开始读取 u-boot.bin ,进入uboot界面,然后由 uboot 加载操作系统。网上有的文档说 u-boot.bin 需要烧写到SD 卡的32KB位置或者19096KB 处,但是这些都不适用于 uboot 官方代码。

u-boot-spl 在完成简单的初始化工作(初始化串口、DRAM、存储介质等)后会执行 common/spl/spl_mmc.c 中的函数 spl_mmc_load_image 从存储卡加载 u-boot.bin,这个函数最终会调用 spl_mmc_load_image 完成读取存储卡、切换到uboot的工作:

  1. 判断 boot mode ,并按顺序检查各个存储介质是否存在启动镜像:

     int spl_mmc_load_image(struct spl_image_info *spl_image,
                    struct spl_boot_device *bootdev)         
     {                                                       
         ...
         boot_mode = spl_boot_mode(bootdev->boot_device);       
         err = -EINVAL;                                         
         switch (boot_mode) {                                   
         case MMCSD_MODE_EMMCBOOT:                              
             ...
         case MMCSD_MODE_RAW:   
             ...
         case MMCSD_MODE_FS: 
             ...
         default:
         ...
         }
     ...
     }
    
  2. 从指定位置加载 u-boot.bin ,其中 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 的值为 0x50,即从SD卡第80块开始读取 u-boot.bin。

     int spl_mmc_load_image(struct spl_image_info *spl_image,
                    struct spl_boot_device *bootdev)         
     {                                                       
    
         ...
    
         case MMCSD_MODE_RAW:                                
             ...
             err = mmc_load_image_raw_sector(spl_image, mmc,        
                 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);          
         ...
     }
    

最后将 bin 文件烧写到sd卡(/dev/sdc):

```
sudo dd if=spl/sunxi-spl.bin of=/dev/sdc bs=1024 seek=8
sudo dd if=u-boot.bin of=/dev/sdc bs=512 seek=80
```

接着如图连上串口线:

现在就可以上电看串口打印了:

U-Boot SPL 2017.03-rc3-00020-ge5bda8a2d8-dirty (Mar 17 2017 - 20:15:04)         
DRAM: 512 MiB                                                                   
Trying to boot from MMC1                                                        
50                                                                              
load legacy                                                                     
copied                                                                          
                                                                                
                                                                                
U-Boot 2017.03-rc3-00020-ge5bda8a2d8-dirty (Mar 17 2017 - 20:15:04 +0800) Allwiy
                                                                                
CPU:   Allwinner A64 (SUN50I)                                                   
Model: Pine64+                                                                  
DRAM:  512 MiB                                                                  
MMC:   SUNXI SD/MMC: 0                                                          
*** Warning - bad CRC, using default environment                                
                                                                                
In:    serial                                                                   
Out:   serial                                                                   
Err:   serial                                                                   
Net:   phy interface7                                                           
eth0: ethernet@01c30000                                                         
starting USB...                                                                 
USB0:   USB EHCI 1.00                                                           
USB1:   USB OHCI 1.0                                                            
scanning bus 0 for devices... 1 USB Device(s) found                             
       scanning usb for storage devices... 0 Storage Device(s) found            
Hit any key to stop autoboot:  0                                                
=> version

U-Boot 2017.03-rc3-00020-ge5bda8a2d8-dirty (Mar 17 2017 - 20:15:04 +0800) Allwinner Technology
aarch64-elf-gcc (Linaro GCC 6.3-2017.02) 6.3.1 20170109
GNU ld (Linaro_Binutils-2017.02) 2.27.0.20161019
=> 

题外话,以前常抱怨 ti、xilinx、freescale 这些芯片厂商的资料太乱了,现在接触了封闭的全志、博通之后,真心为自己以前的错误想法感到惭愧。TI、Xilinx、Freescale 的资料虽然繁杂,但是他们都将自己的产品几乎完全的展示给用户,让用户可以很快的使用,同时还能提供齐全的开源代码,而全志这些恨不得将自己完全封闭起来,这可能也是他们作为系统解决方案商的一种自我保护吧,呵呵。