- Basic introduction
- Because of the Linux multi-platform feature, no matter which important driving force should be portable
- The core issue associated with kernel code should be access at the same time as the known length of the data item. Capabilities and use of different processors
- The data types used by the kernel are divided into three main categories
- Similar to the standard C language type int
- Similar to u32 this has a definite size type
- Types like pid_t that are used for specific kernel objects
- This chapter will discuss under what circumstances these three types are used and how to use
- Use standard C language types
- When we need a "two-byte shim" or "something in a four-byte string". We cannot use standard types due to different architectures. The size of the normal C language data type is not the same
- The normal memory address in the kernel is usually unsigned long. On all platforms currently supported by Linux, pointers and long shaping are always the same size
- The C99 standard defines intptr_t and uintptr_t types, which are shaping variables that can hold pointer values
- Allocate a determined amount of space for a data item
- <asm/types.h>
- <linux/types.h>
- U8, S8
- U16, S16
- U32, S32
- U64, S64
- Suppose a user-space program needs to use these types, which can be prefixed by a two underscore in front of the name
- __u8
- __u32
- Systems that use the new compiler will support C99 standard types, such as uint8_t and uint32_t
- interface-specific types
- The most frequently used data types in the kernel are declared by their own typedef. This will prevent any portability issues from occurring.
- "Interface-specific (interface-specific)" refers to a data type defined by a library to provide an interface for a particular data structure
- The complete _t type is defined in <linux/types.h>
- The main problem with _t data items is that it's not easy to choose the right PRINTK or printf output format when we need to print them.
- Other issues related to transplants
- A common principle is to avoid the use of explicit constant values
- Time interval
- When using jiffies to calculate the time interval, you should use Hz to measure
- Page size
- The size of the memory page is page_size bytes
- Page_shift
- <asm/page.h>
- GetPageSize Library functions
- Get_order function
- byte order
- <asm/byteorder.h>
- __big_endian
- __little_endian
- U32 cpu_to_le32 (U32);
- U32 le32_to_cpu (U32);
- Be64_to_cpu
- Le16_to_cpus
- cpu_to_le32p
- Data alignment
- <asm/unaligned.h>
- Get_unaligned (PTR);
- Put_unaligned (Val, PTR);
- Pointers and error values
- Many kernel interfaces return an error message by encoding the error value into a pointer value
- <linux/err.h>
- void *err_ptr (long error);
- Long Is_err (const void *ptr);
- Long Ptr_err (const void *ptr);
- Linked list
- <linux/list.h>
- struct List_head
- struct List_head *next, *prev;
- Init_list_head (&list);
- List_head (list);
- List_add (struct list_head *new, struct list_head *head);
- List_add_tail (struct list_head *new, struct list_head *head);
- List_del (struct list_head *entry);
- List_del_init (struct list_head *entry);
- List_move (struct list_head *entry, struct list_head *head);
- List_move_tail (struct list_head *entry, struct list_head *head);
- List_empty (struct list_head *head);
- List_splice (struct list_head *list, struct list_head *head);
- List_entry (struct List_head *ptr, type_of_struct, field_name);
- List_for_each (struct list_head *cursor, struct list_head *list)
- List_for_each_prev (struct list_head *cursor, struct list_head *list)
- List_for_each_safe (struct list_head *cursor, struct list_head *next, struct list_head *list)
- List_for_each_entry (type *cursor, struct List_head *list, member)
- List_for_each_entry_safe (Type *cursor, type *next, struct List_head *list, member)
Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.
"Linux Device Drivers" The 11th Chapter core data type--note