Building an Embedded Linux System

Publisher:逍遥游侠Latest update time:2012-04-06 Source: 电子产品设计Keywords:Embedded Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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.

Keywords:Embedded Reference address:Building an Embedded Linux System

Previous article:Optimizing embedded control in ROADMs
Next article:Design of TV Tracking System Based on TMS320DM642

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号