RTEMS实现FDT support for Beaglebone

来源:互联网 发布:wampserver mac 编辑:程序博客网 时间:2024/06/05 17:08

RTEMS目前多数采用nexus总线进行设备管理,但这是一种较老的方法,目前linux和FreeBSD都改为采用FDT(Flatten Device Tree)进行设备管理,无论是ARM还是PowerPC等。接下来讲讲如何在RTEMS上实现FDT,以BBB为例:


FDT需要dtb文件支持,该文件是二进制文件,包含了设备树,Linux和FreeBSD都可以自动生成该文件,通过dts文件生成,但RTEMS目前不支持,因此dtb文件从FreeBSD参考过来,dts文件如下所示:

/* * Device Tree Source for AM33XX SoC * * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ * * This file is licensed under the terms of the GNU General Public License * version 2.  This program is licensed "as is" without any warranty of any * kind, whether express or implied. */#include <dt-bindings/gpio/gpio.h>#include <dt-bindings/pinctrl/am33xx.h>#include "skeleton.dtsi"/ {compatible = "ti,am33xx";interrupt-parent = <&intc>;aliases {i2c0 = &i2c0;i2c1 = &i2c1;i2c2 = &i2c2;serial0 = &uart0;serial1 = &uart1;serial2 = &uart2;serial3 = &uart3;serial4 = &uart4;serial5 = &uart5;d_can0 = &dcan0;d_can1 = &dcan1;usb0 = &usb0;usb1 = &usb1;phy0 = &usb0_phy;phy1 = &usb1_phy;ethernet0 = &cpsw_emac0;ethernet1 = &cpsw_emac1;};cpus {#address-cells = <1>;#size-cells = <0>;cpu@0 {compatible = "arm,cortex-a8";device_type = "cpu";reg = <0>;/* * To consider voltage drop between PMIC and SoC, * tolerance value is reduced to 2% from 4% and * voltage value is increased as a precaution. */operating-points = </* kHz    uV */720000  1285000600000  1225000500000  1125000275000  1125000>;voltage-tolerance = <2>; /* 2 percentage */clocks = <&dpll_mpu_ck>;clock-names = "cpu";clock-latency = <300000>; /* From omap-cpufreq driver */};};pmu {compatible = "arm,cortex-a8-pmu";interrupts = <3>;};/* * The soc node represents the soc top level view. It is used for IPs * that are not memory mapped in the MPU view or for the MPU itself. */soc {compatible = "ti,omap-infra";mpu {compatible = "ti,omap3-mpu";ti,hwmods = "mpu";};};


文件太大,限于篇幅不全部展示了,可以在FreeBSD/sys/gnu/dts/arm目录下找到该文件。


接下来就是要让BBB从U-Boot启动时,U-Boot采用这个dtb文件中的设备信息,并且在bsp启动阶段传递给BBB。bsp的启动部分是由start.S文件完成的,因此需要对start.S文件进行修改。


c/stc/lib/libbsp/arm/shared/start/start.S

/** * @file * * @brief Boot and system start code. *//* * Copyright (c) 2008, 2016 embedded brains GmbH.  All rights reserved. * *  embedded brains GmbH *  Dornierstr. 4 *  82178 Puchheim *  Germany *  <rtems@embedded-brains.de> * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.org/license/LICENSE. */#include <rtems/asm.h>#include <rtems/system.h>#include <rtems/score/percpu.h>#include <bspopts.h>#include <bsp/irq.h>#include <bsp/linker-symbols.h>/* External symbols */.externbsp_reset.externboot_card.externbsp_start_hook_0.externbsp_start_hook_1.extern bsp_stack_irq_end.extern bsp_stack_fiq_end.extern bsp_stack_abt_end.extern bsp_stack_und_end.extern bsp_stack_svc_end#ifdef RTEMS_SMP.extern bsp_stack_all_size#endif.extern_ARMV4_Exception_undef_default.extern_ARMV4_Exception_swi_default.extern_ARMV4_Exception_data_abort_default.extern_ARMV4_Exception_pref_abort_default.extern_ARMV4_Exception_reserved_default.extern_ARMV4_Exception_interrupt.extern_ARMV4_Exception_fiq_default.extern_ARMV7M_Exception_default#ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION.extern bsp_start_init_registers_core.extern bsp_start_init_registers_banked_fiq.extern bsp_start_init_registers_vfp#endif#ifdef BSP_START_IN_HYP_SUPPORT.externbsp_start_arm_drop_hyp_mode.globlbsp_start_hyp_vector_table_begin#endif/* Global symbols */.globl_start.globlbsp_start_vector_table_begin.globlbsp_start_vector_table_end.globlbsp_start_vector_table_size.globlbsp_vector_table_size.globlbsp_start_hook_0_done.section".bsp_start_text", "ax"#if defined(ARM_MULTILIB_ARCH_V4).arm/* * This is the exception vector table and the pointers to the default * exceptions handlers. */bsp_start_vector_table_begin:ldrpc, handler_addr_resetldrpc, handler_addr_undefldrpc, handler_addr_swildrpc, handler_addr_prefetchldrpc, handler_addr_abort/* Program signature checked by boot loader */.word0xb8a06f58ldrpc, handler_addr_irqldrpc, handler_addr_fiqhandler_addr_reset:#ifdef BSP_START_RESET_VECTOR.wordBSP_START_RESET_VECTOR#else.word_start#endifhandler_addr_undef:.word_ARMV4_Exception_undef_defaulthandler_addr_swi:.word_ARMV4_Exception_swi_defaulthandler_addr_prefetch:.word_ARMV4_Exception_pref_abort_defaulthandler_addr_abort:.word_ARMV4_Exception_data_abort_defaulthandler_addr_reserved:.word_ARMV4_Exception_reserved_defaulthandler_addr_irq:.word_ARMV4_Exception_interrupthandler_addr_fiq:.word_ARMV4_Exception_fiq_defaultbsp_start_vector_table_end:#ifdef BSP_START_IN_HYP_SUPPORTbsp_start_hyp_vector_table_begin:ldrpc, handler_addr_hyp_resetldrpc, handler_addr_hyp_undefldrpc, handler_addr_hyp_swildrpc, handler_addr_hyp_prefetchldrpc, handler_addr_hyp_abortldrpc, handler_addr_hyp_hypldrpc, handler_addr_hyp_irqldrpc, handler_addr_hyp_fiqhandler_addr_hyp_reset:.word_ARMV4_Exception_reserved_defaulthandler_addr_hyp_undef:.word_ARMV4_Exception_reserved_defaulthandler_addr_hyp_swi:.word_ARMV4_Exception_reserved_defaulthandler_addr_hyp_prefetch:.word_ARMV4_Exception_reserved_defaulthandler_addr_hyp_abort:.word_ARMV4_Exception_reserved_defaulthandler_addr_hyp_hyp:.word_ARMV4_Exception_reserved_defaulthandler_addr_hyp_irq:.word_ARMV4_Exception_reserved_defaulthandler_addr_hyp_fiq:.word_ARMV4_Exception_reserved_defaultbsp_start_hyp_vector_table_end:#endif/* Start entry */_start:/* * We do not save the context since we do not return to the boot * loader but preserve r1 and r2 to allow access to bootloader parameters */#ifndef BSP_START_NEEDS_REGISTER_INITIALIZATIONmovr5, r1/* machine type number or ~0 for DT boot */movr6, r2/* physical address of ATAGs or DTB */#else /* BSP_START_NEEDS_REGISTER_INITIALIZATION */bl bsp_start_init_registers_core#endif#ifdef RTEMS_SMP/* Read MPIDR and get current processor index */mrcp15, 0, r0, c0, c0, 5andr0, #0xff


我们所关心的是最开始启动部分,也就是:

/* Start entry */_start:/* * We do not save the context since we do not return to the boot * loader but preserve r1 and r2 to allow access to bootloader parameters */#ifndef BSP_START_NEEDS_REGISTER_INITIALIZATIONmovr5, r1/* machine type number or ~0 for DT boot */movr6, r2/* physical address of ATAGs or DTB */#else /* BSP_START_NEEDS_REGISTER_INITIALIZATION */bl bsp_start_init_registers_core#endif


可以看出在这里,并没有关于fdt的任何信息,首先要对fdt的信息进行复制,也就是需要void bsp_fdt_copy(const void *src)函数支持,该函数位于bsp-fdt.c文件中,在/shared/src文件夹中,因此要在configure.ac文件中包含此文件,使其编译。

libbsp_a_SOURCES += ../../shared/src/bsp-fdt.c


然后可以在start.S文件中添加该函数的运行,注意这里是汇编语言,bl代表跳转到此函数运行,运行完成跳转回来。因此加上:

bl bsp_fdt_copy


函数已经完成了,接下来就是函数中的参数传递问题,如何将U-Boot解析dtb文件后的信息通过bsp_fdt_copy函数的参数传递给RTEMS,这里要查看arm系列的寄存器的存储规则了:




可以看出r0-r4都是传递argument的寄存器,因此r0应该是arm的第一个参数传递的寄存器,因此bsp_fdt_copy的参数应该是r0所传递的,回到start.S文件:

#ifndef BSP_START_NEEDS_REGISTER_INITIALIZATIONmovr5, r1/* machine type number or ~0 for DT boot */movr6, r2/* physical address of ATAGs or DTB */

不难看出,寄存器r2是存储U-Boot传递过来的物理地址的,因此只需将r2的值传递给r0即可:

movr0, r2


这样就完成了U-Boot的参数传递给RTEMS的bsp_fdt_copy函数。



以上就完成了RTEMS的FDT支持 For BBB bsp。


除此之外,如何将dtb文件放入镜像文件中呢?这里需要修改beagle下simscripts文件夹下的sdcard.sh脚本文件,将:

$PREFIX/bin/mkimage -A arm -O rtems -T kernel -a 0x80000000 -e 0x80000000 -n RTEMS -d $TMPDIR/$base.bin.gz $TMPDIR/$app

将这行中的rtems换成linux,这样才能实现FDT启动。


并且将dtb文件的启动地址写入uEnv,txt文件中,如下:

echo "setenv bootdelay 5uenvcmd=run bootboot=fatload mmc 0 0x80800000 $app ; fatload mmc 0 0x88000000 $app1 ; bootm 0x80800000 - 0x88000000" >$TMPDIR/$UENV


这里变量$app1指的是dtb文件,启动地址是0x88000000。


Done.