Easy control of the embedded development process of uClinux

Source: Internet
Author: User

UClinux is currently one of the most popular embedded Linux versions. It has many features and has become part of the Linux 2.6 kernel for the first time with the increase of 32-bit CPU that can run uClinux at a low cost, uClinux will become more popular (1 ). Next we will discuss how developers can control the development process when using uClinux, and what will be different from common Linux.

Figure 1 uClinux runs on Palm

No memory management for Applications

The main difference between uClinux and common Linux systems is that it does not have memory management. In normal Linux, memory management is implemented by using virtual memory (VM. Virtual Memory is generally implemented through memory management units (MMU). In the world of uClinux, we often see the word "nommu.

In the case of virtual memory, all processes run in the same address space, and the virtual memory system processes the ing from virtual memory to physical memory. Therefore, even if the virtual memory seen by the process is continuous, the physical memory occupied by the process may be scattered, and some may even be switched to the hard disk. Because the physical memory can be mapped to any location in the process address space, in this environment, the memory can be added to the running process.

In the absence of virtual memory, each process must be allocated to a fixed memory location. Since a process can run in the upper and lower processes (memory location), it usually cannot dynamically expand the memory. This means that the process running in uClinux cannot dynamically increase the available memory during the running process, which is different from that in traditional Linux.

For uClinux developers, memory allocation is a tricky issue, and because there is no form of memory protection, any application or kernel may damage the system. Even worse, unintentional misoperations won't attract much attention, making it very difficult to trace random and inter-process damages. However, these defects are hardly a problem for uClinux, because the uClinux system generally does not have a hard drive or enough memory, and there is no need for complicated management and exchange.

 

Full memory ing

For kernel developers, the difference between uClinux and general Linux is very small. The only real problem is that uClinux kernel developers cannot use the paging support provided by MMU. For example, tmpfs file systems dependent on virtual memory do not work in uClinux. Similarly, standard executable file formats in normal Linux are not supported by uClinux because they all use the features of virtual memory. UClinux requires a new format -- flat, which is a compressed executable file format that only stores executable code and data, and the relocation information required to load the executable program to the memory.

It is also necessary to understand the implementation of memory ing in the uClinux kernel, because some methods do not work in the uClinux system. After understanding the implementation of memory ing, you can avoid using these methods. UClinux requires that the memory ing can be directed to a file in the file system to ensure that it is sequential and continuous. Otherwise, the file must be allocated with memory in advance, and copy the data to the memory block allocated to it.

Therefore, the usage of Effective Memory ing in uClinux is very clear: first, the only file system that can ensure continuous file storage is the ROM file system (romfs ), therefore, romfs must be used to avoid traditional memory allocation. Secondly, only the read-only memory ing can be shared. That is to say, to avoid traditional memory allocation, the ing must be read-only. For these reasons, developers in uClinux cannot use the "Copy-on-write" feature.

Some modifications are required to port the device driver to the uClinux environment, not because of the differences in the kernel, but because of the differences with the hardware details. For example, in Linux, the SMC Network Driver supports the ISA smccard. The driver is a 16-bit program and is generally allocated with I/O address space below 0x3ff.

However, the driver is required to run in 8-bit, 16-bit, or 32-Bit mode, in addition, in 32-bit I/O addresses, the interrupt number is generally higher than the maximum value of ISA 16. Therefore, the hardware details may be related to some porting work.

 

Proper Memory Allocation

In addition to providing the same memory distributor as normal Linux, uClinux also provides another option. In normal Linux, the default memory distributor uses the "2 power" allocation method, so that you can quickly find the memory area that meets the requirements. Unfortunately, this method in uClinux may produce painful results.

To understand the results of this problem, especially the large memory allocation, we will give an example. Imagine that an application requires a kb memory space for loading. If the "2 power" allocation method is used, 64kb (6 power of 2) memory space must be allocated. The excess 31 KB memory space cannot be used. In uClinux, this waste is unacceptable. To solve this problem, we have designed an optional memory distributor for the uClinux kernel. For different kernel versions, this optional memory distributor is different, generally page_alloc2 and kmalloc2.

Page_alloc2 can solve the waste problem caused by the default allocation method. Although it also uses the "2 power" allocation method, it is distributed by PAGE (4096 bytes per page, that is, 4 kb), if the size of the allocated memory has met the requirements, only the current page is allocated, and other pages are not allocated. In the previous example, if you use this method, you only need to allocate 36 KB (≥33kb, And the whole page), which saves 28 KB of space.

Page_alloc2 also adopts some methods to avoid memory fragmentation. It allocates all the two pages (8 KB) or less memory requirements from the idle memory, and allocates all the large memory requirements from the end of the remaining memory. This prevents temporary allocation of network cache and memory fragments.

Once developers understand the differences in kernel memory allocation, there will be changes in the application.

1. No dynamic stack Problems

In Linux with virtual memory, when an application tries to write off the top unit of the stack, it will be marked as abnormal, and the system will map the new memory to the top of the stack to make the stack grow. In uClinux, this growth does not occur because the stack must be allocated with memory during the compilation phase. When an inexplicable crash or a new transplanted application experiences a strange behavior, developers should first consider the memory size allocated to the stack. By default, uClinux allocates 4 kb of memory space for the stack. developers can use one of the methods mentioned below to increase the stack space.

◆ Before application build

Before building an application, you can add the following two lines of code to the MAKEFILE file:

Fltflags =-S

Export fltflags

◆ After the application is built

After the application is built, run the following command:

Flthdr-s executable

Stacksize is the memory space added to the stack.

2. No dynamic heap Problems

Heap is the memory allocated by malloc and related functions in C language. In Linux with virtual memory, applications may change the process size during running through dynamic heap. This function is implemented by using sbrk () and BRK () system calls at the underlying layer. Sbrk () is to increase the memory space at the end of the process, so calling sbrk () can enable the application to obtain additional memory.

BRK () can set any position as the end of the process space. Therefore, you can call BRK () to reduce or increase the memory space usage. Since uClinux cannot implement BRK () and sbrk (), it uses a global memory pool, that is, the idle memory pool of the kernel. The global memory pool method has some advantages.

First, this method only allocates the memory required for use to the process. Second, when the memory is used up, it will be returned to the global memory pool, and the memory can be allocated using an existing kernel distributor, which can reduce the amount of application code. However, this method is flawed. For example, a runaway process can use up all the available memory of the system.

New users generally encounter memory loss problems. The system displays a large amount of available memory, but applications cannot. This is precisely because of the existence of memory fragments, it is almost impossible for uClinux to fully utilize the memory. This problem exists in the existing solutions. An example is provided to illustrate this problem.

Assume that a system has KB of free memory. To load an application, you need to allocate KB of space. You may think this need must be met. However, you should know that you must have KB of continuous memory space to meet this need. If there is KB free space, but the maximum continuous memory block size is only 80 KB, there is no way to allocate it to this application. There are many reasons for this. As mentioned above, the page_alloc2 kernel distributor has a configuration option that can be used to identify this problem. More information can be obtained in the kernel source code page_alloc2.c file.

 

Some people often ask why we cannot fragment the memory to meet the requirements in the previous example? The reason is that uClinux does not have virtual memory, so it cannot move the memory that the program is using. When virtual memory is used, the memory can be moved as long as you locate it again, so as to sort out memory fragments.

In the absence of virtual memory, because the program often references the memory area allocated to it, the program will crash if the memory of the mobile program is used. In uClinux, there is no solution to this problem. Developers need to pay attention to this problem by themselves. If possible, try to use small memory blocks.

Process and Application Control

1. Process

Another difference between Linux with virtual memory and uClinux is that the latter does not call the fork () system. This requires developers to do some work on the application using fork () during transplantation. In uClinux, the only choice is to use vfork (). Although vfork () and fork () have many similarities, the difference between them has a great impact.

For those unfamiliar with Fork () and vfork (), both system calls allow a process to be split into a parent process and a child process. When a process calls fork (), the child process is a full copy of the parent process, but it does not share anything of the parent process and can be executed independently, just like the parent process. Vfork () is called differently. First, the parent process is suspended until the child process calls exec () or the child process exits.

It can be seen that this system call is used to start a new application. Second, the sub-process runs directly in the stack space of the parent process after vfork () returns, and uses the memory and data of the parent process. This means that the child process may damage the data structure or stack of the parent process, resulting in failure.

To avoid these problems, make sure that once vfork () is called, the sub-process will not return from the current stack framework, in addition, if a child process changes the data structure of the parent process, the exit function cannot be called. The child process must also avoid changing the global data structure or any information in the global variables, because these changes may make the parent process unable to continue.

 

Generally, if the application does not call exec () immediately after fork (), it is necessary to perform a careful check before fork () is replaced with vfork.

2. Applications

Although the flat executable formats of uClinux do not directly affect applications and their execution, they allow options that are not allowed by the elf executable formats in many common Linux systems. For example, the flat executable format brings about two variants of the derivative system-position-independent code (PIC. The full relocation system will relocate the code and data of the application, while the PIC system usually only needs to partially relocate the data.

The most useful feature for embedded developers is that the size of the runtime space remains unchanged (execute-in-place, xip for short ). In this way, the application can run directly from flash or ROM, because only the memory occupied by the application is required. Not all uClinux platforms implement xip, because it requires compiler support and flat executable format PIC format.

Romfs in uClinux is the only file system that supports xip. To implement xip, applications must be continuously loaded to the file system. The flat format also defines the stack size of the application in its header. To add the stack allocated to the application, you only need to modify this part. You can use the flthdr command to implement it. The format is as follows:

Flthdr-s flat-executable

The flat format also allows compression of the entire executable file to minimize the occupied Rom space. It also plays a secondary role in making the application fully loaded into a continuous ram block. To save Rom space and use xip, you can also select data-segment-only compression.

Generate a fully compressed executable file:

Flthdr-Z flat-executable

Only the compressed data segment is generated:

Flthdr-D flat-executable

Be especially careful when sharing Libraries

The shared libraries in uClinux are different. Currently, the available solutions need to modify the compiler, and developers need to be especially careful. In fact, the UC-libc and uclibc libraries are provided in the current uClinux release. The best way is to use these two libraries as examples to create your own shared libraries.

 

In addition, the shared library in uClinux must be an executable file in flat format, and xip must be implemented to truly share the file. If xip is not implemented, the shared library will create a copy for each application that uses it. It is better to use a static link application.

Summary

UClinux tends to be a more in-depth embedded system, which requires less memory and can run directly on ROM. If the first development in uClinux encounters a series of situations, such as no hardware driver, strict resource restrictions, and no memory protection, the best way to start is to use the uClinux simulator (see figure 2 ).

Figure 2 uClinux simulator xcopilot

Emphasizing the above issues will help developers prepare in advance and avoid common pitfalls and misunderstandings in uClinux.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.