First mission is to install the gcc for arm linux to ensure that we can compile the kernel.
As using Ubuntu distribution of Linux, use apt
to install gcc-arm-linux-gnueabihf
and the libraries used.
$ sudo apt install gcc-arm-linux-gnueabihf
After finished installing, compile a simple "Hello world" program to see if the compiler is working properly.
$ arm-linux-gnueabigf-gcc -o helloarm helloworld.c
Use file
to see the properties of the output file.
helloarm: ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=8e92a4ef2b70e3db73ce9fe6a740a9025be3fdfc, for GNU/Linux 3.2.0, not stripped
Apply the defualt configure file for BeagleBone.
$ make bb.org_defconfig ARCH=arm
Then use make menuconfig ARCH=arm
to manage the modules.
- In
Device Drivers
, enter the entry ofBlock devices
and enableRAM block device support
. - In
File systems
, enable support forNetwork File Systems
. - Save the new configuration as
.config
.
$ make ARCH=arm CROSS_COMPILE=<Your own cross compiler prefix> -j8
## -j8 means use 8 threads to compile
In ths case, my Cross compiler prefix is set as arm-linux-gnueabihf-
.
The image file output is located at ./arch/arm/boot/
.
The Device tree binary file output is located at ./arch/arm/boot/dts/
.
- Download the busybox source. In this case, we use
apt-src
to get the source code.
$ apt-src install busybox
Remember not to run
apt-src
as root, or you may have to manuallychown
the source file downloaded.
- Configure the busybox using
make menuconfig
.
- Enable the option
Build static binary (no shared libs)
.- Set
Cross compiler prefix
asarm-linux-gnueabihf-
.- (Optional) Set the destination for
make install
, you can found the built binaries there.- (Optional) Remove some of the components if you want the binaries to be smaller.
make
andmake install
to generate the binaries.
The busybox is now ready to deploy. We are going to use it in the following steps.
- Make a new folder named as
fs_root
(This name is not fixed, use your own if you'd like). - Copy all the files generated by busybox to the new folder.
- Move to the new folder and
mkdir etc
. - In the directory
etc
, create the following files:
- inittab
# /etc/inittab
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::once:/usr/sbin/telnetd -l /bin/login
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
- rc
Remember: This file needs to be excutable, do not forget to
chmod +x
.
#!/bin/sh
hostname Minaduki-BeagleBone
mount -t proc proc /proc
/bin/cat /etc/motd
- motd (Message Of ToDay)
# .88b d88. d888888b d8b db .d8b. d8888b. db db db dD d888888b
# 88'YbdP`88 `88' 888o 88 d8' `8b 88 `8D 88 88 88 ,8P' `88'
# 88 88 88 88 88V8o 88 88ooo88 88 88 88 88 88,8P 88
# 88 88 88 88 88 V8o88 88~~~88 88 88 88 88 88`8b 88
# 88 88 88 .88. 88 V888 88 88 88 .8D 88b d88 88 `88. .88.
# YP YP YP Y888888P VP V8P YP YP Y8888D' ~Y8888P' YP YD Y888888P
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# Linux 4.4.155 on BeagleBone Black am335x.
# Powered by MINADUKI Technologies 2019. All rights reserved.
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- Make a dir named
init.d
and inside the dir, make a symbol link frometc/init.d/rcS
toetc/rc
. This assign the fileetc/rc
to be the startup script excuted by inittab.
$ mkdir init.d
$ cd init.d
$ ln -s ../rc rcS
- Make a dir named
dev
, inside the dir create necessary devices usingmknod
.
$ sudo mknod console c 5 1
$ sudo mknod null c 1 3
$ sudo mknod zero c 1 5
Tips: Tired of typing
sudo
? You may usesudo chmod +s
to make the excutable always run as root.
- Create empty dirs
proc
andsys
for processes and SYSFS file system. - Create dir
lib
, copy the following libraries from the cross compilers to the dirlib
:
ld-2.30.so
libc-2.30.so
libm-2.30.so
The version of the libraries may vary, so you may have to change it to your own version.
- Make symbol links for the libraries.
$ ln -s ld-2.30.so ld-linux-armhf.so.3
$ ln -s libc-2.30.so libc.so.6
$ ln -s libm-2.30.so libm.so.6
That's all for the files. Your fs_root
dir shall now look like this:
total 40
drwxr-xr-x 10 minaduki minaduki 4096 11月 12 15:50 .
drwxr-xr-x 7 minaduki minaduki 4096 11月 12 15:09 ..
drwxr-xr-x 2 minaduki minaduki 4096 11月 12 15:04 bin
drwxr-xr-x 2 minaduki minaduki 4096 11月 12 15:42 dev
drwxr-xr-x 3 minaduki minaduki 4096 11月 12 15:26 etc
drwxr-xr-x 2 minaduki minaduki 4096 11月 12 15:53 lib
lrwxrwxrwx 1 minaduki minaduki 11 11月 12 15:11 linuxrc -> bin/busybox
drwxr-xr-x 2 minaduki minaduki 4096 11月 12 15:50 proc
drwxr-xr-x 2 minaduki minaduki 4096 11月 12 15:04 sbin
drwxr-xr-x 2 minaduki minaduki 4096 11月 12 15:50 sys
drwxr-xr-x 4 minaduki minaduki 4096 11月 12 15:04 usr
We use the ramdisk as an example, but you can choose other media as your root file system.
- Make an image file, my image is 8 MiB in size.
$ dd if=/dev/zero of=ramdisk_img bs=1k count=8192
$ mke2fs ramdisk_img
- Mount the ramdisk.
$ mount ramdisk_img ~/Desktop/mnt
- To save the space on ramdisk, we use
strip
to remove symbols in the libraries, making them taking up less space.
$ arm-linux-gnueabihf-strip ld-2.30.so
$ arm-linux-gnueabihf-strip libc-2.30.so
$ arm-linux-gnueabihf-strip libm-2.30.so
- Copy the files generated above to the ramdisk.
Unfortunately, we made a mistake above, the device files under
dev
cannot be copied, so we have to redo themknod
in the ramdisk mounted.
- Umount the ramdisk and compress the file to save space.
$ umount ~/Desktop/mnt
$ gzip ramdisk_img
You may now boot with the new ramdisk.
Remeber to configure as superuser
For the first time running minicom, use command minicom -s
to configure.
- Enter
serial port setup
. - Set
/dev/ttyUSB0
as the Serial Device. - Set Bps/Par/Bits to be
115200 8N1
. - Disable all Flow Controls.
After finished, save the setup as defualt and run minicom.
- Use
apt
to install packagetftp-hpa
andtftpd-hpa
. - Edit
/etc/hosts.allow
and add:
tftpd:ALL
in.tftpd:ALL
- (Optional) (For Manjaro) Edit
/etc/conf.d/tftpd
to modify the default workspace. - (Optional) (For Ubuntu) Edit
/etc/default/tftpd-hpa
to modify the default workspace. - (Optional) Use
chmod
to edit the permissions of the workspace. - Start the service.
$ systemctl start tftpd.socket tftpd.service
$ systemctl enable tftpd.socket
Wait for the device to boot into U-boot and use the following script to boot.
U-Boot# set ipaddr 192.168.208.121 # IP addr of BeagleBone
U-Boot# set serverip 192.168.208.48 # IP addr of PC
U-Boot# tftp 0x82000000 zImage # image file
U-Boot# tftp 0x88080000 ramdisk_img.gz # ramdisk
U-Boot# tftp 0x88000000 am335x-boneblack.dtb # device tree
U-Boot# set ramdisk root=/dev/ram rw initrd=0x88080000
U-Boot# set bootargs console=ttyO0,115200 $ramdisk
U-Boot# bootz 0x82000000 0x88080000: <size of ramdisk> 0x88000000
- Configure the IP address using
ifconfig
command. The default name of the network interface iseth0
. - Configure the gateway, the gateway of our lab is
192.168.208.254
.
$ ifconfig eth0 192.168.208.121
$ route add default gw 192.168.208.254
- Use
apt
to installnfs-kernel-server
. - Edit the file
/etc/exports
to configure the service. - Use
systemctl
to start and enable the service.
You may use
exportfs -a
to refresh the NFS directories.
Be adviced that we found sometimessystemctl
may fail to start NFS, try to useservice
then.
$ mkdir mnt
$ mount 192.168.208.48:/srv/nfs4 mnt -o nolock,proto=tcp
Now that we have comfirmed the NFS works properly, why not try something interesting?
- Edit the file
/etc/exports
to add our new dir to NFS service. The file shall now look like this:
/srv/nfs4 *(rw,sync,no_subtree_check,no_root_squash)
/srv/nfs4/nfsboot_rootfs *(rw,sync,no_subtree_check,no_root_squash)
- Use
exportfs
to refresh the NFS configure of the host. - Now try to boot via NFS:
U-Boot# set ipaddr 192.168.208.121 # IP addr of BeagleBone
U-Boot# set serverip 192.168.208.48 # IP addr of PC
U-Boot# tftp 0x82000000 zImage # image file
U-Boot# tftp 0x88000000 am335x-boneblack.dtb # device tree
U-Boot# setenv rootfs root=/dev/nfs rw nfsroot=<server_ip>:<Root_Dir>
U-Boot# setenv nfsaddrs nfsaddrs=<ip>:<server_ip>:<gateway>:<mask>
U-Boot# setenv bootargs console=ttyS0,115200 $rootfs $nfsaddrs
U-Boot# bootz 0x82000000 - 0x88000000
In my example, my input looks like this:
U-Boot# set ipaddr 192.168.208.121 # IP addr of BeagleBone
U-Boot# set serverip 192.168.208.35 # IP addr of PC
U-Boot# tftp 0x82000000 zImage # image file
U-Boot# tftp 0x88000000 am335x-boneblack.dtb # device tree
U-Boot# setenv rootfs root=/dev/nfs rw nfsroot=192.168.208.35:/srv/nfs4/nfsboot_rootfs,vers=3
U-Boot# setenv nfsaddrs nfsaddrs=192.168.208.121:192.168.208.35:192.168.208.254:255.255.255.0
U-Boot# setenv bootargs console=ttyS0,115200 $rootfs $nfsaddrs
U-Boot# bootz 0x82000000 - 0x88000000
Attention please:
The kernel I use (and provide) will use NFSv2 as default, if you are using later versions of NFS server, add,vers=3
(using NFSv3) or,vers=4
(using NFSv4) at the end of thenfsroot
argument. Be advised that some of the NFSv4 servers defaultly refuses udp connections, if you do not want to modify your NFS server, you may add,proto=tcp
to force the client to use tcp to connect.
If failed when trying to mount the NFS, you may add
nfsrootdebug
when setting bootargs, it will let the kernel print the DEBUG log and you may be able to analyze it to find your mistakes.
Be careful! The command
echo
writes 2 bytes (including enter) but our driver is only expecting 1.
- Download gdb from the Internet, move in to dir
gdbserver
and run configure:
$ ./configure --target=arm-linux --host=x86-linux
- Make the program.
- Perparing: When compiling your kernel, enable
Device Drivers->Graphics support->DRM support for TI LCDC Display Controller
andDevice Drivers->Graphics support->I2C encoder or helper chips->NXP semiconductors TDA668X HDMI encoder
.
Remember to pay attention to your memory! If your fbp pointer is a int there might be not enough memory!
When your screen displays "No Signal"...
This requires you mount sysfs in advance, add the following content to youretc/rc
mount -t sysfs sys /sys
Then run the following commands:
# cd /sys/class/graphics/fb0
# echo "Whatever you like" > blank
How to capture the screen:
Use the following commands to capture your screen:
$ cat /dev/fb0 > demo.raw
And you may convert it via
ffmpeg
:
$ ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt rgb565 -s 1280X1024 -i demo.raw -f image2 -vcodec png out-%d.png
- Use
apt-src
orwget
to get mplayer, zlib and libmad. Recompile the kernel and make sure the sound drivers are included. - Deploy libmad:
$ ./configure --enable-fpm=arm --host=arm-linux-gnueabihf --enable-speed --prefix=/home/minaduki/Desktop/Beaglebone_Proj/mplayer/install/libmad CC=arm-linux-gnueabihf-gcc
The gcc for arm-linux do not accept the option '-fforce-mem', edit the Makefile generated, delete -fforce-mem
from CFLAGS.
$ make
$ make install
- Deploy zlib:
$ CC=arm-linux-gnueabihf-gcc ./configure --prefix=/home/minaduki/Desktop/Beaglebone_Proj/mplayer/install/glib
$ make
$ make install
- Deploy alsa-lib:
$ ./configure --host=arm-linux-gnueabihf --target=arm-linux --prefix=/home/minaduki/Desktop/Beaglebone_Proj/mplayer/install/alsa-lib --enable-shared --disable-python
or?
$ ./configure --host=arm-linux-gnueabihf --target=arm-linux --prefix=/home/minaduki/Desktop/Beaglebone_Proj/mplayer/install/alsa-lib --enable-static --disable-python --disable-shared
./configure --host=arm-linux-gnueabihf --target=arm-linux --prefix=/home/minaduki/Desktop/Beaglebone_Proj/mplayer/install/alsa-lib --enable-static=yes --disable-python --enable-shared=no
$ make
$ make install
Then copy the libraries to the rootfs.
- Deploy MPlayer: MPlayer requires source of ffmpeg and will clone it from github.com, since the lightning-like speed, we may clone from gitee.com in advance.
$ git clone https://gitee.com/mirrors/ffmpeg.git
Configure & Make:
$ ./configure --cc=arm-linux-gnueabihf-gcc --target=arm-linux-gnueabihf --enable-static --prefix=/home/minaduki/Desktop/Beaglebone_Proj/mplayer/install/mplayer --disable-dvdread --enable-fbdev --disable-mencoder --disable-live --enable-mad --disable-armv5te --disable-armv6 --enable-cross-compile --extra-cflags="-I/home/minaduki/Desktop/Beaglebone_Proj/mplayer/install/libmad/include -I/home/minaduki/Desktop/Beaglebone_Proj/mplayer/install/glib/include" --extra-ldflags="-L/home/minaduki/Desktop/Beaglebone_Proj/mplayer/install/libmad/lib -L/home/minaduki/Desktop/Beaglebone_Proj/mplayer/install/glib/lib"
Whatever library is missing, just copy that f**king library into the rootfs.
CC=arm-linux-gnueabi-gcc ./configure --disable-fpm --host=arm-linux-gnueabi --enable-speed --prefix=/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/libmad
CC=arm-linux-gnueabi-gcc ./configure --prefix=/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/glib
./configure --prefix=/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/mplayer --cc=arm-linux-gnueabi-gcc --target=arm-linux-gnueabi --enable-fbdev --disable-mencoder --disable-live --enable-mad --enable-cross-compile --extra-cflags="-I/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/libmad/include -I/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/glib/include" --extra-ldflags="-L/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/libmad/lib -L/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/glib/lib"
CC=arm-linux-gnueabihf-gcc ./configure --disable-fpm --host=arm-linux-gnueabihf --enable-speed --prefix=/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/libmad
CC=arm-linux-gnueabihf-gcc ./configure --prefix=/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/glib
./configure --prefix=/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/mplayer --cc=arm-linux-gnueabihf-gcc --target=arm-linux-gnueabihf --enable-fbdev --disable-mencoder --disable-live --enable-mad --enable-cross-compile --extra-cflags="-I/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/libmad/include -I/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/glib/include" --extra-ldflags="-L/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/libmad/lib -L/home/minaduki/Desktop/nfsroot/nfs4/pi0/mplayer/install/glib/lib"
- enable in kernel:
Device Drivers → Input device support → Touchscreens → USB Touchscreen Driver