How to add support for different board variant (e.g. SOLO vs QUAD, 2GB vs 512MB)

Here you will find information about how to add support for different board variant into uBoot, Kernel and YOCTO meta layer.

Content

See also

Prepare a host machine

Before you start doing any changes, you may want to go through: How to start with Software >

Update uBoot

Get the source code

You have two options to get the source code. You can download it directly from github or you can edit the uBoot files in your YOCTO OpenRex project.

Option 1: Get the uBoot source code from github
git clone -b jethro https://github.com/FEDEVEL/openrex-uboot-v2015.10.git
cd openrex-uboot-v2015.10
Option 2: Find uBoot source code located inside your YOCTO project

Usualy the uBoot source code is located inside your build directory. The path may look like this:
cd ~/fsl-community-bsp/build-openrex/tmp/work/imx6q_openrex-poky-linux-gnueabi/u-boot-openrex/v2015.10+gitAUTOINC+d542ed07a4-r0/git

Install & select cross compiler

If you do not have any compiler installed (or you are not sure)
apt-get install gcc-arm-linux-gnueabihf
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
If you have a compiler installed
export CROSS_COMPILE=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi-
export ARCH=arm

Edit files

Edit: "board/fedevel/mx6openrex/mx6s_2x_mt41k128.cfg"
In case your memory configuration is different from your existing board, you may need to create a memory cfg file. Copy the existing cfg to a new one and edit it:
cp board/fedevel/mx6openrex/mx6q_4x_mt41j256.cfg board/fedevel/mx6openrex/mx6s_2x_mt41k128.cfg
gedit board/fedevel/mx6openrex/mx6s_2x_mt41k128.cfg
Update the "mx6s_2x_mt41k128.cfg" file based on *.inc file which you used for calibration in DDR Stress Tool. Here is an example of "OpenRex_512MB_DDR3_register_programming_aid_v0.4.inc" located on my PC machine inside "DDR_Stress_Tester_V1.0.2\Binary\scripts\MX6_series_boards\SabreSD\RevC_and_RevB\MX6Solo\":
//=============================================================================			
//init script for i.MX6Solo DDR3 SabreSD			
//=============================================================================			
// Revision History			
// v01			
//=============================================================================			
			
wait = on			
//=============================================================================			
// Disable	WDOG		
//=============================================================================			
//setmem /16	0x020bc000 =	0x30	
			
//=============================================================================			
// Enable all clocks (they are disabled by ROM code)			
//=============================================================================			
setmem /32	0x020c4068 =	0xffffffff	
setmem /32	0x020c406c =	0xffffffff	
setmem /32	0x020c4070 =	0xffffffff	
setmem /32	0x020c4074 =	0xffffffff	
setmem /32	0x020c4078 =	0xffffffff	
setmem /32	0x020c407c =	0xffffffff	
setmem /32	0x020c4080 =	0xffffffff	
setmem /32	0x020c4084 =	0xffffffff	
			
//=============================================================================			
// IOMUX			
//=============================================================================			
//DDR IO TYPE:			
setmem /32	0x020e0774 =	0x000C0000	// IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE 
setmem /32	0x020e0754 =	0x00000000	// IOMUXC_SW_PAD_CTL_GRP_DDRPKE 
			
//CLOCK:			
setmem /32	0x020e04ac =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0
setmem /32	0x020e04b0 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1
			
//ADDRESS:			
setmem /32	0x020e0464 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS
setmem /32	0x020e0490 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS
setmem /32	0x020e074c =	0x00000030	// IOMUXC_SW_PAD_CTL_GRP_ADDDS 
			
//CONTROL:			
setmem /32	0x020e0494 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET
			
setmem /32	0x020e04a0 =	0x00000000	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 - DSE can be configured using Group Control Register: IOMUXC_SW_PAD_CTL_GRP_CTLDS
setmem /32	0x020e04b4 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0
setmem /32	0x020e04b8 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1
setmem /32	0x020e076c =	0x00000030	// IOMUXC_SW_PAD_CTL_GRP_CTLDS 
			
//DATA STROBE:			
setmem /32	0x020e0750 =	0x00020000	// IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL 
			
setmem /32	0x020e04bc =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 
setmem /32	0x020e04c0 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 
setmem /32	0x020e04c4 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 
setmem /32	0x020e04c8 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 
//setmem /32	0x020e04cc =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4 , not used for 32-bit bus
//setmem /32	0x020e04d0 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5 , not used for 32-bit bus
//setmem /32	0x020e04d4 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6 , not used for 32-bit bus
//setmem /32	0x020e04d8 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7 , not used for 32-bit bus
			
//DATA:			
setmem /32	0x020e0760 =	0x00020000	// IOMUXC_SW_PAD_CTL_GRP_DDRMODE
			
setmem /32	0x020e0764 =	0x00000028	// IOMUXC_SW_PAD_CTL_GRP_B0DS 
setmem /32	0x020e0770 =	0x00000028	// IOMUXC_SW_PAD_CTL_GRP_B1DS 
setmem /32	0x020e0778 =	0x00000028	// IOMUXC_SW_PAD_CTL_GRP_B2DS 
setmem /32	0x020e077c =	0x00000028	// IOMUXC_SW_PAD_CTL_GRP_B3DS 
//setmem /32	0x020e0780 =	0x00000030	// IOMUXC_SW_PAD_CTL_GRP_B4DS , not used for 32-bit bus
//setmem /32	0x020e0784 =	0x00000030	// IOMUXC_SW_PAD_CTL_GRP_B5DS , not used for 32-bit bus
//setmem /32	0x020e078c =	0x00000030	// IOMUXC_SW_PAD_CTL_GRP_B6DS , not used for 32-bit bus
//setmem /32	0x020e0748 =	0x00000030	// IOMUXC_SW_PAD_CTL_GRP_B7DS , not used for 32-bit bus
			
setmem /32	0x020e0470 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0
setmem /32	0x020e0474 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1
setmem /32	0x020e0478 =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2
setmem /32	0x020e047c =	0x00000028	// IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3
//setmem /32	0x020e0480 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4, not used for 32-bit bus
//setmem /32	0x020e0484 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5, not used for 32-bit bus
//setmem /32	0x020e0488 =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6, not used for 32-bit bus
//setmem /32	0x020e048c =	0x00000030	// IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7, not used for 32-bit bus
			
//=============================================================================			
// DDR Controller Registers			
//=============================================================================			
// Manufacturer:	Micron		
// Device Part Number:	MT41J128M16HA-15E		
// Clock Freq.: 	400MHz		
// Density per CS in Gb: 	4		
// Chip Selects used:	1		
// Number of Banks:	8		
// Row address:    	14		
// Column address: 	10		
// Data bus width	32		
//=============================================================================			
setmem /32	0x021b0800 =	0xa1390003 	// DDR_PHY_P0_MPZQHWCTRL, enable both one-time & periodic HW ZQ calibration.
			
// write leveling, based on Freescale board layout and T topology			
// For target board, may need to run write leveling calibration 			
// to fine tune these settings			
// If target board does not use T topology, then these registers			
// should either be cleared or write leveling calibration can be run	

setmem /32	0x021b080c = 	0x005D0062 //!MM orig:0x00420043	
setmem /32	0x021b0810 = 	0x00470050 //!MM orig:0x0028002A	
			
//######################################################			
//calibration values based on calibration compare of 0x00ffff00:			
//Note, these calibration values are based on Freescale's board			
//May need to run calibration on target board to fine tune these 			
//######################################################			
			
//Read DQS Gating calibration			
setmem /32	0x021b083c =	0x42600260  //!MM orig: 0x4238023C	// MPDGCTRL0 PHY0
setmem /32	0x021b0840 =	0x02380240  //!MM orig: 0x020C0218	// MPDGCTRL1 PHY0
			
//Read calibration			
setmem /32	0x021b0848 =	0x42444448  //!MM orig: 0x40444646	// MPRDDLCTL PHY0
			
//Write calibration			
setmem /32	0x021b0850 =	0x36383434  //!MM orig: 0x36383034	// MPWRDLCTL PHY0
			
//read data bit delay: (3 is the reccommended default value, although out of reset value is 0):			
setmem /32	0x021b081c =	0x33333333	// DDR_PHY_P0_MPREDQBY0DL3
setmem /32	0x021b0820 =	0x33333333	// DDR_PHY_P0_MPREDQBY1DL3
setmem /32	0x021b0824 =	0x33333333	// DDR_PHY_P0_MPREDQBY2DL3
setmem /32	0x021b0828 =	0x33333333	// DDR_PHY_P0_MPREDQBY3DL3
//setmem /32	0x021b481c =	0x33333333	// DDR_PHY_P1_MPREDQBY0DL3, not used for 32-bit bus
//setmem /32	0x021b4820 =	0x33333333	// DDR_PHY_P1_MPREDQBY1DL3, not used for 32-bit bus
//setmem /32	0x021b4824 =	0x33333333	// DDR_PHY_P1_MPREDQBY2DL3, not used for 32-bit bus
//setmem /32	0x021b4828 =	0x33333333	// DDR_PHY_P1_MPREDQBY3DL3, not used for 32-bit bus
			
// Complete calibration by forced measurement:			
setmem /32	0x021b08b8 =	0x00000800 	// DDR_PHY_P0_MPMUR0, frc_msr
//setmem /32	0x021b48b8 =	0x00000800 	// DDR_PHY_P1_MPMUR0, frc_msr, not used for 32-bit bus
			
//MMDC init:			
setmem /32	0x021b0004 =	0x00020025	// MMDC0_MDPDC 
setmem /32	0x021b0008 =	0x00333030	// MMDC0_MDOTC
setmem /32	0x021b000c =	0x676B5313	// MMDC0_MDCFG0
setmem /32	0x021b0010 =	0xB66E8B63	// MMDC0_MDCFG1
setmem /32	0x021b0014 =	0x01FF00DB	// MMDC0_MDCFG2
setmem /32	0x021b0018 =	0x00011740  //!MM orig: 0x00001740	// MMDC0_MDMISC
//NOTE about MDMISC RALAT:			
//MDMISC: RALAT kept to the high level of 5 to ensure stable operation at 528MHz. 			
//MDMISC: consider reducing RALAT if your 528MHz board design allow that. Lower RALAT benefits: 			
//a. better operation at low frequency			
//b. Small performence improvment			
			
setmem /32	0x021b001c =	0x00008000	// MMDC0_MDSCR, set the Configuration request bit during MMDC set up
setmem /32	0x021b002c =	0x000026d2	// MMDC0_MDRWD; recommend to maintain the default values
setmem /32	0x021b0030 =	0x006B1023	// MMDC0_MDOR
setmem /32	0x021b0040 =	0x00000027	// CS0_END 
			
setmem /32	0x021b0000 =	0x84190000	// MMDC0_MDCTL
			
// Mode register writes			
setmem /32	0x021b001c =	0x04008032	// MMDC0_MDSCR, MR2 write, CS0
setmem /32	0x021b001c =	0x00008033	// MMDC0_MDSCR, MR3 write, CS0
setmem /32	0x021b001c =	0x00048031	// MMDC0_MDSCR, MR1 write, CS0
setmem /32	0x021b001c =	0x05208030	// MMDC0_MDSCR, MR0 write, CS0
setmem /32	0x021b001c =	0x04008040	// MMDC0_MDSCR, ZQ calibration command sent to device on CS0
			
//setmem /32	0x021b001c =	0x0400803A	// MMDC0_MDSCR, MR2 write, CS1
//setmem /32	0x021b001c =	0x0000803B	// MMDC0_MDSCR, MR3 write, CS1
//setmem /32	0x021b001c =	0x00048039	// MMDC0_MDSCR, MR1 write, CS1
//setmem /32	0x021b001c =	0x05208038	// MMDC0_MDSCR, MR0 write, CS1
//setmem /32	0x021b001c =	0x04008048	// MMDC0_MDSCR, ZQ calibration command sent to device on CS1
			
			
setmem /32	0x021b0020 =	0x00005800	// MMDC0_MDREF
setmem /32	0x021b0818 =	0x00011117	// DDR_PHY_P0_MPODTCTRL
//setmem /32	0x021b4818 =	0x00011117	// DDR_PHY_P1_MPODTCTRL, not used for 32-bit bus
			
			
setmem /32	0x021b0004 =	0x00025565	// MMDC0_MDPDC with PWDT bits set
setmem /32	0x021b0404 = 	0x00011006	// MMDC0_MAPSR ADOPT power down enabled, MMDC will enter automatically to self-refresh while the number of idle cycle reached.
			
setmem /32	0x021b001c =	0x00000000	// MMDC0_MDSCR, clear this register (especially the configuration bit as initialization is complete) 
Here is the board/fedevel/mx6openrex/mx6s_2x_mt41k128.cfg after changes:
/*
 * Copyright (C) 2015 Voipac, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 *
 * Refer docs/README.imxmage for more details about how-to configure
 * and create imximage boot image
 *
 * The syntax is taken as close as possible with the kwbimage
 */

/* image version */

IMAGE_VERSION 2

/*
 * Boot Device : one of
 * spi, sd (the board has no nand neither onenand)
 */

BOOT_FROM	sd

/*
//=============================================================================			
// DDR Controller Registers			
//=============================================================================			
// Manufacturer:	Micron		
// Device Part Number:	MT41K256M16HA-125		
// Clock Freq.: 	400MHz		
// Density per CS in Gb: 	8		
// Chip Selects used:	1		
// Number of Banks:	8		
// Row address:    	15		
// Column address: 	10		
// Data bus width	32		
//=============================================================================	
*/

/*
 * Device Configuration Data (DCD)
 *
 * Each entry must have the format:
 * Addr-type           Address        Value
 *
 * where:
 *	Addr-type register length (1,2 or 4 bytes)
 *	Address	  absolute address of the register
 *	value	  value to be stored in the register
 */
DATA 4	0x020e0774 0x000C0000
DATA 4	0x020e0754 0x00000000
DATA 4	0x020e04ac 0x00000028
DATA 4	0x020e04b0 0x00000028
DATA 4	0x020e0464 0x00000028
DATA 4	0x020e0490 0x00000028
DATA 4	0x020e074c 0x00000028
DATA 4	0x020e0494 0x00000028
DATA 4	0x020e04a0 0x00000000
DATA 4	0x020e04b4 0x00000028
DATA 4	0x020e04b8 0x00000028
DATA 4	0x020e076c 0x00000028
DATA 4	0x020e0750 0x00020000
DATA 4	0x020e04bc 0x00000028
DATA 4	0x020e04c0 0x00000028
DATA 4	0x020e04c4 0x00000028
DATA 4	0x020e04c8 0x00000028
/* 
DATA 4	0x020e04cc 0x00000028
DATA 4	0x020e04d0 0x00000028
DATA 4	0x020e04d4 0x00000028
DATA 4	0x020e04d8 0x00000028
*/
DATA 4	0x020e0760 0x00020000
DATA 4	0x020e0764 0x00000028
DATA 4	0x020e0770 0x00000028
DATA 4	0x020e0778 0x00000028
DATA 4	0x020e077c 0x00000028
/*
DATA 4	0x020e0780 0x00000028
DATA 4	0x020e0784 0x00000028
DATA 4	0x020e078c 0x00000028
DATA 4	0x020e0748 0x00000028
*/
DATA 4	0x020e0470 0x00000028
DATA 4	0x020e0474 0x00000028
DATA 4	0x020e0478 0x00000028
DATA 4	0x020e047c 0x00000028
/*
DATA 4	0x020e0480 0x00000028
DATA 4	0x020e0484 0x00000028
DATA 4	0x020e0488 0x00000028
DATA 4	0x020e048c 0x00000028
*/
DATA 4	0x021b001c 0x00008000
DATA 4	0x021b0800 0xA1390003
DATA 4	0x021b080c 0x005D0062
DATA 4	0x021b0810 0x00470050
/*
DATA 4	0x021b480c 0x00000000
DATA 4	0x021b4810 0x00000000
*/
DATA 4	0x021b083c 0x42600260
DATA 4	0x021b0840 0x02380240
/*
DATA 4	0x021b483c 0x00000000
DATA 4	0x021b4840 0x00000000
*/
DATA 4	0x021b0848 0x42444448
/*
DATA 4	0x021b4848 0x40404040
*/
DATA 4	0x021b0850 0x36383434
/*
DATA 4	0x021b4850 0x40404040
*/
DATA 4	0x021b081c 0x33333333
DATA 4	0x021b0820 0x33333333
DATA 4	0x021b0824 0x33333333
DATA 4	0x021b0828 0x33333333
/*
DATA 4	0x021b481c 0x33333333
DATA 4	0x021b4820 0x33333333
DATA 4	0x021b4824 0x33333333
DATA 4	0x021b4828 0x33333333
*/
DATA 4	0x021b08b8 0x00000800
/*
DATA 4	0x021b48b8 0x00000800
*/
DATA 4	0x021b0004 0x0002002D  
DATA 4	0x021b0008 0x00333040  
DATA 4	0x021b000c 0x676B52F3  
DATA 4	0x021b0010 0xB66D8B63  
DATA 4	0x021b0014 0x01FF00DB  
DATA 4	0x021b0018 0x00011740  
DATA 4	0x021b001c 0x00008000  
DATA 4	0x021b002c 0x000026D2  
DATA 4	0x021b0030 0x006B1023  
DATA 4	0x021b0040 0x00000017  //MDPC CS0 END0
DATA 4	0x021b0000 0x83190000  //MDCTL Number of ADDR
DATA 4	0x021b001c 0x02008032
DATA 4	0x021b001c 0x00008033
DATA 4	0x021b001c 0x00048031
DATA 4	0x021b001c 0x15208030
DATA 4  0x021b001c 0x04008040
/*
DATA 4	0x021b001c 0x0200803A
DATA 4	0x021b001c 0x0000803B
DATA 4	0x021b001c 0x00048039
DATA 4	0x021b001c 0x15208038
DATA 4  0x021b001c 0x04008048
*/
DATA 4	0x021b0020 0x00007800
DATA 4	0x021b0818 0x00022227
/*
DATA 4	0x021b4818 0x00022227
*/
DATA 4	0x021b0004 0x0002556D
DATA 4	0x021b0404 0x00011006
DATA 4	0x021b001c 0x00000000

/* set the default clock gate to save power */
DATA 4 0x020c4068 0x00C03F3F
DATA 4 0x020c406c 0x0030FC03
DATA 4 0x020c4070 0x0FFFC000
DATA 4 0x020c4074 0x3FF00000
DATA 4 0x020c4078 0x00FFF300
DATA 4 0x020c407c 0x0F0000C3
DATA 4 0x020c4080 0x000003FF

/* enable AXI cache for VDOA/VPU/IPU */
DATA 4 0x020e0010 0xF00000CF
/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
DATA 4 0x020e0018 0x007F007F
DATA 4 0x020e001c 0x007F007F
Important: When you are changing memory size, double check CS0_END in MDPC register (0x021b0040) and Address width in MDCTL register (0x021b0000). Based on MDCTL settings, uBoot will determine memory size (it's the size you see when uBoot boots up and says like "DRAM: 512 MiB" or "DRAM: 2 GiB")

Edit: "configs/mx6sopenrex_defconfig"
In the next step, create a config file for this board variant. The name of this config file will be used during "bitbake". Let's copy an existing config into a new one:
cp configs/mx6qopenrex_defconfig configs/mx6sopenrex_defconfig
gedit configs/mx6sopenrex_defconfig
In defconfig we can specify some parameters about CPU, memory size, board name .... Here is an example how the file may look then:
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6OPENREX=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/fedevel/mx6openrex/mx6s_2x_mt41k128.cfg,MX6S,DDR_SIZE=SZ_512M,BOARD_TYPE_PREFIX=\"imx6s-\",BOARD_TYPE_POSTFIX=\"\""
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_SPI_FLASH=y
CONFIG_SYS_PROMPT="OpenRex U-Boot> "
Notice the line 4. In the line we set some parameters which we will use later.

Edit: "include/configs/mx6openrex.h"
Now, we need to update the lines which used the fixed values. Replace them with our parameters from "mx6sopenrex_defconfig".

Before
...
#define PHYS_SDRAM_SIZE		(2u * 1024 * 1024 * 1024) //2GB default for QUAD

#define CONFIG_OPENREX_DEFAULT_ARCH_PREFIX  "imx6q-"
#define CONFIG_OPENREX_DEFAULT_ARCH_POSTFIX  ""
...
After
...
#define CONFIG_OPENREX_DEFAULT_ARCH_PREFIX  CONFIG_BOARD_TYPE_PREFIX
#define CONFIG_OPENREX_DEFAULT_ARCH_POSTFIX  CONFIG_BOARD_TYPE_POSTFIX

#if defined(CONFIG_DDR_SIZE) 
#define PHYS_SDRAM_SIZE         CONFIG_DDR_SIZE
#else
#define PHYS_SDRAM_SIZE         SZ_256M
#warning "Using default SDRAM size"
#endif
...
*Note: Notice, that you need to use "CONFIG_" prefix for the parameters defined in "mx6sopenrex_defconfig".

Edit: "include/configs/mx6openrex.h"
Do not forget to update also existing files and add the new parameters into existing "*_defconfig".
gedit configs/mx6qopenrex_defconfig
Before
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6OPENREX=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/fedevel/mx6openrex/mx6q_4x_mt41j256.cfg,MX6Q"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_SPI_FLASH=y
CONFIG_SYS_PROMPT="OpenRex U-Boot> "
After
CONFIG_ARM=y
CONFIG_ARCH_MX6=y
CONFIG_TARGET_MX6OPENREX=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/fedevel/mx6openrex/mx6q_4x_mt41j256.cfg,MX6Q,DDR_SIZE=SZ_2G,BOARD_TYPE_PREFIX=\"imx6q-\",BOARD_TYPE_POSTFIX=\"\""
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_SPI_FLASH=y
CONFIG_SYS_PROMPT="OpenRex U-Boot> "

Compile uBoot

Compile and test the new board configuration. Use the new "mx6sopenrex_config":
make distclean
make mx6sopenrex_config
make
cp u-boot.imx /tftp/imx6/u-boot-imx6s-openrex.imx

Test uBoot

The best way to test a completely new uBoot is to use MFGTOOL. If you are not sure what it is, have a look at: How to setup MFGTOOL

Once you have MFGTOOL installed, you can continue. Follow these steps:

1) Copy u-boot.imx from your Linux machine to "MFGTOOL 5.0\Profiles\Linux\OS Firmware\" directory.

2) Start MfgTool.exe (just run MFGTOOL 5.0\MfgTool2.exe) MFGTOOL 5 - No Device 3) Switch on OpenRex power (or press "RESET" button). Note: If eFuses are already flashed (they probably are), you need to fit Boot Jumper (JP2). MFGTOOL 5 - HID Device 4) Press "Start" button in MFGTOOL. MFGTOOL 5 - Start 5) Watch console output. You should see the uBoot comming up:
U-Boot 2015.10+fslc+gd542ed0 (Mar 14 2016 - 09:44:20 -0700)

CPU:   Freescale i.MX6SOLO rev1.1 996 MHz (running at 792 MHz)
CPU:   Extended Commercial temperature grade (-20C to 105C) at 43C
Reset cause: POR
Board: iMX6-OpenRex
I2C:   ready
DRAM:  512 MiB
MMC:   FSL_SDHC: 0
SF: Detected SST26VF032B with page size 256 Bytes, erase size 4 KiB, total 4 MiB
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   FEC [PRIME]
Error: FEC address not set.

Hit any key to stop autoboot:  0
OpenRex U-Boot>

Flash uBoot

Once you are happy with the uBoot, you can flash it on the board.

*Note: Before you flash uBoot, be sure you have copied the u-boot.imx to /tftp directory. On your Linux host machine run following command:
cp u-boot.imx /tftp/imx6/u-boot-imx6s-openrex.imx
On your OpenRex board, boot up uBoot through MFGTOOL and run this:
env default -a
run set_ethernet
setenv serverip 192.168.0.37 //use your Linux host IP
saveenv
The commands above will reset default uBoot environmental variables, set ethernet and set your server IP (use the IP address of your Linux host machine).

To flash uBoot into SPI run:
run update_spi_uboot
*Note: In case you would like to update it manually, here are the commands:
mw.b 0x10800000 0xFF 0x80000;tftp 0x10800000 imx6/u-boot-imx6s-openrex.imx;sf probe;sf erase 0x0 0x80000;sf write 0x10800000 0x400 0x80000

What next

Press RESET button on your OpenRex board. If your board has eFuses set (it probably has), it will automatically boot up from SPI. If eFuses are not setup, have a look at: How to update eFuses (“fuse” command)

Upload the new uBoot to Github

When you are happy with the new uBoot, run following commands to update uBoot github:
git remote -v #check the origin, should point to your github
#git remote add origin https://github.com/FEDEVEL/openrex-uboot-v2015.10.git #run this if you get error about no origin
git checkout jethro #set the current active branch to jethro
git branch #check if you are on jethro branch
git status  #have a look what files were changed
#based on the status command, add the files you would like to upload to github
#you could also use "git add .", but that occasionally cause problems
#sometimes "add ." wants to upload also files which you have not changed, that's why I use "git add filename"
git add filename1
git add filename2
git diff origin/jethro #check if it shows correct differences
#in case differences are not what you expected or you find a mistake, you can use "git reset". Then repeat the procedure again
#if you are happy with the differences, upload the changes to github
git commit -m 'Added support for SOLO' #use a comment describing the changes
#git remote set-url origin https://github.com/FEDEVEL/openrex-uboot-v2015.10.git #run this if you get error, that "git://" is read only
git push origin jethro

Edit Linux Kernel

Get the source code

You have two options to get the source code. You can download it directly from github or you can edit the Kernel files in your YOCTO OpenRex project.

Option 1: Get the Kernel source code from github
git clone -b jethro https://github.com/FEDEVEL/openrex-linux-3.14.git
cd openrex-linux-3.14
Option 2: Find Kernel source code located inside your YOCTO project

Usualy the Kernel source code is located inside your build directory. The path may look like this:
cd ~/fsl-community-bsp/build-openrex/tmp/work/imx6q_openrex-poky-linux-gnueabi/linux-openrex/3.14-r0/git

Install & select cross compiler

If you do not have any compiler installed (or you are not sure)
apt-get install gcc-arm-linux-gnueabihf
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
If you have a compiler installed
export CROSS_COMPILE=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-none-linux-gnueabi-
export ARCH=arm

Edit files

Edit: "arch/arm/boot/dts/Makefile"
gedit arch/arm/boot/dts/Makefile
Find "imx6sx-sdb-lcdif1.dtb" and add:
imx6s-openrex.dtb \
This is how it will look:
imx6sx-sdb-lcdif1.dtb \
imx6s-openrex.dtb \
imx6ul-14x14-lpddr2-arm2.dtb \
Edit: "arch/arm/boot/dts/imx6s-openrex.dts"
cp arch/arm/boot/dts/imx6q-openrex.dts arch/arm/boot/dts/imx6s-openrex.dts
gedit arch/arm/boot/dts/imx6s-openrex.dts
You may need to adjust memory size and add/remove peripherals which are on the board. You also need to change "q" references to "dl" references, e.g. "imx6q.dtsi" to "imx6dl.dtsi"

Compile Kernel

make clean
make imx_v7_defconfig
make -j4 zImage imx6s-openrex.dtb
cp arch/arm/boot/zImage /tftp/imx6/zImage-imx6s-openrex
cp arch/arm/boot/dts/imx6s-openrex.dtb /tftp/imx6/imx6s-openrex.dtb

Test the Kernel

In case you would like to test just the Kernel and you don't have any SD card yet, then go to OpenRex and run:
tftp 0x12000000 imx6/zImage-imx6s-openrex; tftp 0x18000000 imx6/imx6s-openrex.dtb;bootz 0x12000000 - 0x18000000
*Note: this will finish with an error. To fully boot up, you also need an SD card with filesystem. See the next steps.

Upload the new Kernel to Github

When you are happy with the new Kernel, run following commands to update Kernel github:
git remote -v #check the origin, should point to your github
#git remote add origin https://github.com/FEDEVEL/openrex-uboot-v2015.10.git #run this if you get error about no origin
git checkout jethro #set the current active branch to jethro
git branch #check if you are on jethro branch
git status  #have a look what files were changed
#based on the status, add the files you would like to upload to github
#you could also use "git add .", but that occasionally cause problems
#sometimes "add ." wants to upload also files which you have not changed, that's why I use "git add filename"
git add filename1
git add filename2
git diff origin/jethro #check if it shows correct differences
#in case differences are not what you expected or you find a mistake, you can use "git reset". Then repeat the procedure again
#if you are happy with the differences, upload the changes to github
git commit -m 'Added support for SOLO' #use a comment describing the changes
#git remote set-url origin https://github.com/FEDEVEL/openrex-linux-3.14.git #run this if you get error, that "git://" is read only
git push origin jethro

Update Meta layer

Go into your main YOCTO directory:
cd ~/fsl-community-bsp/
Edit: "sources/meta-openrex/conf/machine/imx6s-openrex.conf"
cp sources/meta-openrex/conf/machine/imx6q-openrex.conf sources/meta-openrex/conf/machine/imx6s-openrex.conf
gedit sources/meta-openrex/conf/machine/imx6s-openrex.conf
This is how it looks after editing:
#@TYPE: Machine
#@NAME: FEDEVEL i.MX6S OpenRex
#@SOC: i.MX6S
#@DESCRIPTION: Machine configuration for FEDEVEL i.MX6 SOLO OpenRex
#@MAINTAINER: Robert Feranec <info@fedevel.com>

require conf/machine/include/imx6openrex-common.inc

SOC_FAMILY = "mx6:mx6dl"

PREFERRED_PROVIDER_u-boot_mx6 = "u-boot-openrex"
PREFERRED_PROVIDER_virtual/kernel_mx6 = "linux-openrex"
PREFERRED_VERSION_linux-openrex ?= "3.14"

KERNEL_DEVICETREE = "imx6s-openrex.dtb"

UBOOT_CONFIG ??= "sd"
UBOOT_CONFIG[sd] = "mx6sopenrex_config,sdcard"
UBOOT_CONFIG[mfgtool] = "mx6sopenrex_config"
*Note: watch out for "q" and change it to "dl" or "s".

Edit: "sources/meta-openrex/recipes-bsp/u-boot/u-boot-openrex_2015.10.bb"
gedit sources/meta-openrex/recipes-bsp/u-boot/u-boot-openrex_2015.10.bb
Add "imx6s-openrex" into "COMPATIBLE_MACHINE" and update "SRCREV" based on the latest uBoot commit (the commit where we added support for SOLO):
# Copyright (C) 2016 FEDEVEL
# Based on u-boot-fslc.inc Copyright (C) 2012-2015 O.S. Systems Software LTDA.
# Released under the MIT license (see COPYING.MIT for the terms)

require recipes-bsp/u-boot/u-boot.inc
inherit fsl-u-boot-localversion

DEPENDS_mxs += "elftosb-native openssl-native"

SUMMARY = "U-Boot bootloader with support for OpenRex board"
DESCRIPTION = "U-Boot bootloader with support for OpenRex board. More info \
at http://www.imx6rex.com/open-rex"

LICENSE = "GPLv2+"
LIC_FILES_CHKSUM = "file://Licenses/README;md5=0507cd7da8e7ad6d6701926ec9b84c95"

COMPATIBLE_MACHINE = "(mxs|mx5|mx6|mx6ul|mx7|vf|imx6q-openrex|imx6s-openrex)"

PROVIDES += "u-boot"

PV = "v2015.10+git${SRCPV}"

SRCBRANCH ??= "jethro"

SRC_URI = "git://github.com/FEDEVEL/openrex-uboot-v2015.10.git;branch=${SRCBRANCH}"

#SRCREV is the commit number, must be always changed for a new version
SRCREV = "5a29cd736cab804addb3ea558e0b529e2dc34ea6" 

S = "${WORKDIR}/git"

# FIXME: Allow linking of 'tools' binaries with native libraries
#        used for generating the boot logo and other tools used
#        during the build process.
EXTRA_OEMAKE += 'HOSTCC="${BUILD_CC} ${BUILD_CPPFLAGS}" \
                 HOSTLDFLAGS="${BUILD_LDFLAGS}" \
                 HOSTSTRIP=true'

PACKAGE_ARCH = "${MACHINE_ARCH}"
Edit: "sources/meta-openrex/recipes-kernel/linux/linux-openrex_3.14.bb"
gedit sources/meta-openrex/recipes-kernel/linux/linux-openrex_3.14.bb
Add "imx6s-openrex" into "COMPATIBLE_MACHINE" and update "SRCREV" based on the latest Kernel commit (the commit where we added support for SOLO):
# Copyright (C) 2016 FEDEVEL
# Released under the MIT license (see COPYING.MIT for the terms)

SUMMARY = "Linux Kernel for OpenRex board"
DESCRIPTION = "Linux Kernel for OpenRex board. More info \
at http://www.imx6rex.com/open-rex"

require recipes-kernel/linux/linux-imx.inc
require recipes-kernel/linux/linux-dtb.inc

DEPENDS += "lzop-native bc-native"

include linux-fslc.inc

#PV .= "+git${SRCPV}"
PV .= ""

SRCBRANCH = "jethro"
LOCALVERSION = "-yocto"

#Always update SRCREV based on your last commit
SRCREV = "c0f0b78fb62763bf08c44510a7174f723e2e2026"

KERNEL_SRC ?= "git://github.com/FEDEVEL/openrex-linux-3.14.git;protocol=git"
SRC_URI = "${KERNEL_SRC};branch=${SRCBRANCH} file://defconfig"

COMPATIBLE_MACHINE = "(mx6|mx7|imx6q-openrex|imx6s-openrex)"
Important: Now, test the new meta layer. See: Compile YOCTO, Create SD card and Test it

Upload the new Meta Layer to Github

If everything works oki, upload the new meta layer to github:
git remote -v #check the origin, should point to your github
#git remote add origin https://github.com/FEDEVEL/openrex-uboot-v2015.10.git #run this if you get error about no origin
git checkout jethro #set the current active branch to jethro
git branch #check if you are on jethro branch
git status #have a look what files were changed
#based on the status, add the files you would like to upload to github
#you could also use "git add .", but that occasionally cause problems
#sometimes "add ." wants to upload also files which you have not changed, that's why I use "git add filename"
git add filename1
git add filename2
git diff origin/jethro #check if it shows correct differences
#in case differences are not what you expected or you find a mistake, you can use "git reset". Then repeat the procedure again
#if you are happy with the differences, upload the changes to github
git commit -m 'Added support for SOLO' #use a comment describing the changes
git push origin jethro
#git remote set-url origin https://github.com/FEDEVEL/meta-openrex.git #run this if you get error, that "git://" is read only

Compile YOCTO, Create SD card and Test it

Compile

cd ~/fsl-community-bsp/
MACHINE=imx6s-openrex source setup-environment build-openrex
MACHINE=imx6s-openrex bitbake core-image-base

Create SD Card

Check the time & date of the files, just to be sure you have just generated them and they are the recent files:
ls -la ~/fsl-community-bsp/build-openrex/tmp/deploy/images/imx6s-openrex/
Insert an SD card into your host machine. Check under what /dev/? it was recognized:
dmesg | tail
Note: The SD card in my system is recognized as "/dev/sdb". This is what I will be using in the examples below.

Make the SD card
umount /dev/sdb?
gunzip -c ~/fsl-community-bsp/build-openrex/tmp/deploy/images/imx6s-openrex/core-image-base-imx6s-openrex.sdcard.gz > ~/fsl-community-bsp/build-openrex/tmp/deploy/images/imx6s-openrex/core-image-base-imx6s-openrex.sdcard
sudo dd if=~/fsl-community-bsp/build-openrex/tmp/deploy/images/imx6s-openrex/core-image-base-imx6s-openrex.sdcard of=/dev/sdb
umount /dev/sdb?
Work around of the fatwrite issue. Re-format the fat partition and upload the zImage + dtb again. Run following commands:
sudo mkfs.vfat -F16 -s 2 /dev/sdb1
sudo mount /dev/sdb1 /media/fedevel/
sudo cp ~/fsl-community-bsp/build-openrex/tmp/deploy/images/imx6s-openrex/zImage-imx6s-openrex.bin /media/fedevel/zImage
sudo cp ~/fsl-community-bsp/build-openrex/tmp/deploy/images/imx6s-openrex/zImage-imx6s-openrex.dtb /media/fedevel/imx6s-openrex.dtb
sudo umount /media/fedevel
Extend root disk size to SD card size (default size of the root is very small):
fedevel@ubuntu:~/fsl-community-bsp/build-openrex$ sudo fdisk /dev/sdb

Command (m for help): p

Disk /dev/sdb: 7948 MB, 7948206080 bytes
4 heads, 32 sectors/track, 121280 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xe9358ca2

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            8192       24575        8192    c  W95 FAT32 (LBA)
/dev/sdb2           24576      204799       90112   83  Linux

Command (m for help): d
Partition number (1-4): 2

Command (m for help): p

Disk /dev/sdb: 7948 MB, 7948206080 bytes
4 heads, 32 sectors/track, 121280 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xe9358ca2

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            8192       24575        8192    c  W95 FAT32 (LBA)

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (2048-15523839, default 2048): 24576
Last sector, +sectors or +size{K,M,G} (24576-15523839, default 15523839): 
Using default value 15523839

Command (m for help): p

Disk /dev/sdb: 7948 MB, 7948206080 bytes
4 heads, 32 sectors/track, 121280 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xe9358ca2

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1            8192       24575        8192    c  W95 FAT32 (LBA)
/dev/sdb2           24576    15523839     7749632   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.
fedevel@ubuntu:~/fsl-community-bsp/build-openrex$
*Note: As the First sector number use the same number where partition 2 originally started. In the example above, it's 24576.

Then run:
sudo e2fsck -f /dev/sdb2
sudo resize2fs /dev/sdb2
umount /dev/sdb?

Test the new SD card

Remove the card and plug it into OpenRex. Press "RESET" button and wait until it boots up.

*Note: If you resized the partition, you may want to double check if it worked oki:
root@imx6q-openrex:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                 7.2G     59.3M      6.7G   1% /
devtmpfs                849.3M         0    849.3M   0% /dev
tmpfs                  1009.5M    188.0K   1009.3M   0% /run
tmpfs                  1009.5M     76.0K   1009.4M   0% /var/volatile
root@imx6q-openrex:~#