Introduction:
At present, the application of embedded systems is becoming more and more extensive. A general PC has 5 to 10 embedded microprocessors in its external devices, such as keyboards, floppy drives, hard disks, monitors, printers, scanners, USB interfaces, etc., which are all controlled by embedded processors. In the manufacturing industry, process control, communication television, instrumentation, automobiles and ships, aerospace, and consumer products are all application fields of embedded systems. At present, the main embedded systems are: Windows CE, VxWorks, QNX, etc. They all have good real-time performance, system reliability, randomness of task processing, etc. However, their prices are generally high, and many developers cannot afford it. Therefore, the Linux operating system has become the first choice for embedded operating systems for the following reasons:
Before compiling the kernel, you must first clarify which drivers and modules are needed, and then select only the required drivers and modules. For example, if the system does not need network support, you can remove the network module. The kernel is generally stored in a compressed manner and will be automatically decompressed when the system starts. The kernel is always resident in the memory. When the application needs to be called, the required program is transferred from the disk to the memory for operation.
The commonly used commands for building the kernel include:
◆ make config: kernel configuration, call ./scripts/Configure to configure according to arch/i386/config.in.
◆ make dep: search for dependencies.
◆ make clean: clear all target files, module files, and some temporary files generated by the previous kernel construction.
◆ make: kernel construction, many target files will be generated in each directory through the Makefile files in each directory. If there is no error in the kernel, the file vmlinux will be generated, which is the built kernel.
◆ make zImage: based on make, a compressed kernel image file ./arch/$(ARCH)/boot/zImage is generated, and temporary files are generated in the ./arch/$(ARCH)/boot/compresed/ directory. ◆ make bzImage: based on make, a kernel image
file ./arch/$(ARCH)/boot/bzImage with a higher compression ratio is generated, and temporary files
are generated in the ./arch/$(ARCH)/boot/compresed/ directory.
◆ make modules: compile module files. All modules configured during make config will be compiled at this time to form module target files, and these target files are stored in the modules directory.
◆ make modules_install: place the module target files compiled above in the directory ./lib/modules/$KERNEL_VERSION /. The above compiled kernel is implemented without changing the source code. If you feel that the functions provided by the source code cannot meet the requirements in some aspects, you must modify the source code. The source code mainly includes the following key parts: the task_struct structure related to process management, which includes almost all file contents related to the process, as well as task queues, clock management and interrupt management, various inter-process communication mechanisms, the implementation of various memory allocation functions in memory management, and the virtual file system.
System startup
The boot program mainly includes the following three files: bootsect.s, head.s and setup.s. Although these three files are all assembler programs, they do use two syntax formats. bootsect.s and setup.s use assembly language syntax similar to Intel, and require the use of Intel 8086 assembler and connector as86 and ld86. head.s uses GUN assembly format and runs in protected mode. It needs to be compiled with GUN as. This is an assembly language format with AT&T syntax. Bootsect.s code is a disk boot block program, which resides in the first sector of the disk. After the PC is powered on and the ROM-BIOS self-test is performed, the boot sector is loaded by the BIOS to memory 0x7C00, and then it moves itself to memory 0x90000. The main function of this program is to first load the setup module (compiled by setup.s) from the disk to the memory immediately after bootsect (0x90200), then use BIOS interrupt 0x13 to get the parameters of the current boot disk in the disk parameter table, and then display the string "Loading system..." on the screen. Then load the system module from the disk to the memory starting at 0x10000. Then determine the device number of the root file system.
The main function of the Setup program is to use the ROM-BIOS interrupt to read the machine system data and save this data to the location starting at 0x90000 (covering the location of the bootsect program). Then the setup program moves the system module from 0x10000 to the absolute memory address 0x0000, and then loads the interrupt descriptor table register (idtr) and the global descriptor table register (gdtr). Turn on the A20 address line, reset the two interrupt control chips 8259A, and reset the hardware interrupt number to 0x20-0x2f. Finally, the CPU control register CR0 (also known as the machine status word) is set to enter the 32-bit protected mode and jump to the head.s program at the front of the system module to continue running. After being compiled, the head.s program will be connected to the front beginning of the system module, that is, the head program. From here on, the kernel runs completely in protected mode. This program actually starts at the absolute address 0 of the memory. The function of this program is relatively simple. First, it loads each data segment register and resets the interrupt descriptor table idt, a total of 256 items. Then reset the interrupt descriptor table gdt, then detect whether the A20 address line is turned on, then detect whether the PC contains a math coprocessor chip, then set the paging processing mechanism for managing memory, and finally use the return instruction to pop the entry address of the /init/main.c program pre-placed in the stack to run the main() kernel initialization program. [page]
Device driver
Device drivers play a special role in the Linux kernel. They are independent "black boxes" that make a specific hardware respond to a well-defined internal programming interface while completely hiding the working details of the device. User operations are performed through a set of standardized calls that are independent of a specific driver. The functionality provided by device drivers is to transfer data with peripherals. There are three types of devices: character devices, block devices, and network interfaces. Each module usually implements one of these types, and accordingly, modules can be divided into three types: char module, block module, and network module. However, this classification is not very strict, and programmers can build a large module in which different types of device drivers are implemented. The three types of devices are as follows:
Character module
Character devices are devices that can be accessed as byte streams (such as files), and this feature is implemented by character device drivers. Character device drivers usually need to implement at least the open, close, read, and write system calls. Character terminals (dev/console) and serial ports (/dev/ttySO and device types) are two examples of character devices that can be well represented by stream abstractions.
Block devices Like character devices, block devices are accessed through file system nodes in the /dev directory. Block devices (such as disks) can accommodate file systems. In most Unix systems, block devices consist of an integer number of blocks, each containing 1KB or a power of 2 bytes of data. Linux allows applications to read and write block devices like character devices, and can transfer any number of bytes of data at a time. Therefore, the difference between block devices and character devices lies only in the way the kernel manages data internally, that is, the interface between the kernel and the driver is different. The interface of the block device must support mounting the file system.
Network interface
Any network transaction must go through a network interface, that is, a device that can exchange data with other hosts. Usually the interface is a hardware device, but it can also be a pure software device, such as a loopback interface. The network interface is driven by the network subsystem in the kernel, which is responsible for sending and receiving data packets. It must understand how each transaction is mapped to the actual transmitted data packets. Although Telnet and FTP connections are stream-oriented and use the same device, the device only sees data packets, not independent streams.
In Linux, in addition to directly modifying the source code of the system kernel and adding device drivers to the kernel, device drivers can also be used as loadable modules, which can be dynamically loaded and unloaded by the system administrator to make them part of the kernel. Linux modules can be written in C language and compiled into target files (without linking, as *.o files) by gcc. To do this, you need to add the -c parameter to the gcc command line. Since gcc only allows one input file when not linking, all parts of a module must be implemented in one file. The compiled module *.o is placed in /lib/modules/xxxx/misc (xxxx represents the kernel version), and then use depmod -a to make this module a loadable module. The module is loaded with the insmod command and unloaded with the rmmod command, and the status of all loaded modules can be viewed with the lsmod command. When writing a module, two functions must be provided, one is init_module(void), which is automatically called by insmod when loading and is responsible for initializing the device driver. Init_module returns 0 to indicate successful initialization and a negative number to indicate failure. The other function is void cleanup_module(void), which is called when the module is unloaded and is responsible for clearing the device driver. After successfully registering the device driver with the system (after successfully calling register_chrdev), you can use the mknod command to map the device into a special file. When other programs use this device, they only need to operate on this special file.
Conclusion
This paper mainly discusses how to construct an embedded Linux system. Designing and implementing a complete and compact embedded Linux system is a very complex process. Since embedded Linux is cut from standard Linux, it is necessary to have a deep understanding of the Linux kernel. A small embedded Linux system constructed in this paper has been successfully used in S3C2410. The problem is that the built kernel is not small enough, which may be caused by the existence of some unnecessary hardware drivers and the unsatisfactory cutting of the library. Future work will focus on the cutting of peripheral modules and libraries, as well as the development of drivers for some specific hardware. References: 1 Wei Yongming, Luo Gang, Jiang Jun. Linux Device Drivers (Second Edition). China Electric Power Press, 2002 2 Zhao Jiong. Linux Kernel Complete Annotation, 2004 3 Feng Yonghong, Zhu Shanjun. Analysis of Cutting Linux Technology. Proceedings of the 2001 International Academic Exchange Conference on Embedded Systems and Single-Chip Microcomputers, 2001 This paper was received on August 30, 2004. Liu Xinchao: Postgraduate, research direction is microcomputer control.
Previous article:Optimizing embedded control in ROADMs
Next article:Design of TV Tracking System Based on TMS320DM642
- Popular Resources
- Popular amplifiers
- Semantic Segmentation for Autonomous Driving: Model Evaluation, Dataset Generation, Viewpoint Comparison, and Real-time Performance
- Machine Learning and Embedded Computing in Advanced Driver Assistance Systems (ADAS)
- Intelligent program synthesis framework and key scientific problems for embedded software
- arm_embedded_machine_learning_design_dummies_guide
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
- Virtual static random access memory in mobile and portable applications
- Fatal Error[Pe1696]: cannot open source file "stm8s.h"
- 【NXP Rapid IoT Review】+8. Brief summary
- Does anyone have the engineering source code that can run on Chuanglong 6678 nor-writer?
- Why do we write =0 when assigning a variable a value of 0, but write =0xffffffffu when assigning it a value of 0xffffffff?
- Learning PCB
- TMDSLCDK138 board about PRU part program
- NI Taobao brand store, Double Eleven hot items return
- About the role of capacitance and inductance in LoRa radio frequency circuit
- Two-color 2835 painting 10 series 14 parallel