Kernel Source Study Preparatory knowledge

Source: Internet
Author: User

Interspersed with details in code reading
Data type:
Type definition:
The kernel uses typedef to define various data types to avoid dependency on architecture-related features, such as the length of the standard data types on each processor may be different. The type names defined, such as sector_t, pid_t, and so on, are defined by the kernel in architecture-specific code to ensure that the values of the relevant types fall within the appropriate range, so it is generally not necessary to know the specific definitions of these types. However, if a variable type is a typedef, it cannot be accessed directly, but through auxiliary functions.
At some point, you must use variables that define the exact number of bits, such as when using USB, which defines a number of integer data types for this kernel, not only whether it is a signed or unsigned number, but also specifies the exact number of digits (__s8,__u8, __U16,__S16, __U32,__S32, __ U64,__S64)

BYTE order:
CPU_TO_LE64 converts 64-bit data to a small-order format, which is exactly the opposite of what LE64_TO_CPU does. (If the architecture uses small-endian, these two routines are empty operations)

PER-CPU variables:
The special things that ordinary user space programming does not involve are PER-CPU variables, which are declared by DEFINE_PER_CPU (Name,type), where name is the variable name, type is its data type (for example int[3], struct hash, etc.). On a single processor, there is no difference between a regular variable declaration, and on an SMP system with several CPUs, one instance of the variable is not created for each CPU separately. An instance for a particular CPU can be obtained with GET_CPU (NAME,CPU), where smp_processor_id () can return the currently active processor ID for CPU parameters.

To access the user space:
Multiple pointers in the source code are marked as __user, which is unknown to the user-space program. The kernel uses this notation to identify pointers to areas in the user's address space and cannot easily access the areas to which these pointers are directed without further precautions. The kernel needs to make sure that the page frame that the pointer points to actually exists in physical memory.


Architecture-related knowledge:
To align:
In some parts of the kernel, you may need to access non-aligned data types. The individual system structure must define two macros (in <asm-arch/unaligned.h>) for this purpose.
Get_unaligend (PTR) is a pointer to a non-aligned memory location, and the dereference operation
Put_unaligned (VAL,PTR) writes the value Val to a non-aligned (and thus not directly accessible) memory location specified by PTR.

Page:
The following macros must be defined in <asm-arch/page.h>
PAGE_SHIFT Specifies the base 2 logarithm of the page length
PAGE_SIZE Specifies the length of the memory page, in bytes
Page_align (addr) can align any address to page boundaries
The two standard operations on a page are usually performed through an optimized assembly instruction:
Clear_page (start) deletes a page starting from start and populates it with 0 bytes
Copy_page (To,from) copies the page data from at

The Page_offset macro specifies where the physical page frames are mapped in the virtual address space, which implicitly defines the length of the user's address space in most architectures, or divides the entire address space into the kernel address space and the user address space. With the exception, SPARC uses two separate address spaces for the kernel and user space, and AMD64 has an addressable void in the middle of the virtual address space. You must therefore use the Task_size constants defined in Asm-arch/process.h to determine the length of the user space

System calls:
Standard files <asm-arch/unistd.h> The following two aspects tasks related to system calls
It defines a preprocessor constant that associates descriptors for all system calls to symbolic constants. The names of these constants, such as __nr_chdir and __nr_send, may be different for each architecture.
It defines the functions that are used to invoke the system inside the kernel, and typically uses a preprocessing mechanism for this, along with an inline assembly for automatic code generation

String processing:
All architectures define the various string operations of their own in <asm-arch/string.h>
int strcmp (const char *cs,const char *ct)-per-character comparison two strings
int strncmp (const char *cs,const char *ct,size_t count) is similar to strcmp, but only count characters are compared
int strnicmp (const char *s1,const char *s2,size_t len) is similar to strncmp, but does not take case
Char *strcpy (char *dest,const char *src)
Char *strncpy (char *dest,const char *src,size_t count) is similar to strcpy, but the maximum length is no more than count characters
size_t *strlcpy (similar to strncpy, if the number of characters in the source string is extra size, the target string is still ending with 0)/* What kind of pit daddy function AH/
Char *strcat (char *dest,const char *src)
Char *strncat (char *dest,const char *src,size_t count)
size_t Strlcat (char *dest,const char *src,size_t count) is similar to strncat, but the result string length does not exceed
Char *strchr (const char *s,int c) finds the first position in the string s where the character C appears
Char *strrchr (const char *s,int c) finds the last position in the string s where the character C appears
....
....
....
All of these functions are used to replace a function of the same name as the C standard library used in user space.
For each string operation defined by the architecture itself in an optimized form, the corresponding __have_arch_operation macro must be defined, and __have_arch_memcpy must be set for MEMCPY. All functions that the architecture code fails to implement are replaced with the architecture-independent standard operations implemented in LIB/STRING.C, based on whether or not the __have_arch_operation is defined.

The thread represents:
The structure used to save the register is defined in the following file:
The PT_REGS structure for saving all registers is defined in <asm-arch/ptrace.h>, where the PT_REGS structure instance that holds each register value is placed on the kernel stack when the process is switched from user state to kernel mentality because of system calls, interrupts, or any other binary. The file also defines the order of the registers on the stack through the preprocessor constants, which is necessary when tracking the debug process to read the register value from the stack.
<asm-arch/processor.h> contains the THREAD_STRUCT structure, which is used to describe all other registers and all other process state information. This structure is usually further divided into a number of processor-specific parts
The THREAD_INFO structure is defined in <asm-arch/thread.h>, which contains all the TASK_STRUCT members that must be accessed for the implementation to enter and exit the kernel state and assemble the code.


Bit operation:
Kernel architecture-specific bit operations must define functions in <asm-arch/bitops.h>
void set_bit (int nr,volatile unsigned long *addr) places the position of the NR bit position, counting from addr onwards.
int test_bit (int nr,const volatile unsigned long *addr) checks whether the specified bit bit is set
void clear_bit (int nr,volatile unsigned long *addr) please place the bit on the NR
void change_bit (int nr,volatile unsigned long *addr) reverse the bit at position NR
int test_and_set_bit (int nr,volatile unsigned long *addr) places a bit position and returns the previous value of that bit
int test_and_clear_bit (int nr,volatile unsigned long *addr) clears a bit and returns the previous value of that bit
int test_and_change_bit (int nr,volatile unsigned long*addr) takes a bit counter and returns the previous value of that bit
The above functions are atomic, and non-atomic prefixes are underlined (such as __set_bit).

Conversion between byte-order:
The kernel provides <byteorder/little_endian.h> and <byteorder/big_endian.h> header files for the current processor version to be included in the <asm-arch/byteorder.h > In
The default function definition is in <byteorder/swab.h>, but can be overridden by a particular processor-specific implementation. __arch__swab16, __arch__swab32, and __arch__swab64 Exchange bytes between various representations, thus converting big-endian to small-order, and vice-versa, __arch__swab16p, __arch__swab32p, __ ARCH__SWAB64P completes the same operation, applies to pointer variables, swab represents swap bytes

Page table:
For memory management, the kernel provides a memory model that abstracts out the different points of each architecture, and the various porting editions must provide functions to manipulate page tables and page table entries. These declarations are defined in <asm-arch/pgtable.h>

Checksum calculation:
If possible, each architecture should use artificially optimized assembly code to calculate checksums. The related code is declared in <asm-arch/checksum.h>.
Two of these functions are the most important:
Unsigned short ip_fast_csum calculates the necessary checksum based on the IP header and header length
Csum_partial calculates the checksum for each packet based on the individual shards received sequentially

Context Switch:
After the scheduler decides to notify the current process to discard the CPU so that another process runs, the hardware-related parts of the context switch are made. For this reason, all architectures must provide the SWITCH_TO function or the corresponding macro, which is defined in <asm-arch/system.h> as follows:
void switch-to (struct task_struct *prev, struct task_struct *next, struct task_struct *last)
Prev Saves the current process, next points to the next process to switch, and last is used to get information about the process that was just running after switching back to Prev, which is useful throughout the kernel.


To find the current process:
The current macro is used to locate a pointer to the task_struct of the currently running process. Each architecture must declare the macro in <asm-arch/current.h>, which is stored in a separate processor register and can use current direct or indirect queries. Depending on the architecture, some architectures use it to store a pointer to the current TASK_STRUCT instance, but most use it to hold a pointer to the currently valid Thread_info instance. In the latter case, Thread_info contains a pointer to the task_struct,current of the related process that can be implemented around a bend.

This article is from the "No Front" blog, please be sure to keep this source http://qianyang.blog.51cto.com/7130735/1620565

Kernel Source Study Preparatory knowledge

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.