Install git.
$ sudo apt-get install git
Install the ARM cross-compiler.
$ sudo apt-get install gcc-arm-linux-gnueabi
Install the software needed to build the Linux kernel.
$ sudo apt-get install flex bison libncurses-dev libssl-dev
Install QEMU for ARM.
$ sudo apt-get install qemu-system-arm
In the following items, the structure of the created directory is as follows.
{top_directory} ├ linux-stable │ └ arch │ └ arm │ └ boot │ ├ zImage: Kernel image │ └ dts │ └ versatile-pb.dtb: Device tree │ ├ busybox │ ├ _install: root file system │ └ rootfs.img: Image of root file system │ ├ driver │ └ sample │ └ driver_sample.ko: Device driver module │ └ app └ sample └ app_sample: Run binary file of the app ~~~
Clone the Linux kernel (Stable Kernel).
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
Navigate to the cloned directory.
$ cd linux-stable
Apply the default settings for Arm Versatile boards (versatilepb).
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- versatile_defconfig
Build.
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
Make sure that the kernel image and device tree have been generated.
$ ls -latr arch/arm/boot/dts/versatile-pb.dtb
$ ls -latr arch/arm/boot/zImage
Clone BusyBox.
$ git clone git://git.busybox.net/busybox
Navigate to the cloned directory.
$ cd busybox
Apply the default settings.
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- defconfig
We need to statically link to work with a single binary, so run the make menuconfig command to enable the kernel config "Build static binary (no shared libs)".
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
Settings --> Build static binary (no shared libs)
Build.
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
Install. When the installation is complete, a root file system will be created under the _install directory.
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- install
Create a directory for the device driver and change to it.
$ mkdir -p driver/sample
$ cd driver/sample
Create the source code for the device driver. (The following source code is a sample device driver that just loads / unloads.)
$ nano driver_sample.c
#include <linux/module.h>
#include <linux/kernel.h>
static int __init sample_module_init( void )
{
printk( "driver sample load\n" );
return 0;
}
static void __exit sample_module_exit( void )
{
printk( "driver sample remove\n" );
}
module_init( sample_module_init );
module_exit( sample_module_exit );
MODULE_DESCRIPTION( "sample_module" );
MODULE_LICENSE( "GPL" );
Create a Makefile.
$ nano Makefile
obj-m := driver_sample.o
all:
make -C $(shell pwd)/../../linux M=$(shell pwd) modules
clean:
make -C $(shell pwd)/../../linux M=$(shell pwd) clean
Cross-compile the device driver.
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
Copy the device driver into busybox's _install directory.
$ cp driver_sample.ko ../../busybox/_install/
Create a directory for your app and change to it.
$ mkdir -p app/sample
$ cd app/sample
Create the source code for your app. (The following source code is a sample application that only outputs logs.)
$ nano app_sample.c
#include <stdio.h>
int main(int argc, char *argv[])
{
printf( "app sample run\n" );
return 0;
}
Create a Makefile.
$ nano Makefile
TARGET = app_sample
CC = ${CROSS_COMPILE}gcc
LD = ${CROSS_COMPILE}gcc
CSRCS = $(TARGET).c
CFLAGS = -c
LDFLAGS = -static -o $(TARGET)
OBJS = $(CSRCS:.c=.o)
LIBS =
.c.o:
$(CC) $(CFLAGS) $<
$(TARGET): $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) $(LIBS)
clean: ;
rm $(OBJS) $(TARGET)
Cross-compile your app.
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
Copy the app into busybox's _install directory.
$ cp app_sample ../../busybox/_install/
Image the root file system.
$ cd busybox/_install/
$ find .| cpio -o --format=newc > ../rootfs.img
$ cd ../../
Run QEMU.
$ qemu-system-arm \
-M versatilepb \
-kernel ./linux/arch/arm/boot/zImage \
-dtb ./linux/arch/arm/boot/dts/versatile-pb.dtb \
-nographic \
-append "rdinit=/bin/sh" \
-initrd ./busybox/rootfs.img
When the startup is complete, the shell will start. Checking with the ls command, the root file system looks like this:
/ # ls
app_sample dev linuxrc sbin
bin driver_sample.ko root usr
/ #
Load the device driver.
/ # insmod driver_sample.ko
driver_sample: loading out-of-tree module taints kernel.
driver sample load
Run the app.
/ # ./app_sample
app sample run
Recommended Posts