-
Notifications
You must be signed in to change notification settings - Fork 0
FreeBSD and Freescale IMX6
So you said you have been over the crossbuild and sd card image pages already and things are still fuzzy? Crochet is a great tool that produces standardized images for many supported platforms, but the scripts add a layer of complexity that is a setback when you are first learning to build FreeBSD for arm.
Fine then, here are my build steps. I feel this is original content as I built up this information over years of tears and more tears (ask the guys on the arm email list how many tears they shed trying to help me through this). However, this is largely the same information found on the FreeBSD Wiki.
Set up a Projects directory under our home folder.
mkdir -p ~/Projects/hummingboard/src
I have a core i7 and an SSD so I load up the number of concurrent jobs with -j10 or -j20
svn checkout https://svn0.us-west.FreeBSD.org/base/head .../src
OR
svn up .../src
THEN
cd .../src
The buildworld target creates all the compilers and the userland utilities
make TARGET=arm TARGET_ARCH=armv6 -j10 buildworld
buildkernel creates the kernel and all the loadable modules. The specific kernel for the platform can be customized through the files under src/sys/arm/conf
make -DNO_CLEAN TARGET=arm TARGET_ARCH=armv6 KERNCONF=IMX6 -j10 buildkernel
- 1 - 10 mb at the front of the sd card unpartitioned
- MBR partition Scheme
- 10 - 100 mb fat32 slice for ubldr and uEnv.txt u-boot configuration file
- The rest of the space for a FreeBSD slice
Note: first use gpart to destroy everything that may already exist
sudo mkdir /mnt/fatpart
sudo mkdir /mnt/bsdpart
gpart create -s mbr da4
gpart add -t fat32 -b 1M -s 50M da4
sudo newfs_msdos -F32 /dev/da4s1
gpart add -t freebsd da4
sudo newfs /dev/da4s2
sudo mount /dev/da4s1 /mnt/fatpart
sudo mount /dev/da4s2 /mnt/bsdpart
For the hummingboard, we can use the sysutil/u-boot-cubox-hummingboard port:
cd /usr/ports/sysutils/u-boot-cubox-hummingboard/
sudo make
the output can be found in a folder such as: /usr/ports/sysutils/u-boot-cubox-hummingboard/work/stage/usr/local/share/u-boot/u-boot-cubox-hummingboard
NOTE: After an update to my PC-BSD the version of the arm cross compiler was bumped to 5.3.0 from 4.9.2 and u-boot failed to build. pkg remove arm-none-eabi-gcc pkg install arm-none-eabi-gcc492 solves the problem
##4. Write u-boot to the disk sudo dd if=u-boot of=md0 seek=2
This didn't seem to work: sudo dd if=u-boot.imx of=md0 seek=2 540+0 records in 540+0 records out 276480 bytes transferred in 0.016680 secs (16575537 bytes/sec)
TODO
make -DNO_CLEAN TARGET=arm TARGET_ARCH=armv6 DESTDIR=/mnt/bsdpart installworld distribution
make TARGET=arm TARGET_ARCH=armv6 KERNCONF=IMX6 installkernel DESTDIR=/mnt/bsdpart
Conf files
The main place to customize the kernel is using the kernel configuration files under .../src/sys/arm/conf as noted above.
Configuring what packages are build for a specific project (i.e. shrink your installation) can be done using the SRCCONF variable. See the rather awkwardly documented src.conf(5) man page here:
The "main" make.conf(5) configuration file is here:
and the main build page with more information about the make targets and some of the more common variables available is here (but not SRCCONF!):
Note: Creating a minimalist installation can also be achieved using NANOBSD, which is currently under construction by Warner Losh, but I don't know too much more than this. But here are some references of unknown freshness.
https://bsdrp.net/documentation/technical_docs/nanobsd
https://www.freebsd.org/doc/en/articles/nanobsd/howto.html
Writing to memdisk instead of little files to the sd card
Writing the installworld to sd card takes FOREVER. I've tried to get fancy and speed up the installation by creating a memorydisk image first and then copying everything into that.
truncate -s 1024M imx6.img
sudo mdconfig -f imx6.img -u0
gpart create -s mbr md0
gpart add -t fat32 -b 1M -s 50M md0
newfs_msdos -F32 /dev/md0s1
gpart add -t freebsd md0
sudo newfs /dev/md0s2
sudo dd if=u-boot of=md0 seek=2 --> This didn't seem to work
make -DNO_CLEAN TARGET=arm TARGET_ARCH=armv6 DESTDIR=/mnt/memdisk installworld distribution
make -DNO_CLEAN TARGET=arm TARGET_ARCH=armv6 DESTDIR=/mnt/memdisk installkernel
umount /mnt
mdconfig -d -u0
sysctl kern.geom.debugflags=16
dd if=imx6.img of=/dev/da0 bs=4096k
I have not verified this is correct code.
Booting from the network
The main build reference for all of this is on the FreeBSD wiki. The crossbuild page provides an excellent build tutorial and explains how to boot the kernel from tftp and mount the rootfs using an nfs mount point.
https://wiki.freebsd.org/FreeBSD/arm/crossbuild
Build locations
I typically use a PC-BSD desktop computer as it's easy and I really like using ZFS. Up until recently I would do all my crossbuilding in a FreeBSD jail. The provided good isolation from my main system but had the drawback that copying files in and out of the jail was difficult due to security restrictions, albeit because I didn't have it set up very well.
Since I have started building in my home directory without a jail, I can copy items much faster and generally have the freedom required to mount and unmount things from a single console, but I have now run into a case where an update to my host computer broke my u-boot build. While not an insurmountable problem, it does create a case for using a jail to isolate your build tools from your host system (which you may need updates for!).
Booting From NAND
On the older Digi Imx53 platform a jumper could be set to toggle the boot location from the sd card(s) to an internal nand flash. I had experimented with running u-boot from nand which can in turn could be used to load the kernel file from SD using u-boot variables and commands. Once the kernel was running I could then mount a USB rootfs. I only had this working for a week or so before I broke it again and could never get it running a second time.
However, my projected next attempt was to copy the kernel onto the nand flash using u-boot commands through the command line terminal and then updating u-boot to load the kernel directly from nand. This could technically also be done using ubldr as well. Here are some notes that outlined a script to do this:
echo ====Set Variables====
setenv kernel_file /CCWMX53/kernel
setenv u-boot_file /CCWMX53/u-boot.bin
setenv ramdisk_file /CCWMX53/uRamdisk
setenv u-boot_size 0x800
setenv kernel_size 0x1800
setenv ramdisk_size 0x1800
setenv u-boot_nand_offset 0x400 //original was 40000000 Should this be 0x400?
setenv u-boot_size 0x800
setenv kernel_addr 0x70800000
setenv ramdisk_addr 0x40100000
echo ===== U-Boot settings =====
setenv load_u-boot 'tftp ${loadaddr} ${u-boot_file}'
setenv install_u-boot 'protect off ${u-boot_nand_offset}
+${u-boot_size};era ${u-boot_nand_offset} +${u-boot_size};cp.b
${loadaddr} ${u-boot_nand_offset} ${u-boot_size};saveenv'
setenv update_u-boot run load_u-boot install_u-boot
echo ===== FreeBSD Kernel settings =====
setenv load_kernel 'tftp ${loadaddr} ${kernel_file};'
setenv install_kernel 'era ${kernel_addr} + ${kernel_size};cp.b
${loadaddr} ${kernel_addr} ${kernel_size}'
setenv update_kernel run load_kernel install_kernel
echo ===== Ramdisk settings =====
setenv load_ramdisk 'tftp ${loadaddr} ${ramdisk_file};'
setenv install_ramdisk 'era ${ramdisk_addr} + ${ramdisk_size};cp.b
${loadaddr} ${ramdisk_addr} ${ramdisk_size}'
setenv update_ramdisk run load_ramdisk install_ramdisk
echo ===== Save new definitions =====
saveenv
The important part would be this:
setenv load_kernel 'tftp ${loadaddr} ${kernel_file};' setenv install_kernel 'era ${kernel_addr} + ${kernel_size};cp.b ${loadaddr} ${kernel_addr} ${kernel_size}'
which would load the kernel into memory using tftp, erasing whatever is on the nand blocks we needed using era and then using cp.d to write the kernel to the nand.
None of this was ever attempted and this should be considered pseudo-code not a working prototype. Moreover, I am SURE there is an easier way to do this. In the end, if you could achieve something like this using ubldr instead of loading the kernel directly, you could then still have a standard image on some other medium (including an updatable kernel) and also utilize what would otherwise be an unused nand chip.
Update: From a gentleman named Ron on the mailing list: My Sheevaplug loads the kernel from NAND which mounts the rootfs from USB-stick. And does this for a couple of years already. I used to have a rootfs on nandfs(5) also, but nandfs is not stable enough.
nandtool erase dev=/dev/gnand0s.fbsd-boot
dd if=/tmp/kernel.bin of=/dev/gnand0s.fbsd-boot bs=2k conv=sync