RTEMS实现FDT support for Beaglebone

47 篇文章 26 订阅
28 篇文章 6 订阅

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  1285000
				600000  1225000
				500000  1125000
				275000  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 */
	.extern	bsp_reset
	.extern	boot_card
	.extern	bsp_start_hook_0
	.extern	bsp_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
	.extern	bsp_start_arm_drop_hyp_mode
	.globl	bsp_start_hyp_vector_table_begin
#endif

	/* Global symbols */
	.globl	_start
	.globl	bsp_start_vector_table_begin
	.globl	bsp_start_vector_table_end
	.globl	bsp_start_vector_table_size
	.globl	bsp_vector_table_size
	.globl	bsp_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:

	ldr	pc, handler_addr_reset
	ldr	pc, handler_addr_undef
	ldr	pc, handler_addr_swi
	ldr	pc, handler_addr_prefetch
	ldr	pc, handler_addr_abort

	/* Program signature checked by boot loader */
	.word	0xb8a06f58

	ldr	pc, handler_addr_irq
	ldr	pc, handler_addr_fiq

handler_addr_reset:

#ifdef BSP_START_RESET_VECTOR
	.word	BSP_START_RESET_VECTOR
#else
	.word	_start
#endif

handler_addr_undef:

	.word	_ARMV4_Exception_undef_default

handler_addr_swi:

	.word	_ARMV4_Exception_swi_default

handler_addr_prefetch:

	.word	_ARMV4_Exception_pref_abort_default

handler_addr_abort:

	.word	_ARMV4_Exception_data_abort_default

handler_addr_reserved:

	.word	_ARMV4_Exception_reserved_default

handler_addr_irq:

	.word	_ARMV4_Exception_interrupt

handler_addr_fiq:

	.word	_ARMV4_Exception_fiq_default

bsp_start_vector_table_end:

#ifdef BSP_START_IN_HYP_SUPPORT
bsp_start_hyp_vector_table_begin:
	ldr	pc, handler_addr_hyp_reset
	ldr	pc, handler_addr_hyp_undef
	ldr	pc, handler_addr_hyp_swi
	ldr	pc, handler_addr_hyp_prefetch
	ldr	pc, handler_addr_hyp_abort
	ldr	pc, handler_addr_hyp_hyp
	ldr	pc, handler_addr_hyp_irq
	ldr	pc, handler_addr_hyp_fiq

handler_addr_hyp_reset:
	.word	_ARMV4_Exception_reserved_default

handler_addr_hyp_undef:
	.word	_ARMV4_Exception_reserved_default

handler_addr_hyp_swi:
	.word	_ARMV4_Exception_reserved_default

handler_addr_hyp_prefetch:
	.word	_ARMV4_Exception_reserved_default

handler_addr_hyp_abort:
	.word	_ARMV4_Exception_reserved_default

handler_addr_hyp_hyp:
	.word	_ARMV4_Exception_reserved_default

handler_addr_hyp_irq:
	.word	_ARMV4_Exception_reserved_default

handler_addr_hyp_fiq:
	.word	_ARMV4_Exception_reserved_default

bsp_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_INITIALIZATION
	mov	r5, r1		/* machine type number or ~0 for DT boot */
	mov	r6, 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 */
	mrc	p15, 0, r0, c0, c0, 5
	and	r0, #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_INITIALIZATION
	mov	r5, r1		/* machine type number or ~0 for DT boot */
	mov	r6, 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_INITIALIZATION
	mov	r5, r1		/* machine type number or ~0 for DT boot */
	mov	r6, r2		/* physical address of ATAGs or DTB */

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

mov	r0, 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 5
uenvcmd=run boot
boot=fatload mmc 0 0x80800000 $app ; fatload mmc 0 0x88000000 $app1 ; bootm 0x80800000 - 0x88000000" >$TMPDIR/$UENV


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


Done.






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值