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:

  1. /* 
  2.  * Device Tree Source for AM33XX SoC 
  3.  * 
  4.  * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ 
  5.  * 
  6.  * This file is licensed under the terms of the GNU General Public License 
  7.  * version 2.  This program is licensed "as is" without any warranty of any 
  8.  * kind, whether express or implied. 
  9.  */  
  10.   
  11. #include <dt-bindings/gpio/gpio.h>  
  12. #include <dt-bindings/pinctrl/am33xx.h>  
  13.   
  14. #include "skeleton.dtsi"  
  15.   
  16. / {  
  17.     compatible = "ti,am33xx";  
  18.     interrupt-parent = <&intc>;  
  19.   
  20.     aliases {  
  21.         i2c0 = &i2c0;  
  22.         i2c1 = &i2c1;  
  23.         i2c2 = &i2c2;  
  24.         serial0 = &uart0;  
  25.         serial1 = &uart1;  
  26.         serial2 = &uart2;  
  27.         serial3 = &uart3;  
  28.         serial4 = &uart4;  
  29.         serial5 = &uart5;  
  30.         d_can0 = &dcan0;  
  31.         d_can1 = &dcan1;  
  32.         usb0 = &usb0;  
  33.         usb1 = &usb1;  
  34.         phy0 = &usb0_phy;  
  35.         phy1 = &usb1_phy;  
  36.         ethernet0 = &cpsw_emac0;  
  37.         ethernet1 = &cpsw_emac1;  
  38.     };  
  39.   
  40.     cpus {  
  41.         #address-cells = <1>;  
  42.         #size-cells = <0>;  
  43.         cpu@0 {  
  44.             compatible = "arm,cortex-a8";  
  45.             device_type = "cpu";  
  46.             reg = <0>;  
  47.   
  48.             /* 
  49.              * To consider voltage drop between PMIC and SoC, 
  50.              * tolerance value is reduced to 2% from 4% and 
  51.              * voltage value is increased as a precaution. 
  52.              */  
  53.             operating-points = <  
  54.                 /* kHz    uV */  
  55.                 720000  1285000  
  56.                 600000  1225000  
  57.                 500000  1125000  
  58.                 275000  1125000  
  59.             >;  
  60.             voltage-tolerance = <2>; /* 2 percentage */  
  61.   
  62.             clocks = <&dpll_mpu_ck>;  
  63.             clock-names = "cpu";  
  64.   
  65.             clock-latency = <300000>; /* From omap-cpufreq driver */  
  66.         };  
  67.     };  
  68.   
  69.     pmu {  
  70.         compatible = "arm,cortex-a8-pmu";  
  71.         interrupts = <3>;  
  72.     };  
  73.   
  74.     /* 
  75.      * The soc node represents the soc top level view. It is used for IPs 
  76.      * that are not memory mapped in the MPU view or for the MPU itself. 
  77.      */  
  78.     soc {  
  79.         compatible = "ti,omap-infra";  
  80.         mpu {  
  81.             compatible = "ti,omap3-mpu";  
  82.             ti,hwmods = "mpu";  
  83.         };  
  84.     };  


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

  1. /** 
  2.  * @file 
  3.  * 
  4.  * @brief Boot and system start code. 
  5.  */  
  6.   
  7. /* 
  8.  * Copyright (c) 2008, 2016 embedded brains GmbH.  All rights reserved. 
  9.  * 
  10.  *  embedded brains GmbH 
  11.  *  Dornierstr. 4 
  12.  *  82178 Puchheim 
  13.  *  Germany 
  14.  *  <rtems@embedded-brains.de> 
  15.  * 
  16.  * The license and distribution terms for this file may be 
  17.  * found in the file LICENSE in this distribution or at 
  18.  * http://www.rtems.org/license/LICENSE. 
  19.  */  
  20.   
  21. #include <rtems/asm.h>  
  22. #include <rtems/system.h>   
  23. #include <rtems/score/percpu.h>  
  24.       
  25. #include <bspopts.h>  
  26. #include <bsp/irq.h>  
  27. #include <bsp/linker-symbols.h>  
  28.   
  29.     /* External symbols */  
  30.     .extern bsp_reset  
  31.     .extern boot_card  
  32.     .extern bsp_start_hook_0  
  33.     .extern bsp_start_hook_1  
  34.     .extern bsp_stack_irq_end  
  35.     .extern bsp_stack_fiq_end  
  36.     .extern bsp_stack_abt_end  
  37.     .extern bsp_stack_und_end  
  38.     .extern bsp_stack_svc_end  
  39. #ifdef RTEMS_SMP  
  40.     .extern bsp_stack_all_size  
  41. #endif  
  42.     .extern _ARMV4_Exception_undef_default  
  43.     .extern _ARMV4_Exception_swi_default  
  44.     .extern _ARMV4_Exception_data_abort_default  
  45.     .extern _ARMV4_Exception_pref_abort_default  
  46.     .extern _ARMV4_Exception_reserved_default  
  47.     .extern _ARMV4_Exception_interrupt  
  48.     .extern _ARMV4_Exception_fiq_default  
  49.     .extern _ARMV7M_Exception_default  
  50.   
  51. #ifdef BSP_START_NEEDS_REGISTER_INITIALIZATION  
  52.     .extern bsp_start_init_registers_core  
  53.     .extern bsp_start_init_registers_banked_fiq  
  54.     .extern bsp_start_init_registers_vfp  
  55. #endif  
  56.   
  57. #ifdef BSP_START_IN_HYP_SUPPORT  
  58.     .extern bsp_start_arm_drop_hyp_mode  
  59.     .globl  bsp_start_hyp_vector_table_begin  
  60. #endif  
  61.   
  62.     /* Global symbols */  
  63.     .globl  _start  
  64.     .globl  bsp_start_vector_table_begin  
  65.     .globl  bsp_start_vector_table_end  
  66.     .globl  bsp_start_vector_table_size  
  67.     .globl  bsp_vector_table_size  
  68.     .globl  bsp_start_hook_0_done  
  69.   
  70.     .section    ".bsp_start_text""ax"  
  71.   
  72. #if defined(ARM_MULTILIB_ARCH_V4)  
  73.   
  74.     .arm  
  75.   
  76. /* 
  77.  * This is the exception vector table and the pointers to the default 
  78.  * exceptions handlers. 
  79.  */  
  80.   
  81. bsp_start_vector_table_begin:  
  82.   
  83.     ldr pc, handler_addr_reset  
  84.     ldr pc, handler_addr_undef  
  85.     ldr pc, handler_addr_swi  
  86.     ldr pc, handler_addr_prefetch  
  87.     ldr pc, handler_addr_abort  
  88.   
  89.     /* Program signature checked by boot loader */  
  90.     .word   0xb8a06f58  
  91.   
  92.     ldr pc, handler_addr_irq  
  93.     ldr pc, handler_addr_fiq  
  94.   
  95. handler_addr_reset:  
  96.   
  97. #ifdef BSP_START_RESET_VECTOR  
  98.     .word   BSP_START_RESET_VECTOR  
  99. #else  
  100.     .word   _start  
  101. #endif  
  102.   
  103. handler_addr_undef:  
  104.   
  105.     .word   _ARMV4_Exception_undef_default  
  106.   
  107. handler_addr_swi:  
  108.   
  109.     .word   _ARMV4_Exception_swi_default  
  110.   
  111. handler_addr_prefetch:  
  112.   
  113.     .word   _ARMV4_Exception_pref_abort_default  
  114.   
  115. handler_addr_abort:  
  116.   
  117.     .word   _ARMV4_Exception_data_abort_default  
  118.   
  119. handler_addr_reserved:  
  120.   
  121.     .word   _ARMV4_Exception_reserved_default  
  122.   
  123. handler_addr_irq:  
  124.   
  125.     .word   _ARMV4_Exception_interrupt  
  126.   
  127. handler_addr_fiq:  
  128.   
  129.     .word   _ARMV4_Exception_fiq_default  
  130.   
  131. bsp_start_vector_table_end:  
  132.   
  133. #ifdef BSP_START_IN_HYP_SUPPORT  
  134. bsp_start_hyp_vector_table_begin:  
  135.     ldr pc, handler_addr_hyp_reset  
  136.     ldr pc, handler_addr_hyp_undef  
  137.     ldr pc, handler_addr_hyp_swi  
  138.     ldr pc, handler_addr_hyp_prefetch  
  139.     ldr pc, handler_addr_hyp_abort  
  140.     ldr pc, handler_addr_hyp_hyp  
  141.     ldr pc, handler_addr_hyp_irq  
  142.     ldr pc, handler_addr_hyp_fiq  
  143.   
  144. handler_addr_hyp_reset:  
  145.     .word   _ARMV4_Exception_reserved_default  
  146.   
  147. handler_addr_hyp_undef:  
  148.     .word   _ARMV4_Exception_reserved_default  
  149.   
  150. handler_addr_hyp_swi:  
  151.     .word   _ARMV4_Exception_reserved_default  
  152.   
  153. handler_addr_hyp_prefetch:  
  154.     .word   _ARMV4_Exception_reserved_default  
  155.   
  156. handler_addr_hyp_abort:  
  157.     .word   _ARMV4_Exception_reserved_default  
  158.   
  159. handler_addr_hyp_hyp:  
  160.     .word   _ARMV4_Exception_reserved_default  
  161.   
  162. handler_addr_hyp_irq:  
  163.     .word   _ARMV4_Exception_reserved_default  
  164.   
  165. handler_addr_hyp_fiq:  
  166.     .word   _ARMV4_Exception_reserved_default  
  167.   
  168. bsp_start_hyp_vector_table_end:  
  169. #endif  
  170.   
  171. /* Start entry */  
  172.   
  173. _start:  
  174.   
  175.     /* 
  176.      * We do not save the context since we do not return to the boot 
  177.      * loader but preserve r1 and r2 to allow access to bootloader parameters 
  178.      */  
  179. #ifndef BSP_START_NEEDS_REGISTER_INITIALIZATION  
  180.     mov r5, r1      /* machine type number or ~0 for DT boot */  
  181.     mov r6, r2      /* physical address of ATAGs or DTB */  
  182. #else /* BSP_START_NEEDS_REGISTER_INITIALIZATION */  
  183.     bl bsp_start_init_registers_core  
  184. #endif  
  185.   
  186. #ifdef RTEMS_SMP  
  187.     /* Read MPIDR and get current processor index */  
  188.     mrc p15, 0, r0, c0, c0, 5  
  189.     and r0, #0xff


What we care about is the start of the start.S, that is:

  1. /* Start entry */  
  2.   
  3. _start:  
  4.   
  5.     /* 
  6.      * We do not save the context since we do not return to the boot 
  7.      * loader but preserve r1 and r2 to allow access to bootloader parameters 
  8.      */  
  9. #ifndef BSP_START_NEEDS_REGISTER_INITIALIZATION  
  10.     mov r5, r1      /* machine type number or ~0 for DT boot */  
  11.     mov r6, r2      /* physical address of ATAGs or DTB */  
  12. #else /* BSP_START_NEEDS_REGISTER_INITIALIZATION */  
  13.     bl bsp_start_init_registers_core  
  14. #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.

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


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:

  1. bl bsp_fdt_copy  

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:

  1. #ifndef BSP_START_NEEDS_REGISTER_INITIALIZATION  
  2.     mov r5, r1      /* machine type number or ~0 for DT boot */  
  3.     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:

  1. mov r0, r2  
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:

  1. $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:

  1. echo "setenv bootdelay 5  
  2. uenvcmd=run boot  
  3. 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.



评论

此博客中的热门博文

RTEMS-libbsd generates drive device firmware

RTEMS Network Transplantation - rtems system initialization process analysis

Add wpa_supplicant_fork command on RTEMS-libbsd