I´ve been searching for a method to write all the stuff you get from building the parts for the system on the internal flash of the board.
Mainly because I don´t want to write everything onto an SD Card and then copy it onto the internal flash. Also there are a lot of steps to do every time.
And because I´m mainly using Windows on my Desktop machines, I thought why not using MFGTool for that.
I won´t explain on how to create the parts. Only how to get them with MFGTools working.
If there are questions on how to create those, just ask in the comments. Also I´ll provide an image you can write onto an sdcard I built like this in the next few days.
Maybe someone can use what I learned here.
But prepare yourself. You´re gonna see a lot of text.
First things first. What you´ll need:
If you already downloaded the Linux Image then you have it. But if you´re like me and don´t want to download 1,6 GB just for the tool (would take one and a half hour with my connection at home...) you can get it from freescale directly.
But why is a tool that´s open source so hard to get? All Downloads I´ve found were pretty big because they all include the stuff for flashing onto the boards.
At least I found the download on the freescale community website, but you´ll have to register to download it. (Really?)
Also they assume you´re a company, so you have to put a lot of info into that account. (What´s that for?)
You´ll find it under "Hardware Development Tools" -> "Programmers" -> "IMX_6DQ_MFG_TOOL" at the Following Link.
(If anyone has an easier download please tell me.)
The other stuff you´ll need:
- U-Boot Image file (compiled from the mainline source)
- Kernel Image and board device tree files (both compiled from the mainline source with a riotboard config)
- rootfs filesystem packed into a tgz file (create your own or take the one from the Linux image from e14)
- bootscript file (I´ll give an example file for that)
Let´s look at MFGTool
MFGTool mainly is a program that allows you to send files and shell commands directly onto the board via USB.
Only problem with that tool: If you send files, they are stored temporarily in the RAM of the board. So with that you´re not able to send bigger files than the RAM on the board.
You can´t send an image file and then dd it onto the flash memory if the image has the size of the internal flash.
You could use a samller image file or try to get it on the board with pipe, but I dind´t try that by now because that wasn´t my goal here.
But what you can do is sending smaller files. For example as a compressed rootfs file and then decompress the files onto a partition.
There are a few files that define which commands are executed.
Let´s look at these files.
In the root folder of the tool you have a file "cfg.ini".
This file defines which method to use on your Board.
Standard Settings are for the Sabre-SD and it looks like this:
chip = MX6Q Linux Update
board = SabreSD
name = Sabre-SD
- "chip" defines which folder to use in the "Profiles" folder.
- "board" defines which board were using. (As far as I can tell it has no function)
- "name" defines which commands are executed. (The commands are defined in ucl2.xml)
Now the ucl2.xml file. You find it in the folder that´s specified in the cfg.ini.
(Remember to rename the file from ucl2.txt to ucl2.xml if you have the E14 image. The freescale download has a correctly named file.)
First thing to look at are the "List" tags.
<LIST name="i.MX6SOLO-DEBIAN-RIOT-eMMC" desc="Choose eMMC as media"> </LIST>
This defines the whole method that is used to flash the files.
With this we would have to write "i.MX6SOLO-DEBIAN-RIOT-eMMC" into the cfg.ini for the name, so that the commands for this list tag are used.
All other commands are written inside the List tag.
There are different commands available. I won´t go through all of them. Only those we need to flash the files.
Because the riotboard is in "Serial Download Mode" when connecting it with MFGtool, the first thing we always have to do is to get it into a state where you are able to send files and execute commands.
(The following commands are all written inside the List tag)
<CMD state="BootStrap" type="boot" body="BootStrap" file ="u-boot-mx6solo-riot.bin" >Loading U-boot</CMD> <CMD state="BootStrap" type="load" file="uImage" address="0x10800000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" >Loading Kernel.</CMD> <CMD state="BootStrap" type="load" file="initramfs.cpio.gz.uboot" address="0x10C00000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" >Loading Initramfs.</CMD> <CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>
What does this do?
Well first it loads u-boot with BootStrap into the RAM of the board.
Then it loads the Kernel image at a specific address.
After that it loads initramfs at another address into the RAM.
And with the last command it boots from all the stuff we just put into RAM.
After bootup the board then is recognized as an External Hard Drive. And at this state we are able to do everything we want as if we are directly in a Linux environment.
Let´s start with the flashing then.
First we need to create the partitions where we store everything.
<CMD state="Updater" type="push" body="send" file="mksdcard.sh.tar">Sending partition shell</CMD> <CMD state="Updater" type="push" body="$ tar xf $FILE "> Partitioning...</CMD> <CMD state="Updater" type="push" body="$ sh mksdcard.sh /dev/mmcblk0"> Partitioning...</CMD>
The first command sends a file called "mksdcard.sh.tar" to the board. This file is already in MFGTool integrated and contains a script that creates a boot partition and a partition to write the root filesystem to.
The second command extracts the file.
For a "send" command we also need the file to send of course. The folder used in which MFGTools searches for the files is the one specified in cfg.ini plus the folder "OS Firmware".
The file that´s been sent is for the next commands accessible through the environment variable $FILE. This environment variable changes after every "send" command and can be used in the commands after that.
After extracting the script, we start it with the internal flash /dev/mmcblk0 as parameter so the script knows what it has to partition.
Next we will send and write the u-boot image.
<CMD state="Updater" type="push" body="send" file="files/u-boot-mx6solo-riot.bin">Sending u-boot.bin</CMD> <CMD state="Updater" type="push" body="$ dd if=$FILE of=/dev/mmcblk0 bs=512 seek=2">write u-boot.bin to sd card</CMD> <CMD state="Updater" type="push" body="$ dd if=/dev/zero of=/dev/mmcblk0 bs=512 seek=1536 count=16">clean up u-boot parameter</CMD>
As you can see, you can use normal Linux commands just like dd to write the image file.
All you need to do is just define with a "$" at the start to execute it on the shell.
After that the created partition will be formatted in ext3 and mounted.
<CMD state="Updater" type="push" body="$ mkfs.ext3 -j /dev/mmcblk0p1">Formatting rootfs partition</CMD> <CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk0p1"/> <CMD state="Updater" type="push" body="$ mount -t ext3 /dev/mmcblk0p1 /mnt/mmcblk0p1"/>
Next will the rootfs filesystem be written.
<CMD state="Updater" type="push" body="pipe tar --numeric-owner -zxv -C /mnt/mmcblk0p1" file="files/oneiric.tgz">Sending and writing rootfs</CMD> <CMD state="Updater" type="push" body="frf">Finishing rootfs write</CMD>
With the pipe command you don´t send the whole file on the board. It executes the command "on the fly". So all files will be extracted directly into the root filesystem.
(In theory you could send an image file like this. But that´s something I need to test first.)
Now we need to copy the bootscript, Kernel and the Devicetree file.
<CMD state="Updater" type="push" body="send" file="files/bootscript">Sending bootscript</CMD> <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk0p1/boot/bootscript"/> <CMD state="Updater" type="push" body="send" file="files/zImage">Sending Kernel</CMD> <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk0p1/boot/zImage"/> <CMD state="Updater" type="push" body="send" file="files/imx6s-riotboard.dtb">Sending Device Tree</CMD> <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk0p1/boot/imx6s-riotboard.dtb"/>
Depending on where u-boot looks for your bootscript you have to change the target path. (Or change the environment variable "lsb" from u-boot to the corresponding path.)
My u-boot searches on the first partition in the folder "/boot" for the file.
Also my bootscript looks for the kernel and devicetree in the same folder.
Now all that is left to do, is unmounting the partition and send the command that we are finished.
<CMD state="Updater" type="push" body="$ umount /mnt/mmcblk0p1">Unmounting rootfs partition</CMD> <CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>
Unmounting before finishing is essential, because we still have a lot of stuff flying around in the buffer that needs to be written.
Because it´s almost impossible to upload a simple xml file here on E14, I´ll upload them on my server.
You can get the whole ucl2.xml file as well as the bootscript I´m using right now at the following Links. (I removed all other List entries except the one to flash the riotboard)
With that you are ready to copy your kernel and rootfs files into the "files" folder of MFGTool and flash it directly onto the board.
Just change your cfg.ini, put the board into serial download mode and start MFGTool.
Remember if the bootscript isn´t found, check the u-boot environment variables with printenv.