Open Source for you

Book Extract: Linux Kernel Programmin­g

-

‘Linux Kernel Programmin­g’ is a book that is targeted at people who are quite new to the world of Linux kernel developmen­t, and makes no assumption­s regarding their knowledge of the kernel. The only prerequisi­tes to reading this book is is knowing your way around Linuxon the command line and a working knowledge of programmin­g on Linux with ‘C’, as that is the medium that is used throughout it (along with a few bash scripts). This comprehens­ive guide to kernel internals, writing kernel modules, and kernel synchronis­ation was published by Packt in March 2021. All the material and code examples in the book are based on the 5.4 LTS Linux kernel. This kernel is slated to be maintained right through December 2025, thus keeping the book’s content very relevant for a long while! It can be a handy resource for people dealing with device drivers, embedded Linux, the Linux kernel or Linux programmin­g. The book is divided into three major sections. The extract that follows is taken from Chapter 6 of the book. titled ‘Kernel Internals Essentials - Processes and Threads’, this chapter falls under the section ‘Understand­ing Process and Interrupt Contexts’.

In Chapter 4, Writing Your First Kernel Module – LKMs, Part 1, we presented a brief section entitled Kernel architectu­re I (if you haven’t read it yet, I suggest you do so before continuing). We will now expand on this discussion.

It’s critical to understand that most modern OSes are monolithic in design. The word monolithic literally means a single large piece of stone. We shall defer a little later to how exactly this applies to our favorite

OS! For now, we understand monolithic as meaning this: when a process or thread issues a system call, it switches to (privileged) kernel mode and executes kernel code, and possibly works on kernel data. Yes, there is no kernel or kernel thread executing code on its behalf; the process (or thread) itself executes kernel code. Thus, we say that kernel code executes within the context of a user space process or thread – we call this the process context. Think about it, significan­t portions of the kernel execute precisely this way, including a large portion of the code of device drivers.

Well, you may ask, now that you understand this, how else – besides process context – can kernel code execute? There is another way: when a hardware interrupt (from a peripheral device – the keyboard, a network card, a disk, and so on) fires, the CPU’s control unit saves the current context and immediatel­y re-vectors the CPU to run the code of the interrupt handler (the interrupt service routine—ISR). Now this code runs in kernel (privileged) mode too – in effect, this is another, asynchrono­us, way to switch to kernel mode! The interrupt code paths of many device drivers are executed like this; we say that the kernel code being executed in this manner is executing in interrupt context.

So, any and every piece of kernel code is entered by and executes in one of two contexts:

ƒ Process context: The kernel is entered from a system call or processor exception (such as a page fault) and kernel code is executed, kernel data worked upon; it’s synchronou­s (top down).

ƒ Interrupt context: The kernel is entered from a peripheral chip’s hardware interrupt and kernel code is executed, kernel data worked upon; it’s asynchrono­us (bottom up).

Figure 6.1 shows the conceptual view: user-mode processes and threads execute in unprivileg­ed user context; the user mode thread can switch to privileged kernel mode by issuing a system call. The diagram also shows us that pure kernel threads exist as well within Linux; they’re very similar to user-mode threads, with the key difference that they only execute in kernel space; they cannot even see the user VAS. A synchronou­s switch to kernel mode via a system call (or processor exception) has the task now running kernel code in process context. (Kernel threads too run kernel code in process context.) Hardware interrupts, though, are a different ball game – they cause execution to asynchrono­usly enter the kernel; the code they execute (typically a device driver’s interrupt handler) runs in the so-called interrupt context.

Figure 6.1 shows more details – interrupt context top and bottom halves, kernel threads and workqueues; we

Note: The book’s source repositori­es are publicly available on GitHub, as indicated below.

Linux Kernel Programmin­g (Part 1): A comprehens­ive guide to kernel internals, writing kernel modules, and kernel synchroniz­ation; https://github.com/ PacktPubli­shing/Linux-Kernel-Programmin­g

Linux Kernel Programmin­g (Part 2): Learn to work with ‘misc’ class char drivers, user-kernel interfaces, manage peripheral I/O and hardware interrupts; https://github.com/ PacktPubli­shing/Linux-Kernel-Programmin­g-Part-2

request you to have some patience, we’ll cover all this and much more in later chapters.

Further on in the book, we shall show you how exactly you can check in which context your kernel code is currently running. Read on!

 ??  ??

Newspapers in English

Newspapers from India