"Linux Kernel Design and Implementation" reading notes-starting from the kernel

Kernel download

The kernel source code is generally installed in the /usr/src/linx directory.

The Ubuntu example here is not installed by default, but it can be downloaded through the command:

apt install linux-source

Download linux-2.6.34.1.tar.bz2, unzip:

tar xvjf linux-2.6.34.1.tar.bz2

After decompression:

The root directory of the kernel source tree is described as follows:

 

Kernel compilation

It needs to be configured before compiling the kernel.

Configuration items exist in the form of CONFIG_XXX .

Choose one of two configuration items: yes no

Choose one of three configuration items: yes no module

Module means to be compiled as a module and exist independently, rather than included in the kernel binary.

The configuration can also be a string or an integer .

In order to simplify the configuration, there are some commands for processing:

make config

The results obtained are as follows:

Need to manually confirm one by one.

make menuconfig

The results obtained are as follows:

In order to use this graphical interface, ncurse needs to be installed:

sudo apt install libncurses5-dev

There are other graphical interfaces available:

make gconfig

Don't pay attention to this temporarily.

You can also create a configuration for the current architecture based on the default configuration:

make defconfig

The results obtained are as follows:

A default configuration of x86_64 is created here.

Finally, a .config file is generated, which contains all the configurations. The following is part of the content in the .config:

#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.34.1
# Tue Apr 21 00:24:46 2020
#
CONFIG_64BIT=y
# CONFIG_X86_32 is not set
CONFIG_X86_64=y
CONFIG_X86=y
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_BUG=y

You can directly modify the .config file, and run the following commands after the modification to verify and update the configuration.

make oldconfig

You can use make directly after compiling .

 

Kernel installation

The installation of the kernel itself needs to be based on the platform, such as x86, and needs to be placed in the following directory:

Then update GRUB, and then you can use this kernel.

The installation of the module is also relatively simple, it needs to be installed under root:

make modules_install

For the actual use of the Ubuntu kernel, you can refer to

https://blog.csdn.net/weixin_38180645/article/details/82856407

Because of the risk of system abnormality, no actual operation is performed here.

But you can also use a virtual machine, so the risk is relatively low, you can refer to

https://blog.csdn.net/jiangwei0512/article/details/52563639

This is an example of using QEMU.

 

Features of kernel development

When the kernel is compiled, neither the C library nor the standard C header files can be accessed.

a. Most of the commonly used C library functions are implemented in the kernel.

b. About header files:

i. <linux/inotify.h> The corresponding code is located in include/linux/inotify.h

ii. The corresponding code of <asm/ioctl.h> is located in arch/<arch>/include/asm/ioctl.h

c. printk() is equivalent to printf() under the kernel.

 

GNU C must be used when compiling the kernel

a. The kernel does not fully comply with the ANSI C standard, but uses many C language extensions provided by gcc.

i. Inline function:

1) Function form:

static inline void func (int a)

2) The inline function will expand at the location where it is called.

3) Kernel developers usually define functions with high time requirements and short length as inline functions.

4) Inline functions are preferred to macros in the kernel.

ii. Inline assembly:

1) The gcc compiler supports embedding assembly instructions in C functions:

2) Such as:

/*
 * Set up the IDT
 */
static void setup_idt(void)
{
    static const struct gdt_ptr null_idt = {0, 0};
    asm volatile("lidtl %0" : : "m" (null_idt));
}

3) In places close to the bottom of the architecture or where the execution time is strict, assembly language is generally used.

iii. Branch statement:

1) Similar to the following:

if (unlikely(ret)) {
    pr_err("%s: CPU clock registration failed.\n", __func__);
    return ret;
}
/* no error */
if (likely(!dev->cmd_err))
    return msg->len;

2) Likely and unlike are used to identify our understanding of the branch. If we know that a branch is not easy to enter, we use unlike, otherwise, if it is easy to enter, we use like.

3) When our judgment is correct, performance can be improved, otherwise performance will decrease.

 

The lack of a memory protection mechanism like user space during kernel programming

 

Difficult to perform floating point operations during kernel programming

a. The kernel cannot perfectly support floating point operations.

b. It is best not to use it.

 

The kernel has only a small fixed-length stack for each process

a. The size of the kernel stack is related to the architecture.

b. On x86, the stack size is configured at compile time, which can be 4KB or 8KB.

Take 32-bit as an example (arch\x86\include\asm\page_32_types.h):

#ifdef CONFIG_4KSTACKS
#define THREAD_ORDER	0
#else
#define THREAD_ORDER	1
#endif
#define THREAD_SIZE 	(PAGE_SIZE << THREAD_ORDER)

If there is no configuration in .config, the 8K stack is used.

For 64-bit, the default is 8K (arch\x86\include\asm\page_64_types.h):

#define THREAD_ORDER	1
#define THREAD_SIZE  (PAGE_SIZE << THREAD_ORDER)

 

Since the kernel supports asynchronous interrupts, preemption, and SMP, you must always pay attention to synchronization and concurrency

a. Commonly used methods to resolve competition are spin locks and semaphores.

 

Consider the importance of portability

 

Guess you like

Origin blog.csdn.net/jiangwei0512/article/details/105962385