Difference between revisions of "U-booting Funtoo on the TI AM335x X2 SBC-B2"

From Funtoo
Jump to: navigation, search
m (Copy Over Kernel Files)
m (Introduction)
 
(24 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
== Introduction ==
 
== Introduction ==
Installing Funtoo to a Raspberry Pi is fun, but there are a lot more boards out there. For example, the carrier boards that hold a DIMM mounted AM335x series cpu. To get this going, we need to use the U-Boot bootloader, some knowledge of serial consoles, and a lot of patience.  
+
Installing Funtoo to a Raspberry Pi is fun, but there are a lot more boards out there. For example, the carrier boards that hold a DIMM mounted AM335x series cpu. To get this going, we need to use the U-Boot bootloader, some knowledge of device tree blobs, and a lot of patience.
 +
 
 +
For this article, we are using this [http://www.goembed.com/index.php/Products/detail/tpid/49 board]. You can read all about it [https://www.dropbox.com/sh/qk4fligwqth7547/AADVvhXGAOxkbqFRKPP8eeSja/SBC335x-B2A?dl=0 here] but the steps depicted here should get you a manufacturer supplied 4.1.8 kernel with a Funtoo stage3 running on it. Possibly. Don't buy it if you don't absolutely need it. There are far better choices.  
  
 
{{note|When you pick a board, documentation is just as important as hardware features. Without it, you WILL be hunting down someone in Shenzhen to explain why the board refuses to boot (you forgot to ground C8, of course).}}
 
{{note|When you pick a board, documentation is just as important as hardware features. Without it, you WILL be hunting down someone in Shenzhen to explain why the board refuses to boot (you forgot to ground C8, of course).}}
 +
{{warning|This is kind of a ridiculous exercise, given the author's limited level and the wild idiosyncrasies of board programming, but it may be instructive. It helps me.}}
  
See http://funtoo.org/Crossdev_Automation for the xcompile_variables.sh script and environment variables referenced here, and a more complete introduction to the process via a complete install of Funtoo to Raspberry Pi 2 and 3.
+
== Making the Environment ==
 +
Edit xcompile_variables to set XC_WORK, XC_LINUX_PREFIX, ARCH, CROSSDEV_TARGET, and STAGE3 variables to taste. For this board, we use:
 +
* CROSSDEV_TARGET="arm-linux-gnueabihf"
 +
* ARCH=arm
 +
* STAGE3=funtoo-current/arm-32bit/armv7a_neon_hardfp
 +
* STAGE3_CFLAGS="-O2 -pipe -march=armv7-a -mfpu=neon -mfloat-abi=hard"
 +
* STAGE3_NAME=stage3-latest.tar.xz
  
 +
{{console|body=
 +
# . xcompile_variables.sh
 +
# mkdir -p $CONFIGS $FIRMWARE $LINUX $UBOOTS $STAGE3S
 +
}}
  
== Kernel Building ==
+
== Retrieve Sources ==
This is an example of using manufacturer supplier scripts for defconfig generation. Don't forget to adjust the make jobs with -j <N> or just alias make="make -j<N>" to copy paste the commands directly.
+
{{console|body=
 +
# git clone https://github.com/zhengsjgoembed/335x-b4-uboot.git $XC_UBOOT
 +
# git clone https://github.com/zhengsjgoembed/335x-b4.git $XC_KERNEL_SRC
 +
# wget https://git.ti.com/ti-cm3-pm-firmware/amx3-cm3/blobs/7c6075f28d9fdd633175cdbd8dc287613ce92e5d/bin/am335x-pm-firmware.bin -O $XC_FIRMWARE/am335x-pm-firmware.bin
 +
# wget https://git.ti.com/ti-cm3-pm-firmware/amx3-cm3/blobs/7c6075f28d9fdd633175cdbd8dc287613ce92e5d/bin/am335x-pm-firmware.elf -O $XC_FIRMWARE/am335x-pm-firmware.elf
 +
}}
  
=== Defconfig Generation ===
+
== Crossdev ==
This is a particular choice of defconfig
+
See Crossdev_Automation for info on how to get crossdev running on Funtoo.
 
{{console|body=
 
{{console|body=
# cd $XC_KERNEL_SRC
+
# crossdev -t $CROSSDEV_TARGET --gcc 4.9.3 -P -v
# ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET ti_config_fragments/defconfig_builder.sh -t ti_sdk_am3x_release
+
# gcc-config -l
# ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET make ti_sdk_am3x_release_defconfig
+
[1] arm-linux-gnueabihf-4.9.3 *
}}
+
[2] arm-linux-gnueabihf-5.2.0
 +
[3] arm-linux-gnueabihf-5.3.0
  
 +
[4] armv6j-hardfloat-linux-gnueabi-4.8.4 *
  
 +
[5] armv7a-hardfloat-linux-gnueabi-4.8.4
 +
...<lots of compilers>...
 +
}}
  
 +
== Kernel Building ==
 
{{console|body=
 
{{console|body=
# ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- make uImage dtbs modules LOADADDR=0x82000000
+
# . xcompile_variables
 +
# get_kernel_version
 +
4.1.18
 +
# set_kernel_extraversion = -defconfig && . xcompile_variables.sh
 +
# get_kernel_version
 +
4.1.18-defconfig
 +
# cd $XC_KERNEL_SRC
 +
# alias make="make -j<N>"
 +
# cp am335x_b4_deconfig $XC_KERNEL_CONFIG
 +
# . xcompile_variables
 +
Your current kernel configs for <XC_LINUX_PREFIX> type builds:
 +
Use 4.1.18.kconf as config (y/n)? y
 +
Setting XC_KERNEL_OLDCONFIG to /usr/src/fun_kernel/configs/<XC_LINUX_PREFIX>/4.1.18.kconf
 +
# cp XC_KERNEL_OLDCONFIG .config
 +
# ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- make zImage modules dtbs
 
}}
 
}}
  
 
== U-Boot Building ==
 
== U-Boot Building ==
  
Notice the use of O=$XC_LINUX_PREFIX to control output. Remove this directory is you need to clean for a rebuild. DTC is the device tree compiler location. Again, a mystery.  
+
Notice the use of O=$XC_LINUX_PREFIX to control output. Remove this directory if you need to clean for a rebuild. DTC is the device tree compiler location that permits the use of Device Tree Blobs, an absolutely essential tool for managing the wild forest of ARM processors and base boards. See this [http://xillybus.com/tutorials/device-tree-zynq-1 tutorial] on the Device Tree.  
 
{{console|body=
 
{{console|body=
# wget $UBOOT_URL -O $UBOOTS/$UBOOT
 
# cd $UBOOTS
 
# mkdir u-boot && tar xf $UBOOT -C u-boot --strip-components 1
 
 
# cd $XC_UBOOT
 
# cd $XC_UBOOT
 
# ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- make mrproper
 
# ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- make mrproper
Line 40: Line 75:
  
 
== Setup Stage3 ==
 
== Setup Stage3 ==
We set up the boot partion  differently. The rest of the steps are the similar. Our board has a hardware clock as well.
+
Follow the steps in http://funtoo.org/Crossdev_Automation#Stage3_Configuration but do not set up a software clock. Our board has a hardware clock.
{{console|body=
 
# sed -i "s/\/dev\/sda1.*/\/dev\/mmcblk0p1 \/boot/uboot vfat defaults 0 2/" $XC_STAGE3S/etc/fstab
 
# mkdir -p $XC_STAGE3S/boot/uboot
 
}}
 
  
===Copy Over Kernel Files===
+
===Copy Over Kernel Files and Firmware===
 
{{console|body=
 
{{console|body=
 
# cd $XC_KERNEL_SRC
 
# cd $XC_KERNEL_SRC
 
# ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- INSTALL_MOD_PATH=$XC_STAGE3S INSTALL_MOD_STRIP=1 make modules_install
 
# ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- INSTALL_MOD_PATH=$XC_STAGE3S INSTALL_MOD_STRIP=1 make modules_install
 
# ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- INSTALL_FW_PATH=$XC_STAGE3S make firmware_install
 
# ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- INSTALL_FW_PATH=$XC_STAGE3S make firmware_install
# cp  arch/arm/boot/uImage $XC_STAGE3S/boot/uboot
+
# cp $XC_FIRMWARE/* $XC_STAGE3S/lib/firmware
# get_kernel_release() { (cd $XC_KERNEL_SRC ; ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- make kernelrelease;) }
+
# cp  arch/arm/boot/zImage $XC_STAGE3S/boot
 +
# cp arch/arm/boot/dts/*.dtb $XC_STAGE3S/boot
 
# rm $XC_STAGE3S/lib/modules/`get_kernel_release`/{build,source}
 
# rm $XC_STAGE3S/lib/modules/`get_kernel_release`/{build,source}
 
}}
 
}}
  
 
===Copy Over U-Boot Files===
 
===Copy Over U-Boot Files===
Leave a blank line at the end of the u-boot config. For some reason or other.
 
 
{{console|body=
 
{{console|body=
# cp $XC_UBOOT/$XC_LINUX_PREFIX/{MLO,u-boot.img} $XC_STAGE3S/boot/uboot
+
# cp $XC_UBOOT/$XC_LINUX_PREFIX/{MLO,u-boot.img} $XC_STAGE3S/boot
# echo "mmcrootfstype=ext4
 
bootargs=console=ttyO0,115200n8 root=/dev/mmcblk0p2 mem=128M rootwait
 
bootcmd=mmc rescan; fatload mmc 0 0x82000000 uImage; bootm 0x82000000
 
uenvcmd=boot
 
" > $XC_STAGE3S/boot/uboot/uEnv.txt
 
 
}}
 
}}
  
Line 83: Line 109:
 
# mkdir -p /mnt/funtoo
 
# mkdir -p /mnt/funtoo
 
# mount /dev/<your_dev>2 /mnt/funtoo
 
# mount /dev/<your_dev>2 /mnt/funtoo
# mkdir -p /mnt/funtoo/boot/uboot
+
# mkdir -p /mnt/funtoo/boot
# mount /dev/<your_dev>1 /mnt/funtoo/boot/uboot
+
# mount /dev/<your_dev>1 /mnt/funtoo/boot
 
# rsync -avz --exclude "usr/portage/*" $XC_STAGE3S/{boot,bin,etc,home,lib,mnt,opt,root,run,sbin,srv,tmp,usr,var,dev} /mnt/funtoo
 
# rsync -avz --exclude "usr/portage/*" $XC_STAGE3S/{boot,bin,etc,home,lib,mnt,opt,root,run,sbin,srv,tmp,usr,var,dev} /mnt/funtoo
 
# mkdir -p /mnt/funtoo/{proc,sys}
 
# mkdir -p /mnt/funtoo/{proc,sys}
 
# umount -R /mnt/funtoo
 
# umount -R /mnt/funtoo
 
}}
 
}}
 +
 +
Reboot! Moment of truth: do you really know what you are doing?
 +
 +
{{tip|Once you get the board up and sshd running on it, then use rsync -e "ssh"  $XC_STAGE3S/{boot,lib} <board_ip>:/ to do the kernel hacking.  How long can you keep it up?}}
 +
 +
== If It Boots... ==
 +
=== Device Tree Fun ===
 +
This is important. In embedded world we need to always handle the relationship between the cpu and baseboard that carries it. We can use the u-boot shell to find this out.
 +
 +
{{console|body=
 +
=> bdinfo
 +
arch_number = 0x00000F8C
 +
boot_params = 0x10000100
 +
DRAM bank  = 0x00000000
 +
-> start    = 0x10000000
 +
-> size    = 0x80000000
 +
eth0name    = FEC     
 +
ethaddr    = (not set)
 +
current eth = FEC     
 +
ip_addr    = <NULL>
 +
baudrate    = 115200 bps
 +
TLB addr    = 0x8FFF0000
 +
relocaddr  = 0x8FF4A000
 +
reloc off  = 0x7874A000
 +
irq_sp      = 0x8EF47EA0
 +
sp start    = 0x8EF47E90
 +
FB base    = 0x8EF4B7C0
 +
}}
 +
 +
This structure is extremely useful in finding an appropriate device tree file so that the cpu can talk to the registers on the hardware and engage with interupts. It's pretty cool.

Latest revision as of 19:20, February 21, 2017

Introduction

Installing Funtoo to a Raspberry Pi is fun, but there are a lot more boards out there. For example, the carrier boards that hold a DIMM mounted AM335x series cpu. To get this going, we need to use the U-Boot bootloader, some knowledge of device tree blobs, and a lot of patience.

For this article, we are using this board. You can read all about it here but the steps depicted here should get you a manufacturer supplied 4.1.8 kernel with a Funtoo stage3 running on it. Possibly. Don't buy it if you don't absolutely need it. There are far better choices.

   Note

When you pick a board, documentation is just as important as hardware features. Without it, you WILL be hunting down someone in Shenzhen to explain why the board refuses to boot (you forgot to ground C8, of course).

   Warning

This is kind of a ridiculous exercise, given the author's limited level and the wild idiosyncrasies of board programming, but it may be instructive. It helps me.

Making the Environment

Edit xcompile_variables to set XC_WORK, XC_LINUX_PREFIX, ARCH, CROSSDEV_TARGET, and STAGE3 variables to taste. For this board, we use:

  • CROSSDEV_TARGET="arm-linux-gnueabihf"
  • ARCH=arm
  • STAGE3=funtoo-current/arm-32bit/armv7a_neon_hardfp
  • STAGE3_CFLAGS="-O2 -pipe -march=armv7-a -mfpu=neon -mfloat-abi=hard"
  • STAGE3_NAME=stage3-latest.tar.xz
root # . xcompile_variables.sh
root # mkdir -p $CONFIGS $FIRMWARE $LINUX $UBOOTS $STAGE3S

Retrieve Sources

root # git clone https://github.com/zhengsjgoembed/335x-b4-uboot.git $XC_UBOOT
root # git clone https://github.com/zhengsjgoembed/335x-b4.git $XC_KERNEL_SRC
root # wget https://git.ti.com/ti-cm3-pm-firmware/amx3-cm3/blobs/7c6075f28d9fdd633175cdbd8dc287613ce92e5d/bin/am335x-pm-firmware.bin -O $XC_FIRMWARE/am335x-pm-firmware.bin
root # wget https://git.ti.com/ti-cm3-pm-firmware/amx3-cm3/blobs/7c6075f28d9fdd633175cdbd8dc287613ce92e5d/bin/am335x-pm-firmware.elf -O $XC_FIRMWARE/am335x-pm-firmware.elf

Crossdev

See Crossdev_Automation for info on how to get crossdev running on Funtoo.

root # crossdev -t $CROSSDEV_TARGET --gcc 4.9.3 -P -v
root # gcc-config -l
 [1] arm-linux-gnueabihf-4.9.3 *
 [2] arm-linux-gnueabihf-5.2.0
 [3] arm-linux-gnueabihf-5.3.0

 [4] armv6j-hardfloat-linux-gnueabi-4.8.4 *

 [5] armv7a-hardfloat-linux-gnueabi-4.8.4
...<lots of compilers>...

Kernel Building

root # . xcompile_variables
root # get_kernel_version
4.1.18
root # set_kernel_extraversion = -defconfig && . xcompile_variables.sh
root # get_kernel_version 
4.1.18-defconfig
root # cd $XC_KERNEL_SRC
root # alias make="make -j<N>"
root # cp am335x_b4_deconfig $XC_KERNEL_CONFIG
root # . xcompile_variables
Your current kernel configs for <XC_LINUX_PREFIX> type builds:
Use 4.1.18.kconf as config (y/n)? y
Setting XC_KERNEL_OLDCONFIG to /usr/src/fun_kernel/configs/<XC_LINUX_PREFIX>/4.1.18.kconf
root # cp XC_KERNEL_OLDCONFIG .config
root # ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- make zImage modules dtbs

U-Boot Building

Notice the use of O=$XC_LINUX_PREFIX to control output. Remove this directory if you need to clean for a rebuild. DTC is the device tree compiler location that permits the use of Device Tree Blobs, an absolutely essential tool for managing the wild forest of ARM processors and base boards. See this tutorial on the Device Tree.

root # cd $XC_UBOOT
root # ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- make mrproper
root # ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- make distclean
root # rm -r ./$XC_LINUX_PREFIX
root # ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- make O=$XC_LINUX_PREFIX am335x_evm_config
root # ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- make O=$XC_LINUX_PREFIX DTC=$XC_KERNEL_SRC/scripts/dtc/dtc

Setup Stage3

Follow the steps in http://funtoo.org/Crossdev_Automation#Stage3_Configuration but do not set up a software clock. Our board has a hardware clock.

Copy Over Kernel Files and Firmware

root # cd $XC_KERNEL_SRC
root # ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- INSTALL_MOD_PATH=$XC_STAGE3S INSTALL_MOD_STRIP=1 make modules_install
root # ARCH=$ARCH CROSS_COMPILE=$CROSSDEV_TARGET- INSTALL_FW_PATH=$XC_STAGE3S make firmware_install
root # cp $XC_FIRMWARE/* $XC_STAGE3S/lib/firmware
root # cp  arch/arm/boot/zImage  $XC_STAGE3S/boot
root # cp arch/arm/boot/dts/*.dtb $XC_STAGE3S/boot
root # rm $XC_STAGE3S/lib/modules/`get_kernel_release`/{build,source}

Copy Over U-Boot Files

root # cp $XC_UBOOT/$XC_LINUX_PREFIX/{MLO,u-boot.img} $XC_STAGE3S/boot

Install to the Board

Make an image.

root # dd if=/dev/zero of=/dev/<your_dev> bs=1024 count=1024
root # parted -s /dev/<your_dev> mklabel msdos
root # parted -s /dev/<your_dev> unit cyl mkpart primary fat32 -- 0 9
root # parted -s /dev/<your_dev> set 1 boot on
root # parted -s /dev/<your_dev> unit cyl mkpart primary ext2 -- 9 -2
root # mkfs.vfat -F 32 -n boot /dev/<your_dev>1
root # mkfs.ext4 -L rootfs /dev/<your_dev>2

Mount and Rsync.

root # mkdir -p /mnt/funtoo
root # mount /dev/<your_dev>2 /mnt/funtoo
root # mkdir -p /mnt/funtoo/boot
root # mount /dev/<your_dev>1 /mnt/funtoo/boot
root # rsync -avz --exclude "usr/portage/*" $XC_STAGE3S/{boot,bin,etc,home,lib,mnt,opt,root,run,sbin,srv,tmp,usr,var,dev} /mnt/funtoo
root # mkdir -p /mnt/funtoo/{proc,sys}
root # umount -R /mnt/funtoo

Reboot! Moment of truth: do you really know what you are doing?

   Tip

Once you get the board up and sshd running on it, then use rsync -e "ssh" $XC_STAGE3S/{boot,lib} <board_ip>:/ to do the kernel hacking. How long can you keep it up?

If It Boots...

Device Tree Fun

This is important. In embedded world we need to always handle the relationship between the cpu and baseboard that carries it. We can use the u-boot shell to find this out.

=> bdinfo
arch_number = 0x00000F8C
boot_params = 0x10000100
DRAM bank   = 0x00000000
-> start    = 0x10000000
-> size     = 0x80000000
eth0name    = FEC       
ethaddr     = (not set)
current eth = FEC      
ip_addr     = <NULL>
baudrate    = 115200 bps
TLB addr    = 0x8FFF0000
relocaddr   = 0x8FF4A000
reloc off   = 0x7874A000
irq_sp      = 0x8EF47EA0
sp start    = 0x8EF47E90
FB base     = 0x8EF4B7C0

This structure is extremely useful in finding an appropriate device tree file so that the cpu can talk to the registers on the hardware and engage with interupts. It's pretty cool.