For the freescale SABRE Board for Smart Devices Based on the i.MX6 Series check the 6000 page datasheet of the MCIMX6Q6AVT10AC chip.
Freescale delivers a lot of things with the board (all other boards and processor variants of the same family) and this makes it a bit tricky to get the overview and not mix up the different things and keep them apart. Mainly there are:
A android demo image (sd card that comes with the board) but does not support connecting with the Internet
Ubuntu demo image
Gnome demo image
Linux Target Image Builder (ltib)
The demo images are good for a first start but there are the questions: How to expand and how to maintain it in the future. ltib is considered the standard way to work with it.
The chip MCIMX6Q6AVT10AC (or if you got a prototype of it PCIMX6Q6AVT10AC) is extremely complex and there are thousands of pages documentation on the freescale site. This section obviously can not duplicate that, but it gives hints about it. Its ball grid package has 25*25 =625 pins and the IO multiplexer allows to assign many different signals to those pins.
The chip has an internal 96kByte boot ROM and uses the internal OCRAM (that can be used for other things after boot). It supports many advanced ways to boot reading the boot pins, fuse settings and internal register BOOT_MODE[1:0] status. The Boot ROM sits on address 0x0000_0000 of the 0xFFFF_FFFF size memory space of the device.
The DRAM can be in the range 0x1000_0000 to 0xFFFF_FFFF = 3.84GByte and the sabre board uses 1GB. Further the chip has maps of fuses that can be used to configure it, mess around there could make the chip un-unstable.
Linux Target Image Builder (ltib) http://ltib.org/allows to build a target including bootloader, Linux kernel, system and application packages. Freescale strongly recommends to install an old ubuntu 9.04 from 2009 to run it (Running this outdated version in virtual box is therefore a good approach). ltib is a good point to start but certain things are a bit outdated including the list of packages that it offers. With such complete (and complex) tools it is strongly recommended to accept its limits that it offers and don't deviate from it. Installing and working with ltib is done as regular user.
./tlib -m configure or ./tlib --mode configure pops up a menu and allows to configure it.
./tlib builds the system (if necessary) and put the results in rootfs/boot/
./ltib -help shows what ltib can do
To configure and rebuild the kernel there is the "Configure the kernel" option in ltib that the does the well known make menuconfig followed by a kernel compilation. The new kernels can then be found in rootfs/boot/
Installing Gentoo Linux gives more freedom and control over the board and allows to test the newest Linux trends. Additionally it is an autonomous installation where no Ubuntu system with ltib and no cross compilation is required. To not have a keyboard, mouse display attached to the sabre board and work with it, a ssh connection to a remote computer can be made and all the work can be done on the remote computer. All the remote computer requires is ssh and this is even available on a Windows machine. For Windows machine all that is required is one single file that runs without installation putty.exe from https://www.putty.org/. Compilation is done on the sabre board using a native compiler. To speed this up distcc can be used to have all computers on the network having an gnu arm compiler participating.
This is a summary of my test that I did until I had it running. Therefore I can not guarantee that the sequence of the steps is correct and that I remembered all I did. So it might not be complete. If you are in trouble let me know at <urs@linurs.org>
A swapfile or partition are required when huge packages are getting complied. The swap should not be on the SDcard an external USB Harddisk. If this does not work /etc/portage/make.conf
can be modified to have
MAKEOPTS="-j1"
to not use all cores in parallel. Compilation takes longer but uses less RAM.
The board can boot from the SD card (and many other methods) using u-boot. It is recommended to take a 16G SD card since a 8G SD card might be too small for the freescale kernel source, uboot source and gentoo package database with close to 20000 ebuilds, sources of the installed packages and maybe a swapfile. If space is a concern a 8G card could be taken (the same size as the internal Flash) plus a 2nd SD card where the big files for the development reside. The following concentrates on the simple approach having just a single SD card.
The SD card needs to be partitioned a bit special since u-boot binary with its around 400kBytes size can not be placed into the 512Byte Master Boot Record (or boot sector) of the SD card. So it is placed in an "unused" slot right after the partition table. To create this slot using fdisk the first partition that becomes the boot partition around 40MByte ext2 type 83 (mkfs.ext2 /dev/sd<f>
1) is not allowed to start with the first cylinder but must be shifted some cylinders to get the slot. The slot should be around 1MBytes. The corresponding cylinder numbers must be calculated using number of heads, sectors of the SD card used. Since u-boot can read ext2 (or fat, but don't use it since it lacks of the Linux features as be unable to store symbolic links) the first partition will therefore be ext2. The second partition the root partition can then be formated using a Linux filesystem as ext4 type 83 (mkfs.ext4 /dev/sd<f>
2) that has journaling features. A swap partition is not made since this can be damage the SD card due to too frequent writes. However a swapfile can later be place to the 2nd partition that can be manually turned on when needed as in the case when compilation of huge packages on sabre requires more DRAM and distcc to do the compilation on an other machine is not available. Alternatively plug in an additional SD card in the second connector for that.
The bootloader u-boot file to be used for SD cards is then copied into this slot using
dd if=u-boot-mx6q-sabresd.bin of=/dev/sdf bs=512 seek=2 skip=2 conv=fsync
this writes it directly to the SD card 1kByte after the partition table and remains invisible since no file system is used. The first test can be made by booting the board wit a serial console as gtkterm (or minicom to see everything that got written) attached (115200 baud). Pressing keys during boot will bring up the u-boot console.
The binary of the kernel can then be copied using the regular cp into the first partition. When stopping u-boot during boot, this partition can be read using the command ext2ls mmc 2:1 . To boot the kernel it must be loaded in memory this can be done with ext2load mmc 2 ${loadaddr} uimage. The variable loadaddr is the start address of the DRAM memory as printenv loadaddr shows 0x10800000. Alternatively u-boot might also support fat instead of ext2 using the commands fat2ls and fat2load. However fat is not recommended since it does not support the nice Linux features as use multiple kernel files with version info in their filenames and then just making a symbolic link to ln -s <nice kernel name>
uImage. This way kernel updated could be done without modifying the u-boot environmental parameters, since just the link needs to be bended to the new kernel file. An other problem of fat is, that it does not support the file attributes user/group and the Linux permission bytes. bootm finally boots then from memory.
The docs from freescale make it a bit different, they put and hide the kernel as the bootloader between MBR and first partition and instead of doing loadfat they read directly from the mmc using the mmc read command.
Advantage: No boot partition is necessary
Disadvantage: Complicated when having multiple kernels. Kernels can not have a filename. Kernel can just be exchanged using a dd command and not a cp command or a GUI drag and drop.
At this stage there is a working bootloader and a binary kernel. The next step is telling the kernel where the root file system is.
It is on the second mmc and on the second partition /dev/mmcblk1p2
. u-boot must pass this to the kernel using its environmental parameters. u-boot might also be setup that it uses dhcp so a Ethernet cable must be plugged in.
The following are the commands for u-boot necessary to load the and start the kernel
setenv bootargs_mmc 'setenv bootargs ${bootargs} root=/dev/mmcblk1p2 rootfstype=ext4 rootwait rw video=mxcfb0:dev=hdmi,1024x768M@60,if=RGB24 video=mxcfb1:off video=mxcfb2:off'
setenv bootcmd_ext2 'run bootargs_base bootargs_mmc; ext2load mmc 2 ${loadaddr} uImage; bootm'
setenv bootcmd 'run bootcmd_ext2'
printenv
saveenv
Since most of the following steps are the standard way of installing Gentoo look at https://wiki.gentoo.org/wiki/Project:ARM Except that the sd card got prepared on a PC so the first chapters of this guide can be skipped and a point to enter the guide is chapter 5. Installing the Gentoo Installation Files. Also chroot into the root file system is not necessary since the goal is to do all the work on a Linux PC having the sd card plugged in and then booting Gentoo on the sabre and finishing the issues directly there. Therefore the sequence is a bit different.
Therefore here just a quick guide not repeating the details from at https://wiki.gentoo.org/wiki/Project:ARM:
Get the filesystem from https://www.gentoo.org/downloads/mirrors/ and navigate to releases/arm/autobuilds/
where you take a stage3-*.tar.bz2
. stage3-armv7a_hardfp-
is best suited for the i.mx. Simply unpack it inside partition 2 of the mmc tar xvjpf stage3-*.tar.bz2 and you get all the directories and files.<YYYYMMDD>
A kernel that boots tries to read /etc/fstab
where it finds the filesystems to be mounted. So edit it and add the second partition as root partition and the first as boot partition.
The list of packages are defined in /usr/portage
and this is now empty. It can be obtained as well from https://www.gentoo.org/downloads/mirrors/ when navigating into snapshot and take portage-latest.tar.bz2
and extract it to /usr/portage
. Two things are worth to be noted portage-latest.tar.bz2 has been created today, this shows that gentoo is a living distribution and second it is quite big since a couple of 10-thousands of different packages can be selected. Furthermore this can be expanded using overlays.
When not having keyboard, mouse and screen attached, it is necessary due to the not yet working Ethernet connection that the kernel prints out data to the serial console using the correct baudrate so for Gentoo Linux using OpenRC put the line
s0:12345:respawn:/sbin/agetty -L 115200 ttymxc0 vt100
to /etc/initab
.
The Gentoo installation might now to boot, start the kernel, mount the root filesystem and start its init scripts. However it might fail with important things as starting new udev versions due to missing kernel settings (This is sign that ltib has build a Linux system that does not use the newest features Gentoo uses). Luckily Gentoo complains with the exact missing CONFIG_DEVTMPFS setting. Therefore a kernel must be compiled (as a start this can be done within ltib).
To continue the network should run including the ssh daemon sshd so configure to use dhcp and start next boot it:
cd /etc/init.d
ln -s net.lo net.eth0
rc-update add net.eth0 default
rc-update add sshd default
Now reboot and then ifconfig to see the IP address you got as 192.168.1.110
If not already done you need a root password on you board that can be set as passwd.
Now you can access the board from you PC inside a console (open more than one console to keep the quad core busy installing packages) type su to become root and then ssh 192.168.1.110 . Set the correct time using date <MMDDhhmmYYYY>
and then from Internet:
emerge net-misc/ntp
rc-update add ntpd default
rc-update add ntp-client default
/etc/init.d/ntp-client start
/etc/init.d/ntpd start
rc-update add swclock boot
rc-update del hwclock boot
Then have fun finishing the installation by going through the guide https://wiki.gentoo.org/wiki/Project:ARM and skipping the things already done.
To get hdmi output (however u-boot and kernel boot messages will still go to the serial console), stop u-boot and type
setenv bootargs_mmc 'setenv bootargs ${bootargs} root=/dev/mmcblk1p2 rootwait rw video=mxcfb0:dev=hdmi,1024x768M@60,if=RGB24 video=mxcfb1:off video=mxcfb2:off'
saveenv
boot
When you and the system are happy, it is worth to move away from ltib to get an autonomous independent Gentoo Linux system system. This means the kernel and boot loader must be built outside ltib.
To get the kernel sources there are two ways:
Simply get it from ltib using: ./ltib -m prep -p kernel and then taking from cd rpm/BUILD/linux
Or get it directly from the nethttp://git.freescale.com/git/ where more and more modern kernel versions are available:
cd /usr/src
git clone http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git
Don't be worried about the 2.6 inside there are also the 3 kernels.
This clones the git repository.
Now to work with the source cd linux-2.6-imx and create a branch so you will not damage the original source. The kernel sources have many versions and many branches, stable and not stable and makes it difficult to choose from. git tag will show you a lot but git branch will show you just the master
branch. However there are also remote branches. git remote shows you a simple word origin
, but git remote show origin shows you what it is all about. Even you cloned it has some references to the origin and there are remote branches. The idea is that you improve the source and eventually give it back (merge) to the origin.
The following command does two things. It creates a new local branch called imx_3.0.35_4.1.0 than comes from the remote branch imx_3.0.35_4.1.0 at where origin points to, then it also checks it out:
git checkout -b imx_3.0.35_4.1.0 origin/imx_3.0.35_4.1.0
git branch shows you that you now have doe the two things, you got a second branch
* imx_3.0.35_4.1.0
and the * shows you that it got checked out and selected to work with it.
The kernel needs to be configured and its configuration ends up in the hidden file .config
. To not start from zero take it from the sabre board using one of the following methods:
copy and rename it to .config
it from the boot partition
copy /proc/config.gz to your kernel source top directory,
gunzip config.gz, and rename it
Finally make menuconfig and make && make modules_install will create arch/arm/boot/zImage
and the device files under /lib/modules
.
Since the kernel will be booted using u-boot the bzImage
needs to be converted into the u-boot format uImage
. An uImage
has a 64Byte header. After having done emerge u-boot-tools different things can be done.
Creating a uImage:
cd arch/arm/boot
mkimage -A arm -O linux -T kernel -C none -a 0x10008000 -e 0x10008000 -n "Linux-3.0.35-4.1.0" -d zImage uImage
The addresses where the kernel gets loaded are different than the ones the kernel gets loaded from the mmc, this copy allows a two step approach: Load a compressed kernel to RAM and then have it extract to an other RAM location.
Observing the header:
mkimage -l uImage
To have the kernel running it is not enough to have the right CPU configured but also the peripherals must fit. Arm systems are not standardized as the PC, therefore a MACHINE_ID has been introduced seehttp://www.arm.linux.org.uk/developer/machines/ or linux/arch/arm/tools/mach-types
to prevent that a wrong kernel gets started and might create some unwanted effects. Sabre has the MACHINE_ID 3529 and MACHINE_TYPE mx6q_sabreauto. The bootloader has to pass this MACH_TYPE_<xxx>
to the kernel (via CPU register 1) and the kernel needs to verify it. If it does not match the kernel hangs and might even to be scared to print out a message. See http://www.arm.linux.org.uk/developer/booting.php.
To get the u-boot sources sources there are two ways:
Simply get it from ltib using: ./ltib -m prep -p u-boot and then taking from cd rpm/BUILD/uboot
Or get it directly from the nethttp://git.freescale.com/git/ where more versions are available:
git clone http://git.freescale.com/git/cgit.cgi/imx/uboot-imx.git
This clones the git repository.
git remote show origin shows what is there and
git checkout -b imx_v2009.08_3.0.35_4.1.0 origin/imx_v2009.08_3.0.35_4.1.0 creates a branch so no damage will be done to the original git branch confirms it
make mx6q_sabresd_config finally configures the source for the sd card version of the boot loader and make does the job and creates u-boot.bin
The sabre PCB's internal 8GByte flash is an embedded Multimedia Card (or Controller) using NAND Flash and host controller. It appears as 3 devices a 8GByte device /dev/mmcblk0
and two 2MByte Boot devices /dev/mmcblk0boot0
and /dev/mmcblk0boot1
Setting the DIP switch (SW6) to boot from the e.MMC on board flash does not use the two boot devices /dev/mmcblk0boot0
and /dev/mmcblk0boot1
the boot loader must be installed in /dev/mmcblk0
as on the SD card.
The switch to select the boot source is a bit tricky since it might not clear where switch 1is. When the silkscreen text is upside down then switch 1 is on the left and the orientation follows the manual. The tiny text on the switch itself is also a good hint to find the orientation.
Pins | 1/16 | 2/15 | 3/14 | 4/13 | 5/12 | 8/11 | 7/10 | 8/9 | |
bit / Switch | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
Slot2 | SD card | on | off | off | off | off | off | on | off |
Slot3 | SD card | off | on | off | off | off | off | on | off |
Slot4 | e.MMC | on | on | off | off | off | on | on | off |
Freescale delivers the windows tool mfgtool.exe that luckily runs on windows without installations. For monitoring purposes it is recommended to attach a terminal to the console using a windows program as teraterm. The other USB OTG connector needs to be connected to the USB of the PC and does the work. On boot failures as booting from an not inserted SD card or not supported dip switch setting, sabre defaults to serial download mode. In this mode the mfgtool.exe downloads a Linux kernel plus an initial ram file system to its DRAM and executes then commands to program the memories of sabre (as on board e.MMC but also SD cards).
The commands to be executed are in the ucl2.xml
file in the <LIST> element sections. Since there are many <LIST> elements, the config file cfg.ini
file select one out of the <LIST> elements. Looking in detail at the ucl2.xml
shows the well known Linux dd commands used to setup the boot memory device. So the mfgtool.exe is mainly a tool for Windows users to launch Linux commands on sabre.