Linux Kernel You Don't Know - How the Linux Kernel Works

Linux kernel updates are getting faster and faster. Maybe due to the popularity of Linux, everyone has begun to pay attention, and various security risks are also increasing. Supports Intel, Alpha, PPC, Sparc, IA-64, ARM, MIPS, Amiga, Atari and IBMs/390, etc. It also supports 32-bit large file systems. On the Intel platform, the maximum physical memory support can reach 64GB. Enhanced support for IDE and SCSI hardware systems, and enhanced support for USB devices and 3D accelerator cards. The following is a detailed introduction to LinuxKernel.

    The Oxford dictionary defines the word "kernel" as: "the softer, usually edible part of a nut." There is of course a second definition: "the core or most important part of something." For Linux In other words, its Kernel undoubtedly belongs to the second explanation. Let's see how this important thing works, starting with a little theory.

    Broadly speaking, a kernel is a piece of software that provides a layer between the hardware and the applications running on the computer. Strictly speaking from a computer science point of view, Kernel in Linux refers to that bit of code written by Linus Torvalds in the early 90s.

    All the other things you see in Linux versions--Bash shell, KDE window manager, web browser, X server, Tux Racer, and all the rest are just applications running on Linux, not part of the operating system itself. In order to give you a more intuitive feeling, let me give you an example. For example, the installation of RHEL5 takes about 2.5GB of hard disk space (the exact size depends on your choice of installation, of course). Among them, the kernel and its various modules components, only 47MB, accounting for about 2%.
 

inside the kernel

    So how exactly does the kernel work? See the chart below. The Kernel makes available to applications running on it through a number of ingress ports or what we technically call system calls. Kernel uses system calls such as "read" and "write" to provide abstraction of your hardware.

    From the programmer's point of view, these seem to be ordinary function calls, but in fact system calls have an obvious switch from user space to kernel space in the operating mode of the processor. At the same time, system calls provide a "Linux virtual machine" that can be thought of as an abstraction of the hardware.

    One of the more obvious abstractions provided by the Kernel is the file system. For example, here is a short program written in C that opens a file and copies the contents to standard output:

    #include <fcntl.h>
    int main()
    {
        int fd, count; char buf[1000];
        fd=open("mydata", O_RDONLY);
        count = read(fd, buf, 1000);
        write(1, buf, count);
        close(fd);
    }

Behind     the Scenes Here, you can see examples of four system calls: open, read, write, and close. Without going into the details of the syntax of this program, the point is: through these system calls the Linux Kernel provides the "illusion" of a file, when in fact it is just a bunch of data with a name, so that you don't have to deal with the hardware The underlying stacks, partitions, headers, pointers, partitions, etc. are negotiated, but directly "communicate" with the hardware in the way in the example, which is what we call abstraction, which makes the underlying things more understandable. express it.
    System files are an obvious abstraction provided by Kernel. There are also some features that are not so obvious, such as process scheduling. At any one time, there may be several processes or programs waiting to run. Kernel's time scheduling allocates CPU time to each process, so for a period of time, we will have the illusion that the computer is running several programs at the same time. Here is another C program:

    #include <stdlib.h>
    main()
    {
      if (fork()) {
        write(1, "Parent\n", 7);
        wait(0);
        exit(0);
      }
      else {
        write(1, "Child\n", 6);
        exit(0);
      }
    }

 

    In this program a new process is created, and both the original process (parent process) and the new process (child process) write to standard output and then terminate. Note that the system calls fork(), exit() and wait() execute program creation, termination and synchronization respectively. This is the most typical simple call in process management and scheduling.

    Kernel also has a more difficult to see function, even the programmer is not easy to detect, that is storage management. Each program runs as if it has its own address space to call. In fact, it shares the computer's physical storage like other processes. If the system runs too low on storage, its address space will even be blocked by the interactive area of ​​the disk. Temporarily sent. Another aspect of memory management is preventing one process from accessing the address space of another process -- a necessary precaution for multi-process operating systems.

    Kernel also configures network link protocols such as IP, TCP and UDP, which provide machine-to-machine and process-to-process communication over the network. Here again, an illusion will be created, that is, TCP provides a fixed connection between two processes - just like a copper wire connecting two telephones, but in reality there is no fixed connection, special reference protocols such as FTP, DNS and HTTP are implemented through user-level programs, not part of the Kernel.

    Linux (like Unix before it) has a good reputation for security because the Kernel keeps track of the user ID and group ID of each running process, every time an application attempts to access a resource (such as opening a file for writing) At that time, the Kernel will check the access permission on the file and make an allow/disable command. This access control mode ultimately has a great effect on the security of the entire Linux system.

    Kernel also provides a large set of modules whose functions include how to handle the details of how to communicate with hardware devices, how to read a partition from disk, how to get packets from a network interface card, etc. Sometimes we call these device drivers.
 

Modular Kernel

    Now that we have some understanding of what the Kernel does, let's take a brief look at its physical composition. Earlier versions of the Linux Kernel were monolithic, meaning that all components were statically linked into a (large) executable.

    In contrast, the current Linux kernel is modular: many functions are contained in modules, which are then dynamically loaded into the kernel. This makes the kernel's kernel small, and modules can be loaded and replaced without rebooting when the kernel is running.

    The kernel of the kernel is loaded into storage at boot time from a file located in the /boot directory. Usually this /boot directory will be called KERNELVERSION , and KERNELVERSION is related to the kernel version. (If you want to know what your kernel version is, run the command line to display system info -r.) The kernel modules are located in the directory /lib/modules/KERNELVERSION, and all components are copied when the kernel is installed.
 

management module

    Most of the time, Linux doesn't need your help to manage its modules, but there is a command line to check and manage modules manually if necessary. For example, to find out which module is currently being loaded into the kernel. Here is an example of lsmod output:

    # lsmod

    pCSPkr                  4224   0

    hci_usb                  18204  2

    psmouse 38920 0

    bluetooth                55908  7  rfcomm,l2cap,hci_usb

    yenta_socket          27532  5

    rSRC_nonstatIC     14080  1  yenta_socket

    iSOFs                     36284  0

    The output includes: the name of the module, its size, the number of times it has been used, and a list of modules that depend on it. The usage count is very important to prevent uninstalling of currently active modules. Linux only allows modules with zero usage count to be removed.

    You can use modprobe to manually load and unload modules, (there are also two command lines called insmod and rmmod , but modprobe is easier to use because it automatically removes module dependencies). For example, the output of lsmod shows an uninstalled module called isofs on our computer, which has zero usage and no dependent modules, (isofs is a module that supports the ISO system file format used on CDs) This situation Next, the kernel will allow us to unload the module:

    # modprobe -r isofs 

    Now, isofs no longer shows up in Ismod's output, saving the kernel 36,284 bytes of storage. If you put in the CD and let it install automatically, the kernel will automatically reload the isofs module and the isofs usage count increases to 1. If you also try to remove the module at this point, it won't work because it's being used:

    # modprobe -r isofs   

    FATAL: Module isofs is in use.

    Lsmod just lists the currently loaded modules, modprobe will list all available modules, it actually outputs all the modules in the /lib/modules/KERNELVERSION directory, the list will be very long!

    In practice, it is not common to use modprobe to manually load a module, but it is possible to set parameters for a module via the modprobe command line , for example:

    # modprobe usbcore blinkenlights=1 

    We are not creating blinkenlights, but actual parameters of the usbcore module.

    So how do you know what parameters a module will accept? A better way is to use the modinfo command, which lists various information about the module. Here is an example on the module snd-hda-intel

    # modinfo snd-hda-intel

    filename:      /lib/modules/2.6.20-16-generic/kernel/sound/PCI/hda/snd-hda-intel.ko

    description:   Intel HDA driver

    license:       GPL

    srcversion: A3552B2DF3A932D88FFC00C

    alias:         pci:v000010DEd0000055Dsv*sd*bc*sc*i*

    alias:         pci:v000010DEd0000055Csv*sd*bc*sc*i*

    depends:       snd-PCM,snd-page-alLOC,snd-hda-codec,snd

    vermagic:      2.6.20-16-generic SMP mod_unload 586

    parm:          index:Index value for Intel HD audio interface. (int)

    parm:          id:ID string for Intel HD audio interface. (charp)

    parm:          model:Use the given board model. (charp)

    parm:          position_fix:Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size). (int)

    parm:          probe_mask:Bitmask to probe codecs (default = -1). (int)

    parm:          single_cmd:Use single command to communicate with codecs (for debugging only). (bool)

    parm:          enable_msi:Enable Message SignaLED Interrupt (MSI) (int)

    parm:          enable:bool

    对我们来说比较有兴趣的以"parm"开头的那些部分:显示了模块所接受的参数。这些描述都比较简明,如果想要更多的信息,那就安装kernel的源代码,在类似于/usr/src/KERNELVERSION/Documentation的目录下你会找到。

    里面会有一些有趣的东西,比如文件/usr/src/KERNELVERSION/Documentation/sound/alsa/ALSA-Configuration.txt描述的是被许多ALSA声音模块承认的参数;/usr/src/KERNELVERSION/Documentation/kernel-parameters.txt这个文件也很有用。

    前几天在Ubuntu论坛有一个例子,说的是如何将参数传递到一个模块(详见https://help.ubuntu.com/community/HdaIntelSoundHowto)。实际上问题的关键是snd-hda-intel参数在正确驱动声音硬件时需要一点操作,而且在boot time加载时会中止。解决方法的一部分是将probe_mask=1选项赋给模块,如果你是手动加载模块,你需要输入:

    # modprobe snd-hda-intel probe_mask=1 

    更有可能,你在文件/etc/modprobe.conf中放置这样类似的一行:options snd-hda-intel probe_mask=1

    这"告诉"modprobe每次在加载snd-hda-intel模块时包含probe_mask=1选项。现在的有些Linux版本将这一信息分离进/etc/modprobe.d下的不同文件中了,而不是放入modprobe.conf中。
 

/proc系统文件

    Linux kernel同样通过/proc系统文件来展示了许多细节。为了说明/proc,我们首先需要扩展我们对于文件的理解。除了认为文件就是存储在硬盘或者CD或者存储空间上的持久信息之外,我们还应当把它理解为任何可以通过传统系统调用如:打开、读、写、关闭等访问的信息,当然它也可以被常见的程序访问。

    /proc之下的"文件"完全是kernel虚拟的一个部分,给我们一个视角可以看到kernel内部的数据结构。实际上,许多Linux的报告工具均能够很好地呈现在/proc下的文件中寻到的格式化版本的信息。比如,一行/proc/modules将展示一行当前加载的模块。

    同样的,/proc/meminfo提供了关于虚拟存储系统当前状态的更多细节信息,而类如vmstat的工具则是以一种更加可理解的方式提供了相同的一些信息;/proc/net/arp显示了系统ARP cache的当前内容,从命令行来说,arp -a显示的也是相同的信息。

    尤其有意思的是/proc/sys下的"文件"。/proc/sys/net/ipv4/ip_forward下的设置告诉我们kernel是否将转发IP数据包,也就是说是否扮演网关的作用。现在,kernel告诉我们这是关闭的:

    # cat /proc/sys/net/ipv4/ip_forward   

    0

    当你发现你可以对这些文件写入的时候,你会觉得更加有意思。继续举例来说:

    # echo 1 > /proc/sys/net/ipv4/ip_forward

将在运行的kernel中打开IP 转发(IP forwarding)

除了使用cat和echo来检查和更正/proc/sys下的设置以外,你也可以使用sysctl命令:

    # sysctl net.ipv4.ip_forward     

    net.ipv4.ip_forward = 0 

这等同于:

    # cat /proc/sys/net/ipv4/ip_forward   

    0 

也等同于:

    # sysctl -w net.ipv4.ip_forward=1  

    net.ipv4.ip_forward = 1 

还等同于:

    # echo 1 > /proc/sys/net/ipv4/ip_forward 

    需要注意的是,以这种方式你所做的设置改变只能影响当前运行的kernel的,当reboot的时候就不再有效。如果想让设置永久有效,将它们放置在/etc/sysctl.conf文件中。在boot time时,sysctl将自动重新确定它在此文件下找到的任何设置。

/etc/sysctl.conf下的代码行大概是这样的:net.ipv4.ip_forward=1
 

性能调优(performance tuning)

    有这样一个说法:/proc/sys下可写入的参数孕育了整个Linux性能调优的亚文化。我个人觉得这种说法有点过夸,但这里会有几个你确实很想一试的例子:Oracle 10g的安装说明(www.oracle.com/technology/obe/obe10gdb/install/linuxpreinst/linuxpreinst.htm)要求你设置一组参数,包括:kernel.shmmax=2147483648 这将公用存储器的大小设置为2GB。(公用存储器是处理期内的通信机制,允许存储单元在多个进程的地址空间内同时可用)

    IBM 'Redpaper'在Linux性能和调优方面的说明(www.redbooks.ibm.com/abstracts/redp4285.html)在调教/proc/sys下的参数方面给出了不少建议,包括:vm.swappiness=100 这个参数控制着存储页如何被交换到磁盘。

    一些参数可以被设置从而提高安全性,如net.ipv4.icmp_echo_ignore_broadcasts=1 它"告诉"kernel不必响应ICMP请求,从而使得你的网络免受类如Smurf攻击之类的拒绝服务器(denial-of-service)型攻击。

    net.ipv4.conf.all.rp_filter=1 则是"告诉"kernel加强入站过滤(ingress filtering)和出站过滤(egress filtering)

    那么有没有一个说明能涵盖这所有的参数?好吧,这有一行命令:# sysctl -a 它将展示所有的参数名字和当前值。列表很长,但是你无法知道这些参数是做什么的。另外比较有用的参考是Red Hat Enterprise Linux Reference Guide,对此有整章节的描述,你可以从www.redhat.com/docs/manuals/enterprise上下载。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324498909&siteId=291194637