AM335x
Prepare card
To make sure everything will run without problem wipe all data on the MMC:
$ sudo dd if=/dev/zero of=/dev/sdx bs=1k count=1024
Format the disk:
$ sudo fdisk /dev/sdx << __EOF__ > n > > > > > w > __EOF__
Make ext4 filesystem
$ sudo mkfs.ext4 -F -O ^metadata_csum,^64bit /dev/sdx1
NOTE: You MUST replace /dev/sdx with your device, e.g. /dev/sdc.
Cross compiler
In this tutorial gcc 5.4.0 is used:
$ arm-linux-gnueabihf-gcc --version arm-linux-gnueabihf-gcc (Debian 5.4.0-6) 5.4.0 20160609 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE
On Ubutuntu/Debian run:
$ sudo apt-get install gcc-5-arm-linux-gnueabihf
Optionally download toolchain from here. For example:
$ wget https://releases.linaro.org/components/toolchain/binaries/latest-5/arm-linux-gnueabihf/gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabihf.tar.xz $ tar -xf gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabihf.tar.xz -C /opt
Then export to PATH:
$ expot PATH=$PATH:/opt/gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/bin/
U-Boot
Building U-Boot
Get sources with:
$ git clone git://git.denx.de/u-boot.git $ cd u-boot
The patch is built against specific commit, so reset repository:
$ git reset --hard b89dfcfd926b8224edd24608065eb9bb601c0d3b
Get and apply patch:
$ wget <patch name> $ git apply <patch name>
Build image, where <board_defconfig> is am335x_olimex_som_defconfig or am335x_olimex_som_nandboot_defconfig:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- <board_defconfig>
This will produce two files:
- MLO
- u-boot.img
Writing U-Boot
MMC
Insert your card and write MLO and u-boot.img:
$ sudo dd if=MLO of=/dev/sdx count=1 seek=1 bs=128k $ sudo dd if=u-boot.img of=/dev/sdx count=2 seek=1 bs=384k
NAND
In both cases below you will need bootable MMC card. Copy MLO and u-boot.img to root (/) directory of the card.
NOTE: U-boot must be built with am335x_olimex_som_nandboot_defconfig!
From u-boot console
Boot via MMC and press any key to stop autoboot:
U-Boot SPL 2016.09-rc2-00047-gb89dfcf-dirty (Sep 15 2016 - 15:46:19) Trying to boot from MMC1 U-Boot 2016.09-rc2-00047-gb89dfcf-dirty (Sep 15 2016 - 15:46:19 +0300) DRAM: 512 MiB NAND: 512 MiB MMC: OMAP SD/MMC: 0 Hit any key to stop autoboot: 0 =>
To see nand partitions run:
=> mtd device nand0 <nand.0>, # parts = 10 #: name size offset mask_flags 0: NAND.SPL 0x00020000 0x00000000 0 1: NAND.SPL.backup1 0x00020000 0x00020000 0 2: NAND.SPL.backup2 0x00020000 0x00040000 0 3: NAND.SPL.backup3 0x00020000 0x00060000 0 4: NAND.u-boot-spl-os 0x00040000 0x00080000 0 5: NAND.u-boot 0x00100000 0x000c0000 0 6: NAND.u-boot-env 0x00020000 0x001c0000 0 7: NAND.u-boot-env.backup10x00020000 0x001e0000 0 8: NAND.kernel 0x00800000 0x00200000 0 9: NAND.file-system 0x1f600000 0x00a00000 0
Erase the while chip:
=> nand erase.chip NAND erase.chip: device 0 whole chip Erasing at 0x1ffe0000 -- 100% complete. OK
Or you can erase single partition:
=> nand erase.part NAND.SPL NAND erase.part: device 0 offset 0x0, size 0x20000 Erasing at 0x0 -- 100% complete. OK
NOTE: Everytime before write operation mtd partitions MUST be erased!
Write MLO:
=> nand erase.part NAND.SPL NAND erase.part: device 0 offset 0x0, size 0x20000 Erasing at 0x0 -- 100% complete. OK => nand erase.part NAND.SPL.backup1 NAND erase.part: device 0 offset 0x20000, size 0x20000 Erasing at 0x20000 -- 100% complete. OK => nand erase.part NAND.SPL.backup2 NAND erase.part: device 0 offset 0x40000, size 0x20000 Erasing at 0x40000 -- 100% complete. OK => nand erase.part NAND.SPL.backup3 NAND erase.part: device 0 offset 0x60000, size 0x20000 Erasing at 0x60000 -- 100% complete. OK => => => load mmc 0 0x82000000 MLO 46044 bytes read in 32 ms (1.4 MiB/s) => => => nand write 0x82000000 NAND.SPL NAND write: device 0 offset 0x0, size 0x20000 131072 bytes written: OK => nand write 0x82000000 NAND.SPL.backup1 NAND write: device 0 offset 0x20000, size 0x20000 131072 bytes written: OK => nand write 0x82000000 NAND.SPL.backup2 NAND write: device 0 offset 0x40000, size 0x20000 131072 bytes written: OK => nand write 0x82000000 NAND.SPL.backup3 NAND write: device 0 offset 0x60000, size 0x20000 131072 bytes written: OK =>
Write u-boot.img:
=> nand erase.part NAND.u-boot NAND erase.part: device 0 offset 0xc0000, size 0x100000 Erasing at 0x1a0000 -- 100% complete. OK => => => load mmc 0 0x82000000 u-boot.img 347364 bytes read in 48 ms (6.9 MiB/s) => => => nand write 0x82000000 NAND.u-boot NAND write: device 0 offset 0xc0000, size 0x100000 1048576 bytes written: OK =>
From linux console
Boot board from MMC card. Make sure you have mtd-utils package, otherwise:
$ apt-get update $ apt-get install mtd-utils
You should see 10 mtd devices:
# cat /proc/mtd dev: size erasesize name mtd0: 00020000 00020000 "NAND.SPL" mtd1: 00020000 00020000 "NAND.SPL.backup1" mtd2: 00020000 00020000 "NAND.SPL.backup2" mtd3: 00020000 00020000 "NAND.SPL.backup3" mtd4: 00040000 00020000 "NAND.u-boot-spl-os" mtd5: 00100000 00020000 "NAND.u-boot" mtd6: 00020000 00020000 "NAND.u-boot-env" mtd7: 00020000 00020000 "NAND.u-boot-env.backup1" mtd8: 00800000 00020000 "NAND.kernel" mtd9: 1f600000 00020000 "NAND.file-system"
To erase partition use:
# flash_erase /dev/mtd0 0 0
To write MLO:
# flash_erase /dev/mtd0 0 0 # nandwrite -p /dev/mtd1 /MLO # flash_erase /dev/mtd1 0 0 # nandwrite -p /dev/mtd0 /MLO # flash_erase /dev/mtd2 0 0 # nandwrite -p /dev/mtd2 /MLO # flash_erase /dev/mtd3 0 0 # nandwrite -p /dev/mtd3 /MLO
To write u-boot.img:
# flash_erase /dev/mtd5 0 0 # nandwrite -p /dev/mtd5 /u-boot.img
Kernel
We are going to use kernel 4.4 from TI.
Getting the sources
Clone into repository:
$ git clone git://git.ti.com/ti-linux-kernel/ti-linux-kernel.git $ cd ti-linux-kernel
Get 4.4.y remote branch:
$ git checkout linux-4.4.y -b linux-4.4
Configure kernel
Make omap2plus default defconfig:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- omap2plus_defconfig
Make some modifications:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- omap2plus_defconfig
- Enable SPIDEV
Device Drivers ---> [*] SPI support ---> <M> User mode SPI device driver support
- Enable DRM
Device Drivers ---> Graphics support ---> <M> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) ---> <M> DRM Support for TI LCDC Display Controller [*] Support device tree blobs using TI LCDC Slave binding (NEW)
- Enable SHAM and AES
-*- Cryptographic API ---> [*] Hardware crypto devices ---> <M> Support for OMAP MD5/SHA1/SHA2 hw accelerator <M> Support for OMAP AES hw engine
Kernel build
Build kernel and modules:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules
Install modules to target directory:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=output modules_install
Patch kernel tree to get our device-tree blobs:
$ git apply 0001-Add-support-for-OLIMEX-dtbs.patch
If patch fail, you can reset the tree:
$ git reset --hard 65fd19fc2bac06ae7e66cc3d6450c9d6dd034311
Build dtbs:
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- dtbs
This will produce lot of .dtb files. The interesting ones are:
- am335x-olimex-som.dtb - The minimum configuration for AM335x-SOM to run.
- am335x-olimex-som-nand.dtb - Same as above, but with enabled nand.
- am335x-olimex-som-evb.dtb - Support for AM335x-SOM-EVB. Use this one, if there isn't intalled nand on AM335x-SOM
- am335x-olimex-som-evb-nand.dtb - Save above, without dual ethernet and enabled nand.
Kernel writing
Now when you have new kernel put it on the right location
MMC card
We assume that you already installed rootfs on the card. Mount card, if its not mounted yet:
$ sudo mount /dev/sdx1 /mnt
Copy zImage and device-tree blobs:
$ sudo cp arch/arm/boot/zImage /mnt/boot/ $ sudo cp arch/arm/boot/dts/am335x-olimex-som*.dtb /mnt/boot
Install modules:
$ sudo cp -r output/* /mnt
NAND flash
Again you must boot from MMC and have zImage and dtbs stored in some folder.
From u-boot console
Write zImage:
=> nand erase.part NAND.kernel NAND erase.part: device 0 offset 0x200000, size 0x800000 Erasing at 0x9e0000 -- 100% complete. OK => => => load mmc 0 0x82000000 /boot/zImage 3667672 bytes read in 327 ms (10.7 MiB/s) => => => nand write 0x82000000 NAND.kernel NAND write: device 0 offset 0x200000, size 0x800000 8388608 bytes written: OK =>
Write device-tree blob:
=> nand erase.part NAND.u-boot-spl-os NAND erase.part: device 0 offset 0x80000, size 0x40000 Erasing at 0xa0000 -- 100% complete. OK => => => load mmc 0 0x82000000 /boot/am335x-olimex-som-evb-nand.dtb 37870 bytes read in 18 ms (2 MiB/s) => => => nand write 0x82000000 NAND.u-boot-spl-os NAND write: device 0 offset 0x80000, size 0x40000 262144 bytes written: OK =>
From linux console
To write zImage:
# flash_erase /dev/mtd8 0 0 # nandwrite -p /dev/mtd8 /boot/zImage
To write dtb:
# flash_erase /dev/mtd4 0 0 # nandwrite -p /dev/mtd4 /boot/am335x-olimex-som-evb-nand.dtb
File system
Debian 8
Install required tools:
$ sudo apt-get install qemu-user-static debootstrap binfmt-support
Make target directory:
$ mkdir rootfs $ sudo debootstrap --arch=armhf --foreign jessie rootfs
Copy qemu and resolvonf:
$ sudo cp /usr/bin/qemu-arm-static rootfs/usr/bin/ $ sudo cp /etc/resolv.conf rootfs/etc
Go into the new file system:
$ sudo chroot rootfs
Inside the new file system do:
# export LANG=C # /debootstrap/debootstrap --second-stage
Set apt sources.list:
# cat << __EOF__ > /etc/apt/sources.list #------------------------------------------------------------------------------# # OFFICIAL DEBIAN REPOS #------------------------------------------------------------------------------# ###### Debian Main Repos deb http://ftp.bg.debian.org/debian/ jessie main contrib non-free deb-src http://ftp.bg.debian.org/debian/ jessie main contrib non-free ###### Debian Update Repos deb http://security.debian.org/ jessie/updates main contrib non-free deb http://ftp.bg.debian.org/debian/ jessie-proposed-updates main contrib non-free deb-src http://security.debian.org/ jessie/updates main contrib non-free deb-src http://ftp.bg.debian.org/debian/ jessie-proposed-updates main contrib non-free __EOF__
Note: The list is generated using this tool, so feel free modify it.
Set hostname:
# echo "AM335x" > /etc/hostname
Install some packages:
# apt-get install locales dialog sudo openssh
Set locales:
# dpkg-reconfigure locales
Set root password:
# passwd
Add olimex user:
# adduser olimex
Enable serial port on USB-OTG
Make script that initialize serial gadget:
# cat << __EOF__ > /usb/bin/usb_serial.sh #/bin/sh
# variables and strings CONFIGS_DIR="/configs" MANUFACTURER="Olimex Ltd." # manufacturer attribute SERIAL=$(ifconfig eth0 | head -n1 | awk -F" " '{print $5}' | sed 's/://g') IDPRODUCT="0x003e" # hex product ID, issued by USB Group IDVENDOR="0x15ba" # hex vendor ID, assigned by USB Group PRODUCT="AM335x Serial Gadget" # cleartext product description CONFIG_NAME="Configuration 1" # name of this configuration UDC=musb-hdrc.0.auto # name of the UDC driver to use (found in /sys/class/udc/) # Load modules ! lsmod | grep "libcomposite" > /dev/null 2>&1 && modprobe libcomposite ! lsmod | grep "usb_f_acm" > /dev/null 2>&1 && modprobe usb_f_acm # Mount confgsfs [ ! -d $CONFIGS_DIR ] && mkdir $CONFIGS_DIR mount none $CONFIGS_DIR -t configfs # Create gadget mkdir -p $CONFIGS_DIR/usb_gadget/serial cd $CONFIGS_DIR/usb_gadget/serial # Set VID and PID echo $IDVENDOR > idVendor echo $IDPRODUCT > idProduct # Set strings mkdir strings/0x409 echo $SERIAL > strings/0x409/serialnumber echo $MANUFACTURER > strings/0x409/manufacturer echo $PRODUCT > strings/0x409/product # Create configuration mkdir configs/c.1 mkdir configs/c.1/strings/0x409 echo "120" > configs/c.1/MaxPower echo $CONFIG_NAME > configs/c.1/strings/0x409/configuration # Creating functions mkdir functions/acm.usb0 # Associate function with comfiguration ln -s functions/acm.usb0 configs/c.1 # Enable UDC echo $UDC > UDC __EOF__ # chmod +x /usb/bin/usb_serial.sh
Add startup service:
# cat << _EOF__ > /lib/systemd/system/usb-serial.service [Unit] Description=Serial console on USB-OTG ConditionPathExists=/sys/devices/platform/ocp/47400000.usb/47401300.usb-phy/ Before=serial-getty@ttyGS0.service [Service] Type=oneshot ExecStart=/bin/bash -c "/usr/bin/usb_serial.sh" RemainAfterExit=yes [Install] WantedBy=getty.target __EOF__
Enable login on ttyGS0:
# cp -v /lib/systemd/system/serial-getty\@.service # nano /lib/systemd/system/serial-getty\@ttyGS0.service
Add following in [Unit] section:
Requires=usb-serial.service # systemctl enable serial-getty\@ttyGS0.service