Linux kernel Analysis and programming--Data type and List (original) __HTML5

Source: Internet
Author: User
Tags prev

Chapter One data types and lists

1.1 Space occupied by data type
Use the-wall-wstict-prototypes option when compiling the kernel to prevent many errors from occurring
Basic data types used by the kernel
int standard C language integer type
U32 32-bit integer type
pid_t a specific kernel object PID type

The Linux user space based on the SPARC64 platform can run 32 code, the user space pointer is 32-bit wide, but the kernel is 64-bit
The address in the kernel is the unsigned long type with the same pointer size as the long type

Use a prefix type to expose variables to user space. such as _ _u8 type. For example, a driver uses the IOCTL function to exchange data with a program running in user space, and should use _ _u32 to declare a 32-bit data type
Sometimes the kernel uses the type of C language, such as unsigned int, which is typically used for data items that are sized independently of the architecture.
Many data types in the kernel are declared by TypeDef, which facilitates porting. If you use the pid_t type as the type of the process marker (PID) instead of the int type, pid_t masks the difference between the actual data types on different platforms.
If the appropriate type is not easily selected, the cast is coerced to the most probable type (long or unsigned long).

1.2 Time interval
100 jiffy cannot be used for 1s intervals. Because different platforms may be set differently, you should use Hz (number of timer interrupts per second) to measure

Page size
The size of the memory page is page_size bytes, not 4KB. On different platforms, the page size range can be 4KB to 64kb.page_shift by moving the address right page_shit to get a page of the page where the address is located
Number. For user space, you can use the Geipagesize function to get the size of the page.
Using the Get_free_pages function to request 16KB of free space (2 of 14), first converts 16KB to 2 of the free number of X-times. Define Page_shift as 12 under x85
int order = (14-page_shift > 0)? 14-page_shift:0;
BUF = Get_free_pages (Gfp_kernel,order);

BYTE storage Order
There are two kinds of byte storage order, and low byte priority is when storing multibyte values, the lower byte is in front, and the high byte is in the back. The high byte priority is the opposite. Most modern processors work in Big-endian mode. Linux Approved
A set of macros that are used to convert between processor byte-order data and special byte data. Macros in Linux/byteorder/big_endian.h
U32 _ _cpu_to _le32 (u32); To convert a byte-order conversion of a CPU's value into a. Unsigned value for a small end byte
and _BE64_TO_CPU.

Data alignment
Reads a 4-byte value stored in an address that is not a multiple of 4 bytes, which has a problem with the data, and accesses the misaligned data with the following macro
#Include <asm/unaligned.h>
Get_unaligned (PTR);
Put_unaligned (VAL,PTR);
These macros are independent of the type and are valid for each data item.

1.3 Kernel Universal Link list
A list_head type simple structure is defined in the <Linux/list.h> file
struct list_head{
struct List_head *next,*prev;
};

The common use of a common list is to string a data structure itself into a list, or link some linked list with a data structure, both of which are essentially composed of the structure List_head chain list.

String a data structure itself into a linked list
(1) Join List_head structure member
struct example_struct{
struct List_head list;
int priority;
..//Other Members
}
Using the list member to example_struct the structure of the chain into a list, is the List_head "Bear" load is the EXAMPLE_STRUCT structure.

(2) Create List_head structure
You must request a chain header and use the Init_list_head macro to initialize the linked header before using it. Two ways to use
Method 1:
struct List_head example_list;
Init_list_head (&example_list);
Method 2:
List_head (example_list):

Where these two macros are defined in Include/linux/list.h are as follows:
#define LIST_HEAD (name)/
struct List_head name = List_head_init (name)

#define Init_list_head (PTR) do{
(PTR)->next = (PTR); (PRT)->prev = (PTR);
}while (0)

(3) The EXAMPLE_STRUCT structure pointer corresponding to the node is obtained from the Example_list list, in which PTR is a pointer in the Example_list list, such as PTR = Example_list->next
struct Example_struct *node = List_entury (ptr,struct example_struct,list);

The macro definition in the line above list_entry maps a LIST_HEAD structure pointer back to a pointer that only wants to structure example_struct, that is, the List_head host structure, the macro definition (in include/linux/list.h)
#define LIST_ENTRY (Ptr,type,member)/
Container_of (Ptr,type,member)
To get the structure of a node in a linked list:
PTR is a struct list_head structure element pointer in a linked list
Type is a user-defined structure, containing struct list_head struct members
struct List_head struct member name of user-defined structure

There is contain_of definition in include/linux/kernel.h, parameter meaning and list_entry, container_of get the container structure of list, that is, the institution containing list member Type.contain_ The definition of IS as follows:
#define CONTAINER_OF (Ptr,type,member) ({

Converts element ptr in a linked list to the type of member Menber in struct type
Const typeof ((type *) 0)->member) *_mptr = (PTR);

_mptr minus member offset address is exactly the type structure address
(Type *) ((char *) _mptr-offsetof (type,member));
})

There is a definition of macro offsetof in Include/linux/stddef.h, listed below
#define OFFSETOF (Type,member) (size_t) & ((TYPE *) 0)->member)
Where the & ((struct example_struct *) 0)->list represents the address of its member list when the structure example_struct exactly on address 0, that is, the member displacement

(4) Traverse list
The following uses the List_entry macro to traverse the list pointer, then map the pointer back to the corresponding structure example_struct from the list pointer, and then manipulate its member priority. Function Example_add_entyr function is to add to the list
New struct Members
void Exaple_add_entry (struct example_struct *new) {
struct List_head *ptr;
struct Example_struct *entry;
Traversing a linked list
for (ptr = exmple_list.next;ptr!=example_list;ptr = ptr->next) {
mapping back to the corresponding structure example_struct pointer
Entry = List_entry (Ptr,struct todo_struct,list);
if (entry->priority<new->priority) {
List_add_tail (&AMP;NEW-&GT;LIST,PTR);
Return
}
}
List_add_tail (&new->list,&exmple_struct)
}

The include/linux/list.h also defines the following functions from the action list
List_add (struct list_head *new, struct list_head); This function adds a new element after the header of the list, and if you add elements to the head of the list, it can be used to build the stack.
It also requires that the head does not have to be the first item in the list, and if it passes a list_head structure that happens to be somewhere in the middle of the list, the new entry immediately follows it, because the Liinux list is circular, and the linked table header
Usually there is no essential difference from other entrances

List_add_tail (struct list_head *new, struct list_head); add a new element to the front of the given chain, that is, at the end of the list, and you can use *head to create a "first out" queue

List_del (stuct list_head *entry) deletes the given entry from the list
List_empty (struct list_head *head *head); Returns a value other than 0 if the given list is empty
List_splice (struct list_head *list, struct list_head);
The definition of 1.3.1 list and hlist hash list structure in include/linux/list.h

Hash table-specific hlist data structure is a single pointer to the double loop chain table, Hlist table header only a pointer to the first node, but not just the end of the pointer, so that in Russia may be a huge hash table stored in the table can be reduced by half
of space consumption.
Pprev because Hlist is not a complete circular list, it has to be used. In the list, the header and node are the same data structure, directly using the prev is no problem; in Hlist, the header has no prev, no next, only one first in order to unify the
Modify the first pointer of the header, that is, the first pointer of the header must modify the node that points to the new insert only, and hlist designed the Pprev pprec.hlist node Pprev no longer refers to a pointer to a node forward, but to a node forward (possibly
Is the next (for header) pointer (struct List_head **pprev) in the header, so that actions inserted in the header can be accessed and modified by consistent "(*node->pprev)" to the previous node's next (first) pointer

1.3.2 RCU (read-copy Update) improves synchronization performance through delayed write operations
RCU is often used to protect lists and arrays with a majority of read operations. The difference between the operation function of a linked list with RCU and that of a common list is to add _rcu after the function name, such as the LIST_FOR_EACH_RCU function
The function List_for_each_rcu function is to traverse a RCU-protected, linked list. The parameter pos represents the &AMP;STRUCT list_head structure used to make the list position technique, and the parameter head represents the linked table header, as long as the traversal is Rcu_read_lock ( ) protection
It is safe to use a function such as LIST_ADD_RCU () to access a linked list at the same time

Assembly format for 1.4at&t
With lowercase letters, the register prefix%, the source operand before, the target operand, the last letter of the opcode indicates the bit width, such as "B" for 8 bits, "W" for 16 bits, and "L" for 32 bits. Add $ before direct operand
Plus $ is a representation of an address reference, not a reference to a value. For local variables, you can use the stack pointer to reference the
In general, underlining refers to global variables

Time delay in the 1.5 kernel
The operating system determines the time interval through a clock interrupt, and the clock interrupt is generated periodically by the system timer hardware, which is set by the kernel pattern Hz, which is an architecture-related constant. in file <Linux/param.h>
The current Linux version for most platform-defined Hz is 100, and on some platforms it is 1024. Try to count the platform-independent Hz values in the kernel code.

When the clock breaks, the value of the variable jiffies increases and jiffies is initialized to 0 at system startup, so the Jiffes value is the number of clocks that have arrived since the operating system started, jiffes the header file <Linux/sched.h> is defined as the data
The type is a unsigned long volatile variable, which returns to 0 when the jiffes reaches its maximum value.

Most CPUs have a high-precision counter that can read or change its value by counting registers. such as the x86 register TSC (timestamp counter, timestamp counter) is a 64-bit register that records the number of CPU clock cycles. Contains the
Header file <asm.msr.h>

Many drivers need to defer the characters to later processing, but do not want to use the interruption, Linux provides three ways to do this: task queue, Tasklet and kernel timer.

Related Article

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.