zoukankan      html  css  js  c++  java
  • Linux主机上使用交叉编译移植u-boot到树莓派

    0环境

    Linux主机OS:Ubuntu14.04 64位,运行在wmware workstation 10虚拟机

    树莓派版本:raspberry pi 2 B型.

    树莓派OS: Debian Jessie  Raspbian Jessie

    1树莓派的启动过程

    树莓派1,2,3的启动过程大致相同,主要分为3个阶段:ROM上的GPU bootloader启动GPU,GPU启动CPU,CPU直接启动内核或通过u-boot启动内核.

    由于树莓派涉及到GPU的东西不开源,移植u-boot到树莓派并不是真正意义上的bootloader,但是鉴于u-boot广泛的应用,还是很有学习的必要

    树莓派启动过程:

    HOW THE RASPBERRY PI BOOTS UP

    树莓派3启动过程概述

    RPi Software

    2移植u-boot到Debian Jessie系统

    最初想直接移植u-boot到Raspbian,尝试了多次都失败告终.google上u-boot启动raspberry pi大都是基于Debian Jessie,所以先照葫芦画瓢试一把.

    移植u-boot到树莓派参考例程

    (1)最全面的RPi u-boot例程RPi U-Boot

    (2)基于RPi2的例程Booting a Raspberry Pi2, with u-boot and HYP enabled

    (3)基于RPi2,提供现成文件的例程Raspberry Pi 2 – Debian Jessie and U-Boot

    (4)基于mainline u-boot的例程How to compile mainline u-boot for Raspberry Pi ?

     

    MicroSD卡烧写镜像:debian jessie下载地址

    Ubuntu主机上u-boot使用Mainline版本,官网源码 亚马逊下载地址

    Ubuntu主机上文件位置如下

    家目录(/root)下u-boot-2016.09文件夹是解压后的u-boot

    家目录(/root)下script_u-boot文件夹是自己写的环境配置,脚本

    u-boot-2016.09文件夹如下,可以先读读README

    script_u-boot文件夹内如下图,从左到右是scr配置文件,环境配置文件,生成u-boot.bin文件,生成scr文件

    env_gnueabihf_mkimage文件代码如下

    #添加树莓派的交叉编译工具链路径(主机是64位)
    export PATH
    =$PATH:/root/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin #指定编译目标架构为arm,编译器为PATH路径中的交叉编译器

    export ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

    树莓派交叉编译工具链地址https://github.com/raspberrypi/tools

    树莓派交叉编译可以参考Linux主机上实现树莓派的交叉编译及文件传输,远程登陆

    在后续操作之前先source一下这个文件使配置生效,关闭终端或者重新登陆Ubuntu需要再次source

    用echo查看变量,注意使用tab自动补全路径

    make_ubootbin文件代码如下

    #从脚本文件夹切换到u-boot文件夹下
    cd /root/u-boot-2016.09
    
    #配置适用于树莓派2的u-boot
    make rpi_2_defconfig
    
    #编译
    make all
    #返回脚本文件夹 cd
    /root/script_u-boot

    切换路径是因为执行这个脚本是在script_u-boot文件夹,而make命令执行Makefile是在u-boot-2016.09文件夹,最后切回路径方便后续的source

    这里make rpi_2_defconfig是针对树莓派2板,其它版本树莓派的make config参考前文的移植u-boot到树莓派参考例程(1)(4)

    执行make_ubootbin无报错

    在u-boot-2016.09文件夹下生成了u-boot.bin

    把debian jessie的SD卡通过读卡器插到电脑,注意先选中虚拟机的Ubuntu系统,Ubuntu会自动读取(mount)SD卡

    rootfs(根文件系统)分区:

    firmware(debian jessie下的启动分区):

    关于启动分区config.txt bootcode.bin cmdline.txt start.elf kernel7.img等文件,参考前文的树莓派启动过程

    至此可以把u-boot.bin拷到sd卡的firmware(对于debian jessie系统)

    然后在config.txt添加

    kernel=u-boot.bin

    指定用u-boot.bin启动内核kernel7,config.txt是内核的配置文件,类似电脑的BIOS配置

    配置内核的方法:

    一种方法是在u-boot阶段手动输入命令,而mainline版本的u-boot不支持usb输入,尝试过例程(1)中的Stephen Warren版本,也无法输入(问题还有待调查)

    另一种是把u-boot中输入的命令写到一个脚本文件,通过mkimage命令将这个脚本生成.scr镜像,然后放到启动分区,u-boot会自动读取脚本来启动内核,这样更简单更容易修改,但是不利于调试错误信息

    用第一种方法可以拔出SD卡,在树莓派上配置内核启动,注意在u-boot阶段只能通过HDMI外接显示屏或者串口来查看输出信息.关于串口可以参考RPi Serial Connection

    用第二种方法是在Ubuntu主机上生成boot.scr镜像,先写一个配置文件:在script_u-boot文件夹下新建configure_scr_file,内容如下

    #设置环境为树莓派2
    setenv machid 0x00000c42
    
    #设置打印信息,允许HDMI,允许串口,设置根文件系统路径和类型 setenv bootargs
    "earlyprintk console=tty0 console=ttyAMA0 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait noinitrd"
    #保存环境配置 saveenv
    #载入内核镜像到MMC0的第一分区 fatload mmc
    0:1 ${kernel_addr_r} kernel7.img
    #启动内核 bootz ${kernel_addr_r}
     

    以上命令的语法都是u-boot软件规定,关于命令的细节可以参考RPi U-Boot   官方文档U-Bootdoc   

    然后新建一个脚本make_ubootscr生成scr镜像,make_ubootscr内容如下

    #生成boot.scr镜像文件
    mkimage -A arm -O linux -T script -C none -a 0x00000000 -e 0x00000000 -n "RPi2 Boot Script" -d /path/to/script /boot/firmware/boot.scr

    /path/to/script是configure_scr_file的路径,替换后如下

    mkimage -A arm -O linux -T script -C none -a 0x00000000 -e 0x00000000 -n "RPi2 Boot Script" -d /root/script_u-boot/configure_scr_file /boot/firmware/boot.scr

    source报错,提示未安装mkimage

    命令找不到通常是未安装软件,或者没添加路径,mkimage应该是包含在u-boot软件中的,由于之前用过树莓派交叉编译工具链的经验,在u-boot-2016.09文件夹的tools文件夹找到了mkimage程序

    更通用的是用find命令查找

    find 查找路径 -name 文件名

    看来是没有添加mkimage的路径到环境变量,只需在env_gnueabihf_mkimage添加路径然后source

    env_gnueabihf_mkimage修改如下

    export PATH=$PATH:/root/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:/root/u-boot-2016.09/tools
    
    export ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

    提示路径不存在

    这时就需要了解这条mkimage命令的具体含义了,参考mkimage - Generate image for U-Boot

    /boot/firmware/boot.scr是生成boot.scr文件的路径,如果在树莓派上直接操作这个路径就是启动分区,但是我是在Ubuntu主机操作,SD卡是挂载到Ubuntu主机的路径被改变了

    查看块设备可以用命令

    lsblk

    sdb就是SD卡,sdb1是firmware启动分区,sdb2是rootfs文件系统分区

    事实上插入SD卡时Ubuntu自动把SD卡mount到了主机的/media路径,所以前面才能对u-boot.bin直接复制粘贴操作

    但是想把SD卡的第一分区挂载到其它路径,比如主机的/mnt文件夹下,应该

    mount /dev/sdb1 /mnt

    注意设备的实际路径和挂载后路径的区别,/dev/xxx才是实际的设备路径

    在运行原版debian jessie的树莓派2上查看SD卡挂载路径如下

    debian jessie把SD卡两个分区mmcblk0p1,mmcblk0p2分别挂载到/root和根目录

    可以把boot.scr直接生成到firmware下(先在Ubuntu插好SD卡)

    mkimage -A arm -O linux -T script -C none -a 0x00000000 -e 0x00000000 -n "RPi2 Boot Script" -d /root/script_u-boot/configure_scr_file /media/boot/firmware/boot.scr

    更推荐生成在其它目录(比如u-boot-2016.09文件夹)再拷到SD卡,最终改为如下,-n是生成的文件名

    mkimage -A arm -O linux -T script -C none -a 0x00000000 -e 0x00000000 -n boot.scr -d /root/script_u-boot/configure_scr_file /root/u-boot-2016.09/boot.scr

    成功生成boot.scr

    在把u-boot.bin boot.scr拷到SD卡的firmware以后,确认config.txt添加了kernel=u-boot.bin就可以拔出SD卡启动树莓派2了

    启动过程如下

    进入登陆界面

    登陆名(login):root  

    密码(password):debian

    登录成功,至此在debian jessie上的u-boot移植完成

    在主机上交叉编译生成boot.bin,也可以不添加环境变量ARCH,CROSS_COMPILE,直接在make语句指定编译器

    make_ubootbin可以改为如下

    cd /root/u-boot-2016.09
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- rpi_2_defconfig 
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 cd /root/script_u-boot
    -j4是采用四核处理器四线程编译,取决于主机CPU WIN7下查看CPU核心数

    3移植u-boot到Raspbian Jessie系统

    有了前面的尝试,后面的就水到渠成了.raspbian jessie我用的2015年的官网镜像,新版应该区别不大 raspbian下载

    如果直接把刚才生成的u-boot.bin boot.scr拷到raspbian,在config.txt添加kernel=u-boot.bin

    启动后停留在starting kernel...

    信息显示kernel7已经通过boot.scr读取了,说明问题出在启动内核之后的部分

    对比一下debian jessie和raspbian jessie的分区,文件系统都一样,就是启动分区有差别

    debian jessie的启动分区

    raspbian jessie的启动分区

    发现raspbian多了一个kernel.img,几个.dtb文件,overlay里面也是.dtb文件

    参考RPi U-Boot后感觉需要加载dtb(Device Tree binary)

    修改boot.scr的配置文件(configure_scr_file)的内容如下

    setenv machid 0x00000c42
    #添加变量fdtfile的值为bcm2709-rpi-2-b.dtb
    setenv fdtfile bcm2709-rpi-2-b.dtb
    setenv bootargs "earlyprintk console=tty0 console=ttyAMA0 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait noinitrd"
    saveenv
    fatload mmc 0:1 ${kernel_addr_r} kernel7.img
    #载入fdtfile的值
    fatload mmc 0:1 ${fdt_addr_r} ${fdtfile}
    bootz ${kernel_addr_r} - ${fdt_addr_r}

    这里添加bcm2709-rpi-2-b.dtb是因为使用树莓派2,如果是其它版本酌情修改

    然后source生成boot.scr

    source make_ubootbin

    将新的boot.scr拷到boot分区,u-boot.bin和之前完全相同,config.txt添加kernel=u-boot.bin

    主机上拔出SD卡,启动树莓派

     自动登录进入桌面

     至此u-boot在raspbian jessie上移植完成 

    本文允许转载,转载请声明原文地址http://www.cnblogs.com/cursorhu/p/5896800.html

  • 相关阅读:
    SAP S/4HANA extensibility扩展原理介绍
    SAP CRM系统订单模型的设计与实现
    使用nodejs代码在SAP C4C里创建Individual customer
    SAP Cloud for Customer Account和individual customer的区别
    Let the Balloon Rise map一个数组
    How Many Tables 简单并查集
    Heap Operations 优先队列
    Arpa’s obvious problem and Mehrdad’s terrible solution 思维
    Passing the Message 单调栈两次
    The Suspects 并查集
  • 原文地址:https://www.cnblogs.com/cursorhu/p/5896800.html
Copyright © 2011-2022 走看看