Since entering the post-PC era, along with the development of design and manufacturing technology, integrated circuits have evolved from transistor integration to current IP integration, namely SoC (System on Chip) design technology. This has led to embedded systems penetrating into various industries in today's society and playing an increasingly important role. An embedded system can generally be defined as a dedicated computer system that is application-centric, based on computer technology, with tailorable software and hardware, suitable for application systems, and has strict requirements on functions, costs, volume, and power consumption. Its main features are embedded and application.
As the functions of various embedded devices become more and more powerful, it is inevitable to use embedded operating systems in the devices. The Linux operating system has the characteristics of open source code, easy portability, rich resources, and free, and its position in the embedded field is becoming more and more important. Embedded Linux and Linux on PC are the same set of kernel codes, but the degree of tailoring is different. Therefore, many software developed on PC can be directly run on embedded devices after cross compilation. This article mainly involves three aspects: Bootloader porting and Linux-2.6.32.2 kernel porting, root file system porting, and building a complete embedded development platform on the S3C2440 platform.
1 Establishment of cross-development environment
Before developing embedded software, you must establish an ARM cross-compilation environment on the PC. Cross-compilation is to generate code that can run on the ARM platform on the PC platform. It mainly includes ARM's cross-compiler arm-elf-gcc and cross-linker arm-elf-ld. The cross-compiler version used in this article is gcc-3.4.5-glibc-2.3.6.
The cross-compilation process is shown in Figure 1.
Figure 1 Embedded system cross-compilation process
2 BootLoader Bootloader
BootLoader is a program that starts executing when the system is powered on. It is used to initialize hardware devices, prepare the software environment, set the startup parameters, and finally boot the operating system. It is similar to the BIOS program on a PC. Currently, the main open source Linux boot programs are LILO and GRUB for the x86 architecture, and Vivi and U-Boot for the ARM architecture. This article uses U-Boot as the boot program. U-Boot (Universal Boot Loader) is a universal BootLoader that follows the GPL terms and is open source. Compared with Vivi, U-Boot is more powerful and more convenient for debugging subsequent programs.
The startup of BootLoader is generally divided into two stages. The code of the first stage is mainly written in assembly language. Its main function is to complete the initialization of hardware devices, prepare RAM space for loading the code of the second stage, and set up the stack; the second stage is mainly written in C language, detects memory mapping, reads the kernel image and root file system from Nand Flash to RAM, sets parameters for kernel startup, and boots the kernel.
The source code of U-Boot can be downloaded from ftp://ftp.denx.de/pub/u-boot/ . The U-Boot version used in this article is U-Boot2009.08.
The key steps to port U-Boot are as follows:
(1) First, copy smdk2410.h in the include/configs directory and rename it to mini2440.h. According to the instructions of U-Boot, if you want to use the development board board/
(2) The U-Boot used in this article is started from Nand Flash. The CPU can directly access the first 4 KB of code in Nand Flash and use this 4 KB of code to copy most of the code in U-Boot to the memory [3]. The following code calls the read and write function of Nand Flash in C language. This function mainly copies the code after 4 KB in Nand Flash to RAM. When writing the nand_read_ll function, please refer to the Nand Flash data manual. The read and write commands and timings for large and small pages of Nand Flash are different.
@copy U-Boot to RAM
ldr r0,=TEXT_BASE
mov r1,#0x0
mov r2,#0x60000
bl nand_read_ll
tst r0,#0x0
beq ok_nand_read
Since the Linux kernel and root file system are loaded later using the tftp method, the driver for the DM9000EP network card must be added. In the mini2440.h file, the main configuration is as follows:
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_NET_MULTI 1
#define CONFIG_DM9000_NO_SROM 1
#define CONFIG_DM9000_BASE 0x20000300
#define DM9000_DATA (CONFIG_DM9000_BASE +4)
Among them, CONFIG_DM9000_BASE macro is the most important, because it defines the address of the network card. Different network cards have different addresses. The base address accessed by DM9000EP is 0x20000000. The reason why it is offset by 0x300 is determined by its characteristics.
(3) To correctly boot the Linux kernel, you also need to configure the following important macro definitions. Different macro definitions mean different ways to boot the Linux kernel.
#define CONFIG_BOOTARGS"noinitrd root=/dev/mtdblock3
init=/linuxrc console=ttySAC0,115200 mem=64M"
Among them, root =/dev/mtdblock3 is determined by the Nand Flash partition in Linux, which means that the fourth partition of Nand Flash is the root file system.
#define CONFIG_BOOTCOMMAND"nand read 0x32000000 0x60000 0x560000;bootm 0x32000000"
This macro definition reads the contents of 0x60000 -0x560000 (consistent with the kernel partition) in Nand Flash into memory 0x32000000, and then executes it with the bootm command.
To boot the Linux kernel normally, the following conditions must be met:
(1) CPU registers
R0=0;
R1 = Machine type ID; for ARM architecture CPU, its machine type
Type ID in linux/arch/arm/tools/mach-types;
R2 = The starting base address of the boot parameter tag list in RAM.
(2) CPU operating mode
Interrupts (IRQs and FIQs) must be disabled;
The CPU must be in SVC mode.
(3) Cach and MMU settings
The MMU must be shut down;
Instruction Cach can be turned on or off;
The Data Cache must be closed.
3 Linux 2.6.32.2 kernel porting
3.1 Obtaining the kernel
The Linux kernel is updated very quickly. The latest Linux kernel version can be obtained from http://www.kernel.org/pub/linux/kernel/ . The Linux kernel version used in this article is Linux-2.6.32.2, and the cross-compilation tool uses arm-linux-gcc-4.3.2 that complies with the EABI standard.
3.2 Kernel Porting
You can run the make menuconfig command in the kernel's root directory to tailor the kernel appropriately to suit the hardware platform.
Appropriately tailor the kernel to suit the hardware platform.
(1) Modify the Makefile
To set the default platform of Linux to ARM platform, you need to enter the Linux-2.6.32 folder and modify the Makefile file in this directory.
export KBUILD_BUILDHOST := $(SUBARCH)
ARCH ?=arm // Target platform used
CROSS_COMPILE ?=arm-linux- // The cross compiler used,
The system default compiler is used here
(2) About machine code
When starting the kernel, the machine code (MACH_TYPE) passed by the BootLoader is used to determine which target platform to start [6]. The machine code of this development platform is 1999. The machine code is stored in the file opt/kernel/linux-2.6.32.2/arch/arm/tools/mach-types.
mini2440 MACH_MINI2440 MINI2440 1999 // Machine code
If the machine code does not match, the kernel boot fails and the following error message appears:
Uncompressing
Linux………………………………………………………………………… done, booting the kernel.[page]
(3) Modify the clock source
Rename the mach-smdk2440.c file in the /kernel/linux-2.6.32.2/arch/arm/mach-s3c2440/ directory to mach-mini2440.c.
Because mini2440 and mach-smdk2440.c are extremely similar, this file is used as the basis for modification. In the mach-mini2440.c file, the crystal oscillator frequency in the staticvoid__init smdk2440_map_io (void) function is changed to 12000000 actually used on the mini2440 development board.
(4) Apply the yaffs2 patch to the kernel
①Yaffs2 file system is a file system specially created for embedded devices, especially embedded devices that use Nand Flash as memory. Using yaffs2 can support large-page Nand Flash.
Enter the yaffs2 source code directory and execute the following command:
#./patch -ker.sh c /opt/FriendlyARM/mini2440/linux -2.6.32.2
②Configure the kernel to support Yaffs2 file system
Run make xconfig in the root directory of the Linux kernel source code. In the "File systems" option, find the "Miscellaneous filesystems" menu item, find "YAFFS2 file system support" and select it. This will add support for the yaffs2 file system to the kernel. Save and exit. Then execute make zImage in the command line.
(5) Modify Nand Flash partition information
① Add the partition information of Nand Flash in the mach-mini2440.c file. The following code divides Nand Flash into 4 partitions. The first partition is also the partition where BootLoader is located, corresponding to dev/mtdblock0; the second partition is the parameter partition of U-Boot, corresponding to dev/mtdblock1; the third partition is the kernel partition, corresponding to dev/mtdblock2; the fourth partition is the root file system partition corresponding to dev/mtdblock3. The partition structure diagram is shown in Table 1.
Table 1 Partition structure of 128 MB Nand Flash
Some of the implementation codes are as follows:
static struct mtd_partition mini2440_default_nand_part[] ={
[0] = {
.name="U-boot",
.offset = 0,
.size = 0x00040000,
}
Where name is the name of the partition, offset is the starting address of the offset, and size is the size of the partition. The rest of the partitions are similar.
②The following code is to add the Nand Flash setting table. Because there is only one Nand Flash on the board, there is only one setting table.
static struct s3c2410_nand_set mini2440_nand_sets[] = {
[0] = {
.name = "NAND",
.nr_chips= 1,
.nr_partitions=
ARRAY_SIZE(mini2440_default_nand_part),
.partitions= mini2440_default_nand_part,
}
}
③After completing the above settings, you also need to register the Nand Flash device to the system. The following code is to add the Nand Flash device to the device list structure of the development board.
static struct platform_device *mini2440_devices [] __initdata
= {
&s3c_device_nand,
}
④Add platform data information in the mini2440_machine_init function.
static void __init mini2440_machine_init(void){
s3c_device_nand.dev.platform_data=&mini2440_nand_info;
}
Now you can enter the kernel/linux-2.6.32.2/arch/arm/boot directory and execute the following command, which will generate a kernel image in the uImage.img format that can be booted by U-Boot in this directory.
Mkimage – n 'linux-2.6.32.2 ' –A arm – O linux –T kernel –C none – a 0x30008000 – e 0x30008000 –d zImage uImage.img
At this point, you can copy the generated image file in uImage.img format to the tftp directory and download it using tftp.
3.3 File System
The so-called root file system is to create various directories, such as storing various executable programs in the /bin and /sbin/ directories, storing configuration files in the /etc directory, and storing library files in the /lib directory.
You can use Busybox to create a root file system. Busybox is an open source project that complies with the GPL v2 protocol. It optimizes the file size during the writing process and takes into account the limited system resources (such as memory). Busybox can automatically generate the bin, sbin, usr directories and linuxrc files required for the root file system. You can use make menuconfig to configure Busybox options.
(1) Enter opt/kernel, create a shell script to build the various directories of the root file system, and add execution permissions to it; (2) The init process in Linux will create other child processes based on the etc/inittab file. The following code is the content of the inittab file, which shows that the first script file executed after the system starts is rcS, the virtual terminal is serial port 0, and the system restarts when ctr+alt+del is pressed. The function of the inittab file is to control the running of some programs when and after the system starts.
#etc/inittab
::sysinit:/etc/init.d/rcS
s3c2410_serial0::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -ar
(3) Create the etc/init.d/rcS file, which is a script file in which you can add some commands to be executed automatically.
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S //Run level
prevlevel=N
umask 022 // Folder mask
mount -a // Mount all file systems specified in the /etc/fstab/ file
mdev-s
/bin/hostname -F /etc/sysconfig/HOSTNAME// Host name
Use the tools provided by the yaffs source code to create the image file of the file system. Since the 128MB Nand Flash is a large page structure, you need to use the corresponding large page creation tool; Use the command mkyaffs2image rootfsrootfs.img to generate the root file system image file.
This article discusses U-Boot porting and Linux kernel porting, and gives the key parts of porting U-Boot and Linux to most development boards. Due to the complexity of porting, it is impossible to include all the steps, but through the explanation in this article, you can understand the basic process and key points of porting, provide a reference for porting different versions to other hardware platforms, and build a relatively complete embedded platform for application development.
Previous article:Design of RFID middleware system based on ARM
Next article:ARM-based embedded intelligent control system for residential water supply
Recommended ReadingLatest update time:2024-11-16 17:59
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- [Jihai APM32E103VET6S MINI development board review] FLASH test
- I sent the PCB drawings made by a PCB novice to the PCB manufacturer. They said there was a problem with the drawings. I hope the experts can take a look.
- What kind of motors are generally used in surveillance camera pan/tilts?
- Various LED ring light lighting pattern reference designs
- Hey guys, this is the ADC code of MSP430F5529, how do I fill it in?
- Recruiting MCU sales engineers
- Find a circuit
- Notes on using Arteli ADC - ADON trigger function
- CAN waveform
- How to read and analyze labview program