Implemention of RTEMS FDT support for BBB
Currently, RTEMS still use nexus bus on most of BSP to manage the device, But this is an older method.
At present, Linux and FreeBSD have used FDT (Flatten Device Tree) for equipment management, on most of ARM and PowerPc arch.
Next, talk about how to implement FDT on RTEMS, using BBB as an example.
FDT requires DTB file support, which is a binary file, generated by dtsi file. This bin file contains the device tree. Linux and FreeBSD can automatically generate this file, but RTEMS is not supported at the moment, so the DTB file comes from the FreeBSD reference, as shown in the DTS file below:
At present, Linux and FreeBSD have used FDT (Flatten Device Tree) for equipment management, on most of ARM and PowerPc arch.
Next, talk about how to implement FDT on RTEMS, using BBB as an example.
FDT requires DTB file support, which is a binary file, generated by dtsi file. This bin file contains the device tree. Linux and FreeBSD can automatically generate this file, but RTEMS is not supported at the moment, so the DTB file comes from the FreeBSD reference, as shown in the DTS file below:
- /*
- * 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";
- };
- };
The file is too large to be fully displayed and can be found in the FreeBSD/sys/gnu/dts/arm directory.
The next thing is when BBB boot from U-Boot, U-Boot uses the device information in this DTB file and passes it to BBB during the BSP startup phase. The startup part of the BSP is done by the start.S file, so you need to modify the start.S file.
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
What we care about is the start of the start.S, that is:
- /* 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
As you can see, there is no information about FDT here, So we need add it.
First, copy the information from the FDT, that is, the void bsp_fdt_copy (const void *src) function is required. The function is in the bsp-fdt.c file, in the /shared/src folder, so it contains the file in the configure.ac file to compile it.
You can then add the function in the start.S file, note that here is the assembly language, BL represents the jump to this function to run, run, complete, jump back. So add:
The function is finished, and then there is the parameter passing problem in the function.
How do I pass the information from the U-Boot parsing DTB file to the RTEMS through the arguments of the bsp_fdt_copy function, where the storage rules for the registers of the arm series are to be viewed:
As you can see, r0-r4 is the register that passes the argument, so the R0 should be the register passed by the first parameter of arm.
Therefore, the bsp_fdt_copy parameter should be passed by R0, back to the start.S file:
- #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 */
It is not difficult to see that the register R2 stores the physical address passed by the U-Boot, so you simply pass the value of R2 to the r0:
This completes the bsp_fdt_copy function passed to the RTEMS function of the U-Boot.
The above is done with RTEMS's FDT support For BBB bsp.
Besides, how do you put the DTB file into the mirror file? Here you need to modify the sdcard.sh script file under the simscripts folder under beagle:
- $PREFIX/bin/mkimage -A arm -O rtems -T kernel -a 0x80000000 -e 0x80000000 -n RTEMS -d $TMPDIR/$base.bin.gz $TMPDIR/$app
Change the RTEMS in this line to Linux so that FDT can start.
And writes the startup address of the DTB file to the uEnv, TXT file, as follows:
- echo "setenv bootdelay 5
- uenvcmd=run boot
- boot=fatload mmc 0 0x80800000 $app ; fatload mmc 0 0x88000000 $app1 ; bootm 0x80800000 - 0x88000000" >$TMPDIR/$UENV
At here, the variable $app1 refers to the DTB file, and the boot address is 0x88000000.
Done.
评论
发表评论