Linux 3.4.2 Kernel Porting

Experimental Platform: Jz2440 Development Board

1. Simple modification of linux 3.4.2 kernel transplantation

1. Download the 3.4.2 kernel from the website and get the linux server decompression kernel:

tar xjf linux-3.4.2.tar.bz2

2. Enter the linux-3.4.2 directory and modify Makefile to specify the CPU architecture and cross-compiler:

cd linux-3.4.2/
vim Makefile

Line 159 finds the following code:

ARCH        ?= $(SUBARCH)
CROSS_COMPILE   ?= $(CONFIG_CROSS_COMPILE:"%"=%)

Modify to:

ARCH        ?= arm
CROSS_COMPILE   ?= arm-linux-

Note: The cross-compiler version used here is 4.3.2, and a lower version compiler may fail to compile

3. Configure the linux kernel, compile:

make s3c2410_defconfig
make uImage

The following errors occurred during compilation:

Solution: Change 373 lines of the kernel/timeconst.pl file if (!Defined(@val){to if (!(@val){.

Recompile, compiled successfully:

4. Burn the compiled uImage onto the development board:
Type the following command in uboot to burn uImage to the development board: (Note: You need to copy the compiled uImage to/home/book/works/first_fs/directory)

nfs 32000000 192.168.2.109:/home/book/works/first_fs/uImage

uImage burned successfully:

Note: If an error occurs: Loading: T *** ERROR: File lookup fail, two more burns will succeed, provided the Ubuntu server is developed to ping through.

5. Start the linux kernel:
Start the Linux kernel by typing the following command in uboot:

bootm 32000000

The printed information is as follows:

As you can see from the figure above, the serial output is garbled.Obviously, although our kernel has been started, the serial port settings are definitely not set up.
By analyzing the uboot source code, the way to get and its ID is to get it from the environment variable, or use the default ID, the default MACH ID in uboot:

gd->bd->bi_arch_number = MACH_TYPE_SMDK2410; // MACH_TYPE_SMDK2410 = 193

If s = getenv("machid"); use it if successful.
We can set ourselves in the environment variable first: (enter the following command in uboot)

set machid 16a     // smdk2440 mach-smdk2440.c

perhaps

set machid 7CF // mini2440 mach-mini2440.c

Note: This setting is for testing purposes only, without setting machid, only modifying the crystal frequency can also boot the kernel normally.
The Jz2440 development board uses 12M crystal vibration, so 165 lines of arch/arm/mach-s3c24xx/mach-smdk2440.c are required:

s3c24xx_init_clocks(16934400);

Change to:

s3c24xx_init_clocks(12000000);

Modify uboot's environment variables as well:

set bootargs console=ttySAC0,115200 root=dev/mtdblock3

Burn the recompiled uImage to the development board via nfs and start linux with the following printed information:

As you can see from the image above, you can finally print the characters normally, but the kernel has not been started successfully.

2. Modified System Partition for linux 3.4.2 Kernel Transplantation

The previous section was able to start linux and print characters normally, but the linux kernel was not started successfully. The last printed information is as follows:

From the print information, we can see that our partition is wrong. In uboot porting, we have partitioned the whole system. Now printing says that our partition is wrong. It must be that there are partition-related settings in the kernel. We need to modify the kernel.
From the information printed below,

Search in the linux top directory for grep-nR "Boot Agent" and find that 113 rows in common-smdk.c have partition settings:

/* NAND parititon from 2.4.18-swl5 */

static struct mtd_partition smdk_default_nand_part[] = {
	[0] = {
		.name	= "Boot Agent",
		.size	= SZ_16K,
		.offset	= 0,
	},
	[1] = {
		.name	= "S3C2410 flash partition 1",
		.offset = 0,
		.size	= SZ_2M,
	},
	[2] = {
		.name	= "S3C2410 flash partition 2",
		.offset = SZ_4M,
		.size	= SZ_4M,
	},
	[3] = {
		.name	= "S3C2410 flash partition 3",
		.offset	= SZ_8M,
		.size	= SZ_2M,
	},
	[4] = {
		.name	= "S3C2410 flash partition 4",
		.offset = SZ_1M * 10,
		.size	= SZ_4M,
	},
	[5] = {
		.name	= "S3C2410 flash partition 5",
		.offset	= SZ_1M * 14,
		.size	= SZ_1M * 10,
	},
	[6] = {
		.name	= "S3C2410 flash partition 6",
		.offset	= SZ_1M * 24,
		.size	= SZ_1M * 24,
	},
	[7] = {
		.name	= "S3C2410 flash partition 7",
		.offset = SZ_1M * 48,
		.size	= MTDPART_SIZ_FULL,
	}
};

The uboot partition is as follows:

0x00000000-0x00040000 : "bootloader"
0x00040000-0x00060000 : "params"
0x00060000-0x00260000 : "kernel"
0x00260000-0x10000000 : "root"

The linux system partition needs to be changed to:

/* NAND parititon from 2.4.18-swl5 */

static struct mtd_partition smdk_default_nand_part[] = {
	[0] = {
		.name	= "bootloader",
		.size	= SZ_256K,
		.offset	= 0,
	},
	[1] = {
		.name	= "params",
		.offset = MTDPART_OFS_APPEND, //Next to the previous partition
		.size	= SZ_128k,
	},
	[2] = {
		.name	= "kernel",
		.offset = MTDPART_OFS_APPEND,
		.size	= SZ_2M,
	},
	[3] = {
		.name	= "rootfs",
		.offset	= MTDPART_OFS_APPEND,
		.size	= MTDPART_SIZ_FULL,//All remaining partitions
	},
};

Recompile, write uImage to the development board, and start, with the final printed information as follows:

As you can see, our partition is working, but we are missing a file system and not burning.
Let's start by burning a simple file system to see if it works:

nfs 30000000 192.168.2.120:/home/book/works/first_fs/fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000 889bc0 

Note: 192.168.2.120 is the IP address of the Ubuntu server. Because IP is assigned dynamically, it is different from the previous one.
Download the kernel after burning the file system to start:

nfs 32000000 192.168.2.120:/home/book/works/first_fs/uImage
bootm 32000000

It is found that the yaffs2 file system is not supported, so try again if the jffs file system is okay:

 nfs 30000000 192.168.2.120:/home/book/works/first_fs/fs_mini_mdev.jffs2
 nand erase.part rootfs
 nand write.jffs2 30000000 260000 5b89a8
 nfs 32000000 192.168.2.120:/home/book/works/first_fs/uImage
 bootm 32000000

The printed information is as follows:

From the information printed above, the jffs2 file system was mounted successfully, but the kernel did not start successfully.
For ifconfig: SIOCSIFADDR: No such device This problem should be that the network card driver is not ported well.There are two solutions: 1) migrate the linux DM9000 network card driver; 2) comment out ifconfig eth0 xxx.xxx.xxx.xxx x.xxxx in etc/init.d/rcS (Note: someone on someone's blog said that it eventually got stuck in starting PID 933, TTY':'/etc/init.d/rcS', because the file system needs the same version of the tool chain that compiles the kernel)

3. Make a kernel-enabled file system from 0

1. Compile Busybox
Get version 1.20.0 of the busybox source Download Address , take the downloaded source to the Linux system, unzip it, go to the source directory, and then directly:

make menuconfig

The following interface appears:

Set up a cross-compiler:
Choice:
Busybox Settings —>
Build Options —>
Cross Compiler prefix (NEW)
Then a bar appears where you can enter the prefix of our compiler:

After configuring, exit saving the configuration.
Then compile directly:make
Once compilation is complete, install it to fs_mini_mdev_new, and create a new directory:

mkdir fs_mini_mdev_new

Switch to the busybox directory for installation:

make install CONFIG_PREFIX=../fs_mini_mdev_new

After the installation, the files in the fs_mini_mdev_new directory are as follows:

The first step is complete, busybox is installed, and the next step is to install the library.

2. Installation Library
View the path to the tool chain: echo $PATH
The path to the known tool chain is: /work/tools/arm-linux-gcc-4.3.2/bin
Enter / work/tools/arm-linux-gcc-4.3.2/directory: cd/work/tools/arm-linux-gcc-4.3.2/
Input: find-name Lib
A number of libraries were found as follows:

Only two libraries are used:

./arm-none-linux-gnueabi/libc/armv4t/usr/lib
./arm-none-linux-gnueabi/libc/armv4t/lib

We just need to copy the two libraries here:
First create a lib directory in the fs_mini_mdev_new directory, then copy all.so files in the / work/tools/arm-linux-gcc-4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib directory to the Lib directory of fs_mini_mdev_new:

Cp/work/tools/arm-linux-gcc-4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib/*so*/home/book/works/busybox/fs_mini_mdev_new/lib-d (-d stands for linked file, copied or linked file)

There is also a library to add:
Create a new lib directory in the / home/book/works/busybox/fs_mini_mdev_new/usr directory, and copy all.so files to the / work/tools/arm-linux-gcc-4.3.2//arm-none-linux-gnueabi/libc/armv4t/usr/lib directory under the / home/book/works/busybox/fs_mini_mdev_new/uslib directory:

cp /work/tools/arm-linux-gcc-4.3.2/arm-none-linux-gnueabi/libc/armv4t/usr/lib/*so* /home/book/works/busybox/fs_mini_mdev_new/usr/lib -d

Now that the library has been added, the next step is to construct some other directories (etc, dev, etc.)

3. Construct the etc directory:
3.1 Create etc/inittab file
Create an etc directory in the fs_mini_mdev_new directory and an inittab file in the etc directory, as follows:

# /etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r

3.2 Create etc/init.d/rcS file
This is a script that adds commands that you want to execute automatically.The following commands configure the IP address, hook/etc/fstab specified file system.

#!/bin/sh
ifconfig eth0 192.168.2.200
mount -a

Where:
The first line indicates that this is a script file that is parsed at run time using / bin/sh.
The third line hooks all the file systems specified by the / etc/fstab file.
Finally, change its properties so that it can execute:

chmod +x etc/init.d/rcS

3.3 Create etc/fstab file
This means that the proc, tmpfs file systems will be hooked after the command "mount-a" is executed

# device     mount-point     type     options    dump    fsck    order

proc          /proc           proc    defaults     0      0
tmpfs         /tmp            tmpfs   defaults     0      0

Note: /etc/fstab files are used to define the "static information" of the file system that controls the behavior of the mount command.

4. Build dev directory
This directory contains device files.Device files are a unique file type in Linux system. On Linux system, various peripherals are accessed as files, that is, to operate a specific hardware by reading and writing a device file.For example,'/dev/ttySAC0'file allows you to manipulate serial port 0, and / dev/mtdblock1 allows you to access the second partition of MTD devices (NAND Flash, NOR Flash, etc.).
There are three ways to create / dev:
Manual creation: Create device files such as ttySAC0 in the / dev directory when you are making the root file system.Once the system is hooked up to the root file system, you can use the device files in the / dev directory.
(2) Using the devfs file system: This method is obsolete
(3) Using udev:udev is a user program that can update device files according to the status of hardware settings in the system, including the creation and deletion of device files.The udev mechanism also does not require the creation of device nodes in the / dev directory, it requires some user program support, and the kernel supports the sysfs file system.It is more complex to operate, but more flexible.In busybox, there is an mdev command, which is a simplified version of the udev command.

Then we use mdev to create device files: to run mdev automatically at kernel startup, you need to modify etc/fstab files to automatically mount the file system, modify etc/init.d/rcS files to add commands to run automatically.
Modifications to etc/fstab:

# device     mount-point     type     options    dump    fsck    order

proc          /proc           proc    defaults     0      0
tmpfs         /tmp            tmpfs   defaults     0      0
sysfs         /sys            sysfs   defaults     0      0
tmpfs         /dev             tmpfs  defaults     0      0

Modification of etc/init.d/rcS:

#!/bin/sh
ifconfig eth0 192.168.1.104
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

In addition, mdev is started by the init process, which uses at least / dev/console and / dev/null device files before using the mdev construct/dev directory, so create these two files:

mkdir dev
cd dev
sudo mknod console c 5 1
sudo mknod null c 1 3

5. Build other directories

mkdir proc mnt sys root tmp

Now our / work/nfs_root/fs_mini_mdev_new directory is a very small root file system.The development board can start it directly as the network root file system.If you want to burn it to the development board, you also need to make it into a file called an image file.

6. Making File System Image Files
6.1 First you need to compile a tool to make a jffs2 image file
Tools: mtd-utils-05.07.23.tar.bz2 is a toolkit for MTD devices. It is compiled to generate the mkfs.jffs2 tool, which can be used to make a directory into a JFFS2 file system image file.This toolkit requires a zlib zip package. Install zlib first.(The files mtd-utils-05.07.23.tar.bz2 and zlib-1.2.3.tar.gz can be found on the data disc of the Jz2440 development board)
First install zlib:

tar xzf zlib-1.2.3.tar.gz
cd zlib-1.2.3
./configure --shared --prefix=/usr
make
sudo make install

(2) Then compile mkfs.jffs2

tar xjf mtd-utils-05.07.23.tar.bz2
cd mtd-utils-05.07.23/util
make
sudo make install

6.2 Make a jffs2 image file
Enter the directory where fs_mini_mdev_new is located and enter the following command:

mkfs.jffs2 -n -s 2048 -e 128KiB -d fs_mini_mdev_new -o fs_mini_mdev_new.jffs2

Above, -n means d o n't put a erase flag o n each erase block, -s 2018 means that o n e page of our NAND Flash is 2048 bytes in size, -e 128 KiB means a 128 KiB erase fast size, -d means the directory of the root file system, -o means the output file.

 nfs 30000000 192.168.2.120:/home/book/works/busybox/fs_mini_mdev_new.jffs2
 nand erase.part rootfs
 nand write.jffs2 30000000 260000 $filesize
 set bootargs console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=jffs2
 nfs 32000000 192.168.2.120:/home/book/works/first_fs/uImage
 bootm 32000000

Serial output is normal, linux is also normal to start, the whole system is running.

Note: In the video tutorial, an error occurred: Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000200.
Analyze this error: Search for the string in the kernel: exitcode, through analysis of function layer calls, and find: do_exit(SIGKILL); execute this call, error code 4 appears, because the compilation tool used to compile the kernel is EABI interface, we need to reconfigure the kernel to use EABI interface:
linux:make menuconfig needs to be configured before compiling the kernel
Then choose:
Kernel Features —>
[*] Use the ARM EABI to compile the kernel

4. Modify the kernel code to support YAFFS file system

The last section produced the jffs2 file system from 0 because the linux 3.4.2 kernel itself supports the jffs2 file system, but it does not support the yaffs file system, so now it supports the yaffs file system by modifying the linux kernel source code.
1. Get yaffs source code
There are many ways to get the source yaffs source code, here I am the yaffs source directly from the Jz2440 development board CD material.Copy it to the Ubuntu server and unzip it.

2. Patch the linux kernel
Go to the yaffs2 source directory and patch with the following command:

./patch-ker.sh c m /home/book/works/linux-3.4.2  //This is my linux kernel source directory

After patching, the source code for yaffs will be added to the kernel's fs/yaffs2 directory

3. Configure the kernel to support YAFFS
In the top directory of the linux source, type:

make menuconfig

Select in turn:

File systems  ---> 
     Miscellaneous filesystems  ---> 
        <*>   yaffs2 file system support 

Then save the configuration.Recompile the kernel:

make uImage

Compilation succeeded.

4. Make a yaffs2 file system image
In the last section, we've made the file system, and now we're making the yaffs2 image.In the directory where fs_mini_mdev_new is located, enter the following command:

mkyaffs2image fs_mini_mdev_new fs_mini_mdev_new.yaffs2

yaffs2 file system image is made.

5. Burn YAFFS File System Image
Type the following command in uboot:

nfs 30000000 192.168.2.120:/home/book/works/busybox/fs_mini_mdev_new.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 260000 $filesize

6. Burn New Kernel Start
Before burning the kernel, set the boot parameters at uboot:

set bootargs console=ttySAC0,115200 root=/dev/mtdblock3
save

Burn Kernel:

 nfs 32000000 192.168.2.120:/home/book/works/first_fs/uImage
 bootm 32000000

As shown in the figure below, the yaffs file system was mounted successfully, the linux was started successfully, and the whole system was running normally.

7. Make Kernel Patches
Finally, we will transplant the kernel and generate patches for future use:

cp .config config_ok
make distclean
mv linux-3.4.2 linux-3.4.2_100ask
tar xjf linux-3.4.2.tar.bz2
diff -urN linux-3.4.2 linux-3.4.2_100ask > linux-3.4.2_100ask.patch

8. How to patch:

patch -p1 < ../linux-3.4.2_100ask.patch
cp config_ok .config
make uImage

9. Burn the previously modified uImage to the development board (Note: it is burned to Nand flash, before it is burned to an address in SDRAM, then boot the kernel from this address)

nfs 32000000 192.168.2.120:/home/book/works/first_fs/uImage
nand erase.part kernel
nand write 32000000 kernel

Restart the development board, print the following information, linux failed to start.

The image above shows a checksum error, Data Size is 2.4M. We have only allocated 2M storage space for the kernel partition before. This is certainly not enough, so we need to change the kernel partition to a larger size, so here we will change it to 4M.
(1) Modify the uboot source:
Repartition uboot as follows: (Change kernel partition to 4M)

0x00000000-0x00040000 : "bootloader" (0~256k)
0x00040000-0x00060000 : "params"
0x00060000-0x00460000 : "kernel"
0x00460000-0x10000000 : "root"

Modify uboot's configuration file include/configs/smdk2440.h:

#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define MTDIDS_DEFAULT      "nand0=jz2440-0"    /* Which device does it represent? */
#define MTDPARTS_DEFAULT    "mtdparts=jz2440-0:256k(u-boot),"   \
                            "128k(params),"     \
                            "2m(kernel),"   \
                            "-(rootfs)"     \

Change to:

#define CONFIG_CMD_MTDPARTS
#define CONFIG_MTD_DEVICE
#define MTDIDS_DEFAULT      "nand0=jz2440-0"    /* Which device does it represent? */
#define MTDPARTS_DEFAULT    "mtdparts=jz2440-0:256k(u-boot),"   \
                            "128k(params),"     \
                            "4m(kernel),"   \
                            "-(rootfs)"     \

Recompile, rewrite uboot, and enter the command: mtdparts at uboot. As you can see from the following figure, the kernel partition has been modified to 4MB.

(2) Modify the linux system partition:
Set 113 rows in common-smdk.c to a partition:

/* NAND parititon from 2.4.18-swl5 */

static struct mtd_partition smdk_default_nand_part[] = {
	[0] = {
		.name	= "bootloader",
		.size	= SZ_256K,
		.offset	= 0,
	},
	[1] = {
		.name	= "params",
		.offset = MTDPART_OFS_APPEND, //Next to the previous partition
		.size	= SZ_128k,
	},
	[2] = {
		.name	= "kernel",
		.offset = MTDPART_OFS_APPEND,
		.size	= SZ_4M,
	},
	[3] = {
		.name	= "rootfs",
		.offset	= MTDPART_OFS_APPEND,
		.size	= MTDPART_SIZ_FULL,//All remaining partitions
	},
};

(3) Recompile uImage and burn the kernel.

nfs 32000000 192.168.2.120:/home/book/works/first_fs/uImage
nand erase.part kernel
nand write 32000000 60000 $filesize

Start the kernel from 0x32000000 and print the following information to show that the linux system partition was modified successfully.

(4) Rewrite yaffs2 file system:

nfs 30000000 192.168.2.120:/home/book/works/busybox/fs_mini_mdev_new.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 460000 $filesize

Reset the uboot start command:

set bootcmd "nand read 30000000 kernel 0x400000;bootm 30000000"
save

Then enter the name: reset, restart the development board, linux started successfully.

Then repeat the step "7. Make a kernel patch" and re-create the patch file.

Published 6 original articles. Praise 2. Visits 255
Private letter follow

Tags: Linux zlib sudo Ubuntu

Posted on Tue, 04 Feb 2020 21:48:13 -0500 by vietnamese