如何让树莓派4上固件的debug日志输出到串口?

第三季奔跑吧旗舰篇视频课程:
   arm64体系结构与编程
   2020年10月1号重磅上线
笨叔带队,以练带学,几十个实验,等您来撸!

树莓派4上的FW

图片


我们玩过树莓派的小伙伴都知道,树莓派4上有几个固件,我们是需要把这些固件拷贝到MicroSD卡里的,这些固件包括如下几个文件。

  1. bootcode.bin:引导程序。树莓派复位上电时,CPU处于复位状态,由GPU来负责启动系统。GPU首先会启动固化在芯片内部的固件(BootROM代码),读取MicroSD卡中的bootcode.bin文件,并装载和运行bootcode.bin中的引导程序。树莓派4B已经把bootcode.bin引导程序固化到SPI Boot EEPROM里。

  2. start4.elf:树莓派4上的GPU固件。bootcode.bin引导程序检索MicroSD卡中的GPU固件,加载固件并启动GPU。

  3. start.elf:树莓派3上的GPU固件。

  4. config.txt:配置文件。GPU启动后读取config.txt配置文件,读取Linux内核映像(比如kernel8.img等)以及内核运行参数等,然后把内核映像加载到共享内存中并启动CPU,CPU结束复位状态开始运行Linux内核。

在树莓派官方文档里提到,把config.txt配置文件中的uart_2ndstage设置为1就能把第二阶段的start4.elf的固件的debug log信息打印到串口。

uart_2ndstage

Setting uart_2ndstage= 1 causes the second-stage loader
 (bootcode.bin on devices prior to the Raspberry Pi  4,
 or the boot code  in the EEPROM  for Raspberry Pi  4 devices)
 and the main firmware (start*.elf) to output diagnostic
 information to UART0.

我们尝试在config.txt配置文件中的uart_2ndstage设置为1,但是start4依然只是打印一句话,并没有打印出debug log。

Starting start4.elf

上面这句话打印之后,需要停顿几十秒才能显示Linux内核的日志,所以,为了方便调试BenOS,我们需要找一个方法来把start4.elf的debug log打印到串口里。

打开start.elf的debug日志

我们从树莓派官网得知,2020年8月20号发布的SPI BootRom固件已经支持了这个功能,另外还需要搭配最新的start4.elf固件,即2020年9月3号发布的。
接下来,我们告诉小伙伴如何更新树莓派4上的固件。

  1. 下载一个最新的树莓派OS,一定是要Raspberry Pi OS,不要使用第三方的树莓派OS,例如ubuntu for Raspberry Pi。
    国内小伙伴可以从清华源中下载。

https:
//mirrors.tuna.tsinghua.edu.cn/raspberry-pi-os-images/raspios_arm64/images/raspios_arm64-2020-08-24/

下载完成之后,使用烧写工具把image 烧写到MircoSD里,在windows下可以使用Win32DiskImager 软件来进行烧录,Linux主机可以使用dd命令。

  1. 修改MircoSD卡中boot分区里面的config.txt配置文件,在这个文件里新增两行。

uart_2ndstage=
1

enable_uart= 1
  1. 把MircoSD插回到树莓派4上,开机。

  2. 配置树莓派4上的wifi。可以使用树莓派上的配置工具.

$ sudo raspi-config

选择“Network Options”来配置WIFI密码等。

图片

  1. 更新软件包。
    树莓派4上的SPI BootRom固件是在rpi-eeprom这个软件包里,第二阶段的固件start4.elf是在raspberrypi-bootloader软件包里。
    这两个软件包更新之后,会自动把最新的BootRom固件烧写到SPI EEPROM里,并且更新start4.elf到MicroSD的boot分区。
    我们最好是全系统的更新软件包。

sudo apt update

sudo apt full-upgrade
sudo reboot

更新完成之后,我们reboot机器。我们就能看到久违的start4.elf的debug日志了。

Starting start4.elf @ 
0xfec00200 partition 
0


MESS: 00: 00: 05.630001: 0: arasan: arasan_emmc_open
MESS: 00: 00: 05.803154: 0: brfs: File read:  /mfs/sd/config.txt
MESS: 00: 00: 05.806352: 0: brfs: File read:  1789 bytes
MESS: 00: 00: 05.834684: 0: brfs: File read:  /mfs/sd/config.txt
MESS: 00: 00: 05.843900: 0: brfs: File read:  1789 bytes
MESS: 00: 00: 06.325273: 0: gpioman: gpioman_get_pin_num: pin DISPLAY_DSI_PORT not defined
MESS: 00: 00: 06.332523: 0: *** Restart logging
MESS: 00: 00: 06.337819: 0: hdmi: HDMI:hdmi_get_state is deprecated, use hdmi_get_display_state instead
MESS: 00: 00: 06.347118: 0: hdmi: HDMI:hdmi_get_state is deprecated, use hdmi_get_display_state instead
MESS: 00: 00: 06.353048: 0: HDMI0: hdmi_pixel_encoding:  300000000
MESS: 00: 00: 06.358516: 0: HDMI1: hdmi_pixel_encoding:  300000000
MESS: 00: 00: 06.368733: 0: dtb_file  'bcm2711-rpi-4-b.dtb'
MESS: 00: 00: 06.377978: 0: brfs: File read:  /mfs/sd/bcm2711-rpi -4-b.dtb
MESS: 00: 00: 06.381224: 0: Loading  'bcm2711-rpi-4-b.dtb' to  0x100 size  0xb96f
MESS: 00: 00: 06.400028: 0: brfs: File read:  47471 bytes
MESS: 00: 00: 06.414733: 0: brfs: File read:  /mfs/sd/overlays/overlay_map.dtb
MESS: 00: 00: 06.472806: 0: brfs: File read:  1423 bytes
MESS: 00: 00: 06.477908: 0: brfs: File read:  /mfs/sd/config.txt
MESS: 00: 00: 06.480832: 0: dtparam: audio=on
MESS: 00: 00: 06.493443: 0: brfs: File read:  1789 bytes
MESS: 00: 00: 06.509298: 0: brfs: File read:  /mfs/sd/overlays/vc4-fkms-v3d.dtbo
MESS: 00: 00: 06.529750: 0: Loaded overlay  'vc4-fkms-v3d'
MESS: 00: 00: 06.574805: 0: brfs: File read:  1238 bytes
MESS: 00: 00: 06.579822: 0: brfs: File read:  /mfs/sd/cmdline.txt
MESS: 00: 00: 06.582401: 0: Read command line  from file  'cmdline.txt':
MESS: 00: 00: 06.588273: 0'console=serial0,115200 console=tty1 root=PARTUUID=2b2231e3-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait plymouth.ignore-serial-consoles'
MESS: 00: 00: 07.648530: 0: brfs: File read:  153 bytes
MESS: 00: 00: 08.864766: 0: brfs: File read:  /mfs/sd/kernel8.img
MESS: 00: 00: 08.867324: 0: Loading  'kernel8.img' to  0x80000 size  0xec4200
MESS: 00: 00: 08.873585: 0: Device tree loaded to  0x2eff4100 (size  0xbead)
MESS: 00: 00: 08.880030: 0: uart:  Set PL011 baud rate to  103448.300000 Hz
MESS: 00: 00: 08.888893: 0: uart: Baud rate change done...
MESS: 00: 00: 08.890915: 0:[     0.000000] Booting Linux on physical CPU  0x0000000000 [ 0x410fd083]
[     0.000000] Linux version  5.4 .51-v8+ (dom@buildbot) (gcc version  5.4 .0  20160609 (Ubuntu/Linaro  5.4 .0 -6ubuntu1~ 16.04 .9)) # 1333 SMP PREEMPT Mon Aug  10  16: 58: 35 BST  2020
[     0.000000] Machine model: Raspberry Pi  4 Model B Rev  1.2

上面是启动Linux内核的日志,接下来我们把MicroSD卡拷贝BenOS的实验代码的bin文件。

Starting start4.elf @ 
0xfec00200 partition 
0


MESS: 00: 00: 05.264585: 0: arasan: arasan_emmc_open
MESS: 00: 00: 05.421982: 0: brfs: File read:  /mfs/sd/config.txt
MESS: 00: 00: 05.424859: 0: brfs: File read:  493 bytes
MESS: 00: 00: 05.453548: 0: brfs: File read:  /mfs/sd/config.txt
MESS: 00: 00: 05.462417: 0: brfs: File read:  493 bytes
MESS: 00: 00: 05.943690: 0: gpioman: gpioman_get_pin_num: pin DISPLAY_DSI_PORT not defined
MESS: 00: 00: 05.950942: 0: *** Restart logging
MESS: 00: 00: 05.956330: 0: hdmi: HDMI:hdmi_get_state is deprecated, use hdmi_get_display_state instead
MESS: 00: 00: 05.965627: 0: hdmi: HDMI:hdmi_get_state is deprecated, use hdmi_get_display_state instead
MESS: 00: 00: 05.971561: 0: HDMI0: hdmi_pixel_encoding:  300000000
MESS: 00: 00: 05.977028: 0: HDMI1: hdmi_pixel_encoding:  300000000
MESS: 00: 00: 05.987254: 0: dtb_file  'bcm2711-rpi-4-b.dtb'
MESS: 00: 00: 05.997023: 0: brfs: File read:  /mfs/sd/bcm2711-rpi -4-b.dtb
MESS: 00: 00: 06.000269: 0: Loading  'bcm2711-rpi-4-b.dtb' to  0x100 size  0xb96f
MESS: 00: 00: 06.019176: 0: brfs: File read:  47471 bytes
MESS: 00: 00: 06.110001: 0: brfs: File read:  /mfs/sd/config.txt
MESS: 00: 00: 06.118301: 0: brfs: File read:  493 bytes
MESS: 00: 00: 06.122231: 0: brfs: File read:  /mfs/sd/cmdline.txt
MESS: 00: 00: 06.125361: 0: Read command line  from file  'cmdline.txt':
MESS: 00: 00: 06.131256: 0'logdev=ttyS1'
MESS: 00: 00: 07.167549: 0: brfs: File read:  13 bytes
MESS: 00: 00: 07.179048: 0: brfs: File read:  /mfs/sd/benos4.bin
MESS: 00: 00: 07.181512: 0: Loading  'benos4.bin' to  0x80000 size  0x4b30
MESS: 00: 00: 07.187507: 0: Device tree loaded to  0x2eff4200 (size  0xbd33)
MESS: 00: 00: 07.193841: 0: uart:  Set PL011 baud rate to  103448.300000 Hz
MESS: 00: 00: 07.202824: 0: uart: Baud rate change done...
Booting at EL2
              Booting at EL1
                            Welcome BenOS!
printk init done
< 0x800880> func_c
BenOS image layout:
  .text.boot:  0x00080000 -  0x000800d8 (    216 B)
       .text:  0x000800d8 -  0x00083ad8 (  14848 B)
     .rodata:  0x00083ad8 -  0x000842fe (   2086 B)
       .data:  0x000842fe -  0x000846d0 (    978 B)
        .bss:  0x00084b30 -  0x000a4f40 ( 132112 B)
test and: p= 0x2
test or: p= 0x3
test andnot: p= 0x1
el =  1
test_asm_goto: a =  1
Bad mode  for Sync Abort handler detected,  far: 0x80002 esr: 0x96000061 - DABT (current EL)
ESR info:
  ESR =  0x96000061
  Exception  class = DABT (current EL), IL =  32 bits
  Data abort:
  SET =  0, FnV =  0
  EA =  0, S1PTW =  0
  CM =  0, WnR =  1
  DFSC = Alignment fault

上面是启动BenOS的日志,其中如下日志对我们调试有帮助。

MESS:
00:
00:
07.179048:
0: brfs: File read: 
/mfs/sd/benos4.bin

MESS: 00: 00: 07.181512: 0: Loading  'benos4.bin' to  0x80000 size  0x4b30
MESS: 00: 00: 07.187507: 0: Device tree loaded to  0x2eff4200 (size  0xbd33)

上面日志告诉我们,固件读取了SD卡里的benos4.bin,其中benos4.bin是我们编写的BenOS的二进制文件,并且把benos加载到0x80000的地址,这些信息对我们调试BenOS非常有帮助。

第三季旗舰篇视频课程:ARM64体系结构与编程,2020年10月1号上线。

图片

上线地址:

淘宝店:shop115683645.taobao.com

第三季视频预览片:

https://space.bilibili.com/277836343/channel/detail?cid=149997


请使用浏览器的分享功能分享到微信等