The kernel driver is independent of the size of the CPU, and the kernel provides a set of functions to handle the difference between the size and the end of __ functions

Source: Internet
Author: User

Recently in doing the kernel from the small-end processor (arm) to the big-endian processor (PPC) of the work, now kernel into the console stable work, the basic work has been completed, but the transplant has a lot of experience or need to summarize, Today, the kernel is summed up for processing the byte-order of the size-end.


Before writing the size-end byte sequence thinking, the article link address: http://blog.csdn.NET/skyflying2012/article/details/42065427.

According to the previous understanding, the byte sequence can be considered as the processor subjective concept, just like how people look at things, the processor is big and small end, for memory reading and writing, as long as the data type consistent, there is no byte-order problem.

So I feel that the biggest difference between byte order is the reading and writing of registers. Because the peripheral registers are small ends (based on the kernel code, the following are explained in detail)

According to my previous byte-sequence thinking, there are 2 different scenarios for register reading and writing:

(1) To solve this problem from the hardware, for 32-bit CPU, the 32 data bus is back, but this may be problematic for addressing less than 32 bits of data, and not all modules are back (such as memory), which also involves compiler problems.

(2) from the software to solve this problem, in the underlying read and write register functions, the read/write data to swap.

As a software personnel, I am most concerned about the feasibility of the second option, because of the data in the reading and writing registers to swap, increasing the complexity of the register read and write, the original storage/loading instructions can be completed work, now may need to add some more swap-related instructions, can not guarantee the atomic nature of the register operation. For high-performance, large concurrent systems can cause competition.

Therefore, with the fewest instructions to complete the data swap and r/w registers, in order to ensure the normal stability of Linux system operation.

In the transplant bootloader I am the data to carry on the displacement to complete the swap, because bootloader single process, does not have the race state question.


This was a concern during the kernel migration, but found that kernel has provided a common function in the case of a large and small-end processor operation Register, which is Readl/writel (for example, to operate a 32-bit register).

For driver developers do not need to care about the processor's byte sequence, register operation directly using Readl/writel.

There are many articles on the web that refer to Readl/writel, but do not specifically analyze its implementation.

Today, we mainly analyze how to achieve efficient data swap and register reading and writing in Readl/writel. We take READL as an example, for the Big-endian processor, how to deal with the register data.

Kernel under READL defined below, in include/asm-generic/io.h

[plain] view plain copy #define READL (addr) __le32_to_cpu (__raw_readl (addr)) __RAW_READL is the lowest register read-write function, very simply, from Get the register data directly. To see the implementation of the __LE32_TO_CPU, this function has a different implementation for the byte order, for the small-end processor, in./include/linux/byteorder/little_endian.h, as follows:

[plain] view plain copy #define __LE32_TO_CPU (x) (__force __u32) (__LE32) (x)) is equivalent to doing nothing. For big-endian processors, in./include/linux/byteorder/big_endian.h, the following:

[plain] view plain copy #define __LE32_TO_CPU (x) __swab32 (__force __u32) (__LE32) (x)) the literal meaning can also be seen, __swab32 realize The data is flipped. Wait, we'll analyze the implementation of __SWAB32, the essence of this function.

But before this first consider a problem, for different CPUs, such as Arm MIPS PPC, how to choose to use Little_endian.h or big_endian.h it.

The answer is, for different processor platforms, there are arch/xxx/include/asm/byteorder.h header files, look at arm MIPS PPC Byteorder.h respectively.

Arch/arm/include/asm/byteorder.h

[Plain]  View Plain  copy    *  arch/arm/include/asm/byteorder.h    *     * arm endian-ness.  in little endian mode, the data  bus is connected such    * that byte accesses appear  as:    *  0 = d0...d7, 1 = d8...d15, 2 =  d16...d23, 3 = d24...d31    * and word accesses  (data  or instruction)  appear as:    *  d0...d31    *     * when in big endian mode, byte accesses appear  as:    *  0 = d24...d31, 1 = d16...d23, 2 =  d8...d15, 3 = d0...d7    * and word accesses  (data  or instruction)  appear as:    *  d0...d31    */   #ifndef  __asm_ arm_byteorder_h   #define  __ASM_ARM_BYTEORDER_H      #ifdef  __armeb__    #include  <linux/byteorder/big_endian.h>   #else    #include  < linux/byteorder/little_endian.h>   #endif       #endif   


Arch/mips/include/asm/byteorder.h

[plain] view plain copy

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.