Getting started with Linux drivers (3) - source code download reading, analysis and introduction to embedded file systems


Starting from the kernel

Get the kernel source code

Log in to the official website of the Linux kernel to obtain the current version of the Linux source code at any time. Can be in full compressed form (use tarthe command to create a compressed file), or in incremental patch form.
Except in special cases where an old version of the Linux source code is needed, it is generally desirable to have the latest code. kernel.orgIn addition to the source code inventory, incremental patches released by leading kernel developers are also placed here.

use Git

All the while, Linus and his kernel developers started using a new version of the control system to manage the Linux kernel source code. The system created by Linus is called Git. Unlike traditional version control systems such as CSV, Git is distributed, and its usage and workflow are unfamiliar to many developers, but it is still strongly recommended to use Git to download and manage Linux kernel source code.
You can use Git to get a copy of the latest commits into the Linus version tree: ( 为了保持对书籍的同步,所以这里也下载2.6版本,自己也会下载较新的版本进行后面的驱动实验)
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
insert image description here
还是比较慢的!!!

After downloading the code, you can update your branch to the latest branch of Linus:
git pull
With these two commands, you can obtain and keep consistent with the official kernel code tree at any time. To submit and manage your own modifications will be introduced later. About Git learning recommended Git learning website

Install the kernel source

Since the download from the official website is relatively slow, the source code download address is recommended. Kernel compression is released
in two forms: GNU zip( gzip) and . bzipbzip2 is the default and preferred form because it has an advantage over gzip in compression. The Linux kernel released in the form of bip2 is called linux-x.y.z.tar.bz2, here x.y.zis the specific version of the kernel source code. Once the source code is downloaded, it can be easily unpacked. Run if the compression is bzip2
tar xvjf linux-x.y.z.tar.bz2
Run if the compression is GNU's zip:
tar xvzf linux-x.y.x.tar.gz
Where to install and touch the source?
The kernel source code is generally installed in /usr/src/linuxthe directory. But please be careful not to use this source tree for development, because the kernel version used to compile your C library is linked to this tree. Also, instead of making changes to the kernel as root, create your own home directory and install new kernels only as root. Even when installing a new kernel, /usr/src/linuxthe directories should remain intact.

use patch

In the Linux kernel community, patch is the lingua franca. You can publish changes to the code as patches, and you can receive changes made by others as patches. Incremental patches can be used as a bridge for version transfer. You no longer need to download the entire zip of the huge kernel source code, but just apply an incremental patch to the old version to make it look new. This not only saves bandwidth, but also saves time. To apply an incremental patch, starting from your kernel source tree, just run:
patch -p1 < ../patch-x.y.z
In general, a kernel patch for a given version is always applied over the previous version.

Read the Linux kernel source code

As follows, we have downloaded the source code of the Linux Kernel. In order to facilitate reading the source code, we can use tools to complete it.
insert image description here

Introduction to Source Insight

For the introduction and use of Source Insight, you can refer to this blog. Or find information directly on the Internet for learning
reference blog

read the source code

以下内容仅是我个人喜好,大家学会后可自行搭建属于自己风格的方式
1. View the code on the Linux server on Winows - map the Linux server to the Windows local
use the sftp tool to map the Linux server to the local. ( 网上搜索下载该工具即可)
insert image description here
insert image description here
2. Open Source Insight to build a project.
By default, Source Insight only supports *.c和*.hfiles, and most of the Linux source codes have *.Sassembly language files ending with . .
insert image description here
insert image description here
insert image description here
insert image description here
添加头文件路径
Build another project, add the Linux header file path include, or choose the header file you need to add. Reopen the previously created file and add the header file path
insert image description here
so that the header file can be freely jumped.

安装内核
After the kernel is compiled, you need to install it. BootloaderHow to install is closely related to the architecture and the boot tool ( ) - consult the instructions of the boot tool, follow its instructions to copy the kernel image to a suitable location, and install it according to the boot requirements . Be sure to have one or two bootable kernels at all times in case problems arise with newly compiled kernels.
For example, on an x86 system using grub, it may be necessary to copy arch/i386/boot/bzImage. to /boota directory, vmlinuxz-versionname it like this, and edit /etc/grub/grub.confthe file to create a new boot entry for the new kernel. A system booted with LILO should be edited /etc/lilo.conf, then run lilo.
Fortunately, module installation is automatic and architecture-independent. As root, just run:
% make modules_install
to correctly install all compiled modules into the home directory /lib/modules.
A file is also created at the root of the kernel code tree when compiling System.map. This is a symbol comparison table that maps kernel symbols to their starting addresses. This is useful when debugging, if you need to translate memory addresses into understandable function and variable names.

Features of Kernel Development

Kernel development has some unique features relative to the development of applications in user space. Although these differences do not make developing kernel code any more difficult than developing user code, they are still very different.
These characteristics make the kernel a beast with a very different character. Some commonly used norms were overturned, and many entirely new ones had to be established. While many of the differences are self-explanatory, there are others that are obscure, the most important of which include the following:

  • Neither the C library nor the standard C header files can be accessed when programming the kernel
  • GNU C must be used for kernel programming.
  • Kernel programming lacks a memory protection mechanism like user space.
  • It is difficult to perform floating-point operations when programming internally.
  • The kernel gives each process only a small fixed-length stack.
  • Since the kernel supports asynchronous interrupts, preemption, and SMP, one must always be careful about synchronization and concurrency.
  • Consider the importance of portability.

No libc library or no standard header files

The main reason is that the full C library - even a subset of it - is too large and inefficient for the kernel.
For the kernel, the basic header files are located includein the top-level directory of the kernel source code; the architecture-related header file sets are located in arch/<architecture>/include/asmthe directory of the kernel source tree. Kernel code usually includes these header files prefixed asm/with . One notable difference between e.g. <asm/ioctl.h>
kernel functions printk()and libc functions () is that allows you to set priority via a flag. It will decide where to display this system message according to the priority flag. Here is an example using priority flags:printfprintk()syslog

printk(KERN_ERR "this is an error!\n");

注意:在KERN_ERR和要打印的消息之间没有逗号,这样写是别有用意的。优先级标志是预处理程序定义的一个描述性字符串,在编译时优先级标志就与要打印的消息绑定在一起处理。

GNU C

1. Inline ( inline) function
Both C99 and GNU C support inline functions. inlineThe name reflects how it works, and the function expands where it is called. Doing so eliminates the overhead of function calls and returns ( 寄存器存储和恢复). Moreover, since the compiler will optimize the code that calls the function and the function itself together, it is also possible to further optimize the code. However, there is a price to do so, the code will become longer, which means more memory space or more instruction cache. 内核开发者通常要把那些时间要求比较高,而本身长度又比较短的函数定义成内联函数。If a function is large, will be called repeatedly, and has no special time limit, we do not agree to make it an inline function.
When defining an inline function, you need to use staticas a keyword and inlinequalify it with . for example:

static inline void wolf(unsigned long tail_size)

Inline functions must be defined before they are used, otherwise the compiler will not be able to expand the function. In practice, inline functions are generally defined in header files. Since static is used as a keyword to restrict, a separate function body will not be created for the inline function during compilation. If an inline function is only used in a source file, it can also be defined at the beginning of the file.
在内核中,为了类型安全和易读性,优先使用内联函数而不是复杂的宏
2. Inline assembly
The gcc compiler supports embedding assembly instructions in C functions. Of course, when programming the kernel, this function can only be used if the corresponding architecture is known.
We usually embed assembly code using asm()the instruction register. For example, the following inline assembly instruction is used to execute the rdtsc instruction of the x86 processor and return the value of the time stamp (tsc) register.

unsigned int low, high;
asm volatile("rdtsc": "=a" (low), "=d" (high));
/*low和high分别包含64位时间戳的低32位和高32位*/

The Linux kernel uses a mix of C and assembly language. 在偏近体系结构的底层或对执行时间要求严格的地方,一般使用的是汇编语言。在内核其他部分的大部分代码是使用C语言编写的.
3. Branch statement
For the conditional selection statement, gcc has a built-in instruction for optimization. When a condition occurs frequently or rarely, the compiler can use this instruction to optimize the conditional branch selection. The kernel encapsulates this instruction into a macro, for example likely()和unlikely(). This is more convenient to use.
For example, the following is a conditional select statement:

if(error){
    
    
	/*...*/
}
//如果想要把这恶鬼选择标记成绝少发生的分支;
/*我们会认为error绝大多数时间会为0*/
if(unlikely(error)){
    
    
	/**.../
}
//相反,如果我们想把一个分支标记为通常为真的选择:
/**我们认为success通常不会为0/
if(likely(success)){
	/*....*/
}

Before you want to optimize a conditional selection statement, you must find out whether there is such a condition in it, which will be true in most cases. This is very important: if you are right that the condition is overwhelming, performance will improve; if you are wrong, performance will degrade. As the above example shows, it is usually used when judging some error conditions likey()和unlikely(). As you can guess, unlikey()it is more widely used in the kernel, since if statements tend to evaluate a special case.

no memory protection mechanism

If a user Chen Xu tries to perform an illegal memory access, the kernel will detect the error, send SIGSEGVa signal, and end the entire process. However, if the kernel itself illegally accesses the memory, the consequences will be difficult to control. (After all, who can take care of the kernel?) Memory errors that occur in the kernel cause oops, which is the most common type of error that occurs in the kernel. In the kernel, you should not access illegal memory addresses, refer to null pointers and other things, otherwise it may die without telling you at all-in the kernel, the risk is often greater than outside.
Also, no memory in the kernel is paged. In other words, every byte you use reduces physical memory by one byte, so keep this in mind when you want to add new features to the kernel.

Don't lightly use floating point numbers in the kernel

When performing floating-point numbers in the process of user space, the kernel will complete the mode conversion from integer operations to floating-point operations. Exactly what to do when executing floating-point instructions varies from architecture to architecture, but usually the kernel catches the trap and proceeds with the conversion from integer to floating-point.
Unlike userspace processes, the kernel does not perfectly support floating point operations, since it cannot trap itself. When using floating-point numbers in the kernel, in addition to manually saving and restoring floating-point registers, there are other trivial things to do. If you want to answer directly, it is: don't do it, except in rare cases, don't use floating point operations in the kernel.

Small and fixed stack

The exact size of the kernel stack varies by architecture. On x86, the stack size is configured at compile time and can be 4KB or 8KB. Historically speaking, the size of the kernel stack is two pages, which means that the kernel stack of a 32-bit machine is 8KB, while that of a 64-bit machine is 16KB, which is fixed. Each processor has its own stack.

synchronization and concurrency

The kernel is prone to race conditions. Unlike single-threaded user programs, many features of the kernel require concurrent access to shared data, which requires a synchronization mechanism to ensure that no race conditions occur, especially:

  • Linux is a preemptive multitasking operating system. The kernel's process scheduler schedules and reschedules processes on the fly. The kernel must be synchronized with these tasks.
  • The Linux kernel supports Symmetric Multiprocessing (SMP). So, without proper protection, kernel code executing on two or more processors at the same time is likely to access the same shared resource at the same time.
  • Interrupts arrive asynchronously, with no regard for currently executing code. In other words, if not properly protected, it is entirely possible for an interrupt to arrive when the code is accessing a resource, so that the interrupt handler may access the same resource.
  • The Linux kernel can be preemptive. So, if not properly protected, one piece of executing code in the kernel may be preempted by another piece of code, potentially causing several pieces of code to access related resources at the same time.
    Commonly used solutions to contention are spin locks and semaphores. Introduced later.

The Importance of Portability

Although user-space applications pay little attention to portability, Linux is a portable operating system, and will remain so. That is to say, most C code should be architecture-independent, and can be compiled and executed on computers with many different architectures. Therefore, architecture-dependent code must be properly separated from specific directories in the kernel code tree.
Guidelines such as preserving endianness, 64-bit alignment, and not assuming word and page lengths all aid in portability.

Linux source code analysis

Linux source code structure analysis

insert image description here
Linux Source Code

arch directory

Contains code related to the architecture. Each platform has a corresponding directory. The common directories are as follows:
insert image description here

drivers directory

Contains most drivers supported by the Linux kernel. Each driver occupies a subdirectory. The directory contains most of the codes of the driver, and the codes and directory functions are shown in the following table:
insert image description here
注:这本书比较老了,是基于的Linux 2.6.30版本. For details, please refer to the above Linux source code page for reference and learning.

fs directory

fs目录中包含了Linux所支持的所有文件系统相关的代码. Each subdirectory contains a file system such as msodsand ext3. Linux supports almost all current file systems. If you find a new file system that is not supported, you can easily add a new file system directory in the fs directory and implement a file system. The details of the fs directory are as follows:
insert image description here

other directories

In addition to the directories introduced above, there are other important directories and files in the kernel. Each directory and file has its own special function. The following is a brief introduction to these directories and files:
insert image description here

Kernel configuration options

To build an embedded Linux operating system by yourself, you first need to configure the kernel source code accordingly. These configurations determine the functions supported by the embedded Linux system. In order to understand how the compiler configures the system through configuration files, we need to understand the configuration and compilation process.

Configure the compilation process

Facing the increasingly large Linux kernel source code, it is very difficult to manually compile the kernel. Fortunately, Linux provides an excellent mechanism to simplify the compilation of kernel source code. This mechanism consists of the following aspects.

  • Makefile文件: Its role is to construct a list of source files that need to be compiled according to the configuration, then compile them separately, and link the object codes together to finally form a Linux kernel binary file. Since the Linux kernel source code is organized in a tree structure, the Makefile is also distributed in the directory tree.
  • Kconfig文件: The role is to provide users with a hierarchical set of configuration options. make menuconfigThe command constitutes the user configuration interface through the Kconfig files distributed in each subdirectory.
  • 配置文件(.config): After the user configures, save the configuration information in .configa file.
  • 配置工具: Including the configuration command interpreter (to explain the configuration commands used in the configuration script) and the configuration user interface (provide character-based, Ncurses-based graphical interface and Xwindows graphical interface-based user configuration interface, respectively corresponding to Make config, Make menuconfig and make xconfig).
    The location of this mechanism in the directory is as shown in the figure below:
    insert image description here
    As can be seen from the figure, the main directory contains many subdirectories, including Kbuildand Makefilefiles. Each subdirectory also contains other subdirectories and Kbuild and Makefile files. When the command is executed make menuconfig, the configuration program will search each Kbuild profile from the directory in order from shallow to deep, and generate a configuration menu according to the data in this profile. In this sense, Kbuild is like a configuration database distributed in various directories, through which configuration menus can be generated. In the configuration menu, a file will be generated in the main directory after the configuration is completed according to the needs .config, and the configuration information is saved in this file.
    Then makewhen the command is executed, it will rely on the generated .configfiles to determine which functions will be compiled into the kernel and which functions will not be compiled into the kernel. Then recursively enter each directory, look for the Makefile, and compile the corresponding code.

General configuration

General configuration contains a lot of configuration about the kernel, these configurations include code maturity, version information, module configuration, etc.
General configuration options include some pass configurations, mainly related to processes, such as process communication, process statistics, etc. The details of these configurations are as follows:
insert image description here
insert image description here
版本信息
The above Local version-append to kernel release option is used to configure the version information. The format of the Linux version information is as follows:
insert image description here

module configuration

The module is a very important Linux component. There are many parameters and functions that can be configured. The meaning of the configuration is as follows
insert image description here

Block device layer configuration

The block device layer includes the configuration of the block devices used by the system, mainly including the configuration of the scheduler and the configuration of the hard disk device. The detailed configuration information is as follows:
insert image description here

CPU type and feature configuration

The Linux kernel supports CPUs on almost all architectures. The kernel cannot automatically identify the corresponding CPU type and some related 1 features, and it needs to be configured according to the actual situation when configuring the kernel. Common configurations are as follows:
insert image description here
insert image description here
insert image description here

Power Management Configuration

Power management is a very important module in the operating system. With the enhancement of power-saving and energy-saving capabilities of hardware devices, this module becomes more and more important. In an embedded system, because it is generally powered by a battery, there is a requirement for low power consumption. Therefore, when configuring the kernel for an embedded system, it is necessary to configure a power management module for the corresponding hardware. The commonly used power management configuration options are as follows:
insert image description here
insert image description here
insert image description here

bus configuration

An embedded system may contain many buses, common buses include PCI bus, ISA bus, MCA bus, etc. Different embedded systems contain different buses, and the supported buses need to be set. Refer to the table below:
insert image description here

Network Configuration

The network is the main way for embedded systems to communicate with the outside world. At present, many embedded devices have network functions. In order to enable the kernel to support network functions, some special configurations need to be done to them. Commonly used configuration options refer to the following figure:
insert image description here
insert image description here
insert image description here
insert image description here

Device Driver Configuration

The Linux kernel implements some commonly used drivers, such as mouse, keyboard, and common U disk drivers. These drivers are very numerous, and many drivers are not needed for embedded systems. In practical applications, in order to make the configured kernel efficient and compact, only some main drivers need to be configured. The configuration options of these drivers are as follows:

Generic driver configuration

insert image description here
insert image description here
insert image description here

character device configuration

The character device driver is a common driver. In order to support this driver, the kernel provides some configuration options to set, refer to the following figure
insert image description here
insert image description here

Multimedia device driver configuration

If the embedded system needs multimedia functions, such as music, video and other functions, it is necessary to configure multimedia drivers. Commonly used configurations are as follows:
insert image description here
insert image description here

USB device driver configuration

In an embedded system, some devices are connected through the USB bus, and at this time, a USB device driver is needed. The Linux kernel implements a framework for USB drivers, and driver developers can easily write USB drivers using this framework. The kernel can also configure whether to support USB device drivers. Commonly used configuration options are as follows:
insert image description here
insert image description here

file system configuration

The file system is a major component of the operating system. Linux supports many file systems. For the efficiency and compactness of the kernel, those file systems are configurable. Commonly used configuration options are as follows:
insert image description here
insert image description here
insert image description here

Embedded File System Basics

For embedded systems, in addition to an embedded operating system, an embedded file system is also needed to manage and store data and programs. At present, the embedded Linux operating system supports many kinds of file systems, and the specific file system to be used needs to be 存储介质、访问速度、存储容量selected according to other factors.

Embedded file system

Linux supports a variety of file systems, including ext2、ext3、ext4、vfat、ntfs、iso9600、jffs、roomfs、cramfs和nfsetc. In order to manage various file systems in a unified manner, Linux introduces a virtual file system VFS(Virtual File System)to provide a unified operation interface and application programming interface for various file systems. The structure of the Linux file system is as follows:
insert image description here
The structure of the Linux file system consists of 4 layers, respectively 用户层、内核层、驱动层和硬件层. The user layer provides an operation interface for the user, the kernel layer implements various file systems, the driver layer is the driver of the block device, and the hardware layer is several types of memory used by the embedded system.
In the Linux file system structure, the file system implementation of the kernel layer is necessary. When Linux starts, the first thing that must be mounted is 根文件系统; if the system cannot mount the root file system from the specified device, the system will make an error and exit the startup. After the root file system is mounted successfully, other file systems can be mounted automatically or manually. Therefore, 一个系统种可以同时存在不同的文件系统.
Different file system types have different characteristics, so they have different application scenarios according to the hardware characteristics and system requirements of the storage device. In embedded Linux applications, the main storage device is RAM(DRAM,SDRAM)和ROM(常采用FLASH存储器), and the commonly used file system types based on FLASH storage devices include, jffs2、yaffs、cramfs、roomfs、ramdisk和ramfs/tmpfsetc.

Storage media for embedded systems

The Linux operating system supports a large number of file systems. In the embedded field, which file system to use needs to be determined according to the type of the storage chip. Currently on the market, there are two mainstream storage media for embedded systems NOR和NAND Flash. Intel Corporation first developed NOR Flashmemory in 1988. NOR Flash is characterized by on-chip execution ( XIP, eXecute In Place), so that the application program can run directly in the Flash memory without having to read the code into the system RAM. The transmission rate of NOR is very high, and it is very cost-effective in the small capacity of 1MB~4MB, but the very low writing and erasing speed greatly affects its performance.
In 1989, Toshiba Corporation developed NAND Flashmemory. Compared with NOR Flash, NAND Flash can provide extremely high cell density, can achieve high storage density, and the writing and erasing speed is also very fast. The comparison between the two is as follows:
insert image description here
Generally speaking, NOR FLash is more suitable for storing codes, and its capacity is small, and its price is relatively high. NAND Flash has relatively large capacity and relatively cheap price, which is more suitable for storing data.

JFFS file system

Sweden's Axis Communications is based on the Linux 2.0 kernel and is a file system developed for embedded operating systems JFFS. Its upgraded version JFFS2 is RedHata kernel flash file system developed by the company based on JFFS. It was originally an embedded file system developed for RedHat's embedded product eCos, so JFFS2 can also be used in Linux, uCLinux and other operating systems. JFFS的全称是日志闪存文件系统.
The JFFS file system is mainly used for NOR-type Flash memory, which is based on the MTD driver layer. The characteristics of this file system are: readable and writable, support data compression, log-type file system based on hash table, and provide crash/power-off security protection, provide "write balance" support, etc. The main disadvantage is that when the file system is full or close to full, jffs2the operation speed of the garbage collection relationship is greatly slowed down.
JFFS3 is currently under development. For detailed documentation on the use of the JFFS series file system, refer to the MTD patch package mtd-jffs-HOWTO.txt.
The JFFS file system is not suitable for NAND type Flash memory. The main reason is that the capacity of NAND flash memory is generally large, which causes the space and memory occupied by JFFS to maintain log nodes to increase rapidly. In addition, when the JFFS file system is mounted, it needs to scan the contents of the entire Flash to find out all the log nodes and establish the file structure, which will take a lot of time for large-capacity NAND flash.

YAFFS file system

YAFFS is the first NAND Flashembedded file system specially designed for memory, suitable for large-capacity storage devices; it is General Public Licensereleased under the GPL ( ) agreement, and the source code can be obtained for free on its website. The YAFFS file system has four advantages, namely fast speed, less memory usage, no support for compression and only support for NAND Flash memory.
In the YAFFS file system, files are stored in fixed-size data blocks. The block size can be 512B, 1024B or 2048B. Each file (including directories) consists of a data block header and data. The ECC check code and the organization information of the file system are stored in the data block header, which is used for error detection and bad block processing. The YAFFS file system fully considers the characteristics of NAND Flash, and stores the data block header of each file in the 16B spare space of NAND Flash.
When the file system is mounted, the file system information can be stored in the memory only by scanning the spare space of the memory, and resides in the memory, which not only speeds up the loading speed of the file system, but also improves the file access speed, but Increased memory consumption.
Which file system to choose needs to be determined according to the type of Flash memory. Flash memory types mainly include NOR and NAND Flash. According to the memory type, NOR Flash memory is more suitable for JFFS. NAND Flash memory is more suitable for YAFFS.

Build the root file system

当内核启动后,第一件要做的事情就是到存储设备上找到根文件系统。根文件系统包含了使系统运行的主要程序和数据。

Root Filesystem Overview

The root file system is a file system required by the Linux operating system to run. The root file system is stored in the Flash memory, and the memory is divided into multiple partitions, such as partition 1, partition 2, partition 3, etc., as shown in the following figure:
insert image description here
分区1一般存储Linux内核映象文件,在Linux操作系统中,内核映象文件一般存储在单独的分区中。分区2存放根文件系统,根文件系统中存放着系统启动必须的文件和程序。这些文件和程序包括:提供用户界面的Shell程序、应用程序依赖库、配置文件等.
Ordinary file systems, that is, some data files, are stored on other partitions. The operation of the operating system does not depend on these ordinary files. The first program to run after the kernel starts is initthat it will start the shell program in the root file system to provide the user with a friendly operation interface. In this way, the system can operate correctly according to the needs of users.

Linux root file system directory

The root file system organizes the directory and file structure in a tree structure. After the system is started, the root file system is mounted on the root directory "/". At this time, the root directory contains various directories and files of the root file system, such as /bin、/sbin、/mntetc. The root filesystem should contain directories and files following the FHS standard ( Filesystem Hierarchy Standard,文件系统层次标准). This standard contains the minimum directories and files that should be included in the root file system, as well as the organization principles of these directories and files. Refer to the table below.
insert image description here

BusyBox builds the root file system

To make the Linux operating system run normally, at least a kernel and a root file system are required. In addition to being organized in the FHS standard format, the root file system should also contain some necessary commands. These commands are provided for users to operate the system conveniently.
Generally speaking, there are two ways to build a file system. The first method is to download the corresponding command source code and transplant it to the processor architecture platform. Except for some necessary commands, users can customize some non-essential commands. The second method is to use some open source tools to build the file system. eg BusyBox、TinyLogin和Embuilts. Among them, BusyBox is the most commonly used tool. The following is a brief introduction to this tool.

Overview of BusyBox

BusyBox is a tool for building root filesystems. This tool was originally developed in 1996, before embedded systems became popular. The original purpose of BusyBox was to automatically build a command system that could run on a floppy disk. Because there was no removable large-capacity rewritable storage medium at that time, floppy disks were the most commonly used storage medium. BusyBox can package and compile common Linux commands into a single executable file. By establishing a link, users can use BusyBox like traditional commands.
On a desktop PC, each command in the Linux operating system is a separate binary file. In an embedded system, if each command is a separate file, it will increase the size of the entire root file system and make loading commands slower. This is not good for embedded systems with strict storage requirements. BusyBox solves this problem, it can provide the function of the entire command set in a very small application program, and it is configurable to need those commands and not to those commands.
BusyBox的出现是基于Linux共享库. As with most Linux tools, the different commands can share many things. For example, the command to find files grep和find, although the functions are not exactly the same, both programs will use the function of searching files in the file system, and this part of the code can be the same. BusyBox的聪明之处在于把不同工具的代码,以及公用的代码都集成到一起,从而大大减小了可执行文件的体积。
BusyBox implements many commands, including ar、cat、chgrp、chmod、chown、chroot、cpio、cp、date、df、dd、demesg、du、echo、env、expr、find、grep、gunzip、gzip、halt、id、ifconfig、init、insmod、kill、killall、ln、ls、lsmod、mkdir、mknod、modprobe、more、mount、mv、ping、ps、pwd、reboot、renice、rm、rmdir、rmmod、route、sed、sync、syslogd、tail、tar、telnet、tfp、touch、tracerout、umount、vi、wc、which和whoamietc.

UnzipBusyBox

参考的书籍暂时并没有太大的兴趣去实践这部分
Download the corresponding version of BusyBox . There are 3 steps to install BusyBox, which are decompressing BusyBox, configuring BusyBox and compiling and installing BusyBox.
以BusyBox 1.2.0版为例:
insert image description here

Configuration options for BusyBox

BusyBox contains hundreds of system commands, which are generally not required to be used in embedded systems. You can customize some required commands by configuring BusyBox to reduce the size of the root file system. It is also possible to configure whether the link mode of BusyBox is a dynamic link or a static link. 动态链接需要其他库文件的支持,静态链接将需要的库文件放入最终的应用程序中,不需要其他库文件就能运行. Enter the directory where the BusyBox source code is located, execute make menuconfigthe directory to configure BusyBox, the command is as follows:
insert image description here
enter the configuration interface, select the required settings and commands according to the needs. Here, the following items are selected:
insert image description here
After selecting the desired configuration, exit and save the configuration. As can be seen from the above, the configuration interface of BusyBox is the same as that of the kernel, and the methods are similar. The configuration of BusyBox is often used when building the root file system. Here is a brief introduction to the main configuration options, as follows:
insert image description here
insert image description here

Common configurations of BusyBox

The previous configurations are some basic configurations. According to different needs, the configuration of BusyBox will be different. Here are some common configurations of BusyBox.

  • Tab key auto-completion function, for example, typing in the console makwill automatically complete make. This configuration item isBusyBox Settings --->BusyBox Library Tuning ---> Tab completion
  • Compile BusyBox as a static link, so that BusyBox can also start without other library support. This configuration item is BusyBox Setting ---> Build Options---> Build BusyBox as a static binary(no shared libs).
  • If you use a different cross-compilation tool, you need to specify the path of the compilation tool. This configuration item is BusyBox Setting ---> Build Options ---> Cross Compiler prefix.
  • initThe configuration file should be read in the program /ect/inittab. This configuration item is Init Utilities--->Support reading an inittab file.

Compile and install BusyBox

The compiled BusyBox will run on the ARM processor, so you should modify Makefilethe file and use the cross compilation tool to compile the BusyBox program that can run on the ARM processor. The following two lines in the Makefile need to be modified:
insert image description here
These two lines respectively represent the processor architecture and cross compiler that need to be transplanted, and need to be modified to the following two lines:
insert image description here
Then execute makethe command to compile and install BusyBox.
insert image description here
After compiling and installing, a subdirectory can be found in the BusyBox 1.2.0 directory _install, which is the directory just installed.

Create other directories

After installing BusyBox after step 5, in _installthe subdirectory are just some commands generated by BusyBox, which are stored in bin、sbin目录和usr目录中. bin和sbincontains system commands, usrand contains user commands. Using lsthe command, you can see _installthe status of the directory, as shown below:
insert image description here
The directory generated by BusyBox does not meet the requirements of the root file system, and some additional directories need to be added to it. Use the following command to add these directories to the directory _install. The directory is not Necessary, but this directory is generally added to store multimedia files in embedded development. Then enter the directory just created , create some necessary configuration files, the operation command is as follows:
insert image description here
mediaetc

insert image description here
insert image description here

Modify files in the etc directory

etcThe files in the directory are used to configure the system as a whole. Generally, only 3 files are needed, and the system can work normally; These 3 files are etc/inittab、etc/init.d/rcS和etc/fstab. It etc/inittabis used to create other sub-processes, and its content is:
insert image description here
the file etc/init.d/rcSis a script file, in which commands executed after the system starts can be added. The content of the file is as follows:
insert image description here
the file etc/fstabis used to mount mountthe file system, and the command is to parse the file and mount the file system in it. The content is as follows:
insert image description here

Create files in the dev directory

The dev directory contains some device files, and the applications in the root file system need to use these device files to operate the hardware. Device files can be created dynamically or statically. In order to save resources of the embedded system, statically created methods are generally used. A few simple device files have been created here, which can already meet the requirements of most systems. The operation commands are as follows: For
insert image description here
insert image description here
other device files, after the system starts, you can use cat /proc/devicesthe command to check which devices are registered by the kernel, and then manually one by one Create a device file. In fact, the dev directory used by each Linux operating system is very similar, so you can directly copy it from other root file systems that have been built to try. After the above steps, a file system that can be used is built.

Guess you like

Origin blog.csdn.net/m0_56145255/article/details/130849338