青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 297,  comments - 15,  trackbacks - 0

linux kernel development-chapter 2 getting started with the kernel 

A Beast of a Different Nature

The kernel has several differences compared to normal user-space applications that, although not making it necessarily harder to program than user-space, certainly provide unique challenges to kernel development.

These differences make the kernel a beast of a different nature. Some of the usual rules are bent; other rules are entirely new. Although some of the differences are obvious (we all know the kernel can do anything it wants), others are not so obvious. The most important of these differences are

  • The kernel does not have access to the C library.

  • The kernel is coded in GNU C.

  • The kernel lacks memory protection like user-space.

  • The kernel cannot easily use floating point.

  • The kernel has a small fixed-size stack.

  • Because the kernel has asynchronous interrupts, is preemptive, and supports SMP, synchronization and concurrency are major concerns within the kernel.

  • Portability is important.

Let's briefly look at each of these issues because all kernel development must keep them in mind.

No libc

Unlike a user-space application, the kernel is not linked against the standard C library (or any other library, for that matter). There are multiple reasons for this, including some chicken-and-the-egg situations, but the primary reason is speed and size. The full C libraryor even a decent subset of itis too large and too inefficient for the kernel.

Do not fret: Many of the usual libc functions have been implemented inside the kernel. For example, the common string manipulation functions are in lib/string.c. Just include <linux/string.h> and have at them.

Header Files

When I talk about header files hereor elsewhere in this bookI am referring to the kernel header files that are part of the kernel source tree. Kernel source files cannot include outside headers, just as they cannot use outside libraries.


Of the missing functions, the most familiar is printf(). The kernel does not have access to printf(), but it does have access to printk(). The printk() function copies the formatted string into the kernel log buffer, which is normally read by the syslog program. Usage is similar to printf():

printk("Hello world! A string: %s and an integer: %d\n", a_string, an_integer);

One notable difference between printf() and printk() is that printk() allows you to specify a priority flag. This flag is used by syslogd(8) to decide where to display kernel messages. Here is an example of these priorities:

printk(KERN_ERR "this is an error!\n");

We will use printk() tHRoughout this book. Later chapters have more information on printk().

GNU C

Like any self-respecting Unix kernel, the Linux kernel is programmed in C. Perhaps surprisingly, the kernel is not programmed in strict ANSI C. Instead, where applicable, the kernel developers make use of various language extensions available in gcc (the GNU Compiler Collection, which contains the C compiler used to compile the kernel and most everything else written in C on a Linux system).

The kernel developers use both ISO C99[1] and GNU C extensions to the C language. These changes wed the Linux kernel to gcc, although recently other compilers, such as the Intel C compiler, have sufficiently supported enough gcc features that they too can compile the Linux kernel. The ISO C99 extensions that the kernel uses are nothing special and, because C99 is an official revision of the C language, are slowly cropping up in a lot of other code. The more interesting, and perhaps unfamiliar, deviations from standard ANSI C are those provided by GNU C. Let's look at some of the more interesting extensions that may show up in kernel code.

[1] ISO C99 is the latest major revision to the ISO C standard. C99 adds numerous enhancements to the previous major revision, ISO C90, including named structure initializers and a complex type. The latter of which you cannot use safely from within the kernel.

Inline Functions

GNU C supports inline functions. An inline function is, as its name suggests, inserted inline into each function call site. This eliminates the overhead of function invocation and return (register saving and restore), and allows for potentially more optimization because the compiler can optimize the caller and the called function together. As a downside (nothing in life is free), code size increases because the contents of the function are copied to all the callers, which increases memory consumption and instruction cache footprint. Kernel developers use inline functions for small time-critical functions. Making large functions inline, especially those that are used more than once or are not time critical, is frowned upon by the kernel developers.

An inline function is declared when the keywords static and inline are used as part of the function definition. For example:

static inline void dog(unsigned long tail_size)

The function declaration must precede any usage, or else the compiler cannot make the function inline. Common practice is to place inline functions in header files. Because they are marked static, an exported function is not created. If an inline function is used by only one file, it can instead be placed toward the top of just that file.

In the kernel, using inline functions is preferred over complicated macros for reasons of type safety.

Inline Assembly

The gcc C compiler enables the embedding of assembly instructions in otherwise normal C functions. This feature, of course, is used in only those parts of the kernel that are unique to a given system architecture.

The asm() compiler directive is used to inline assembly code.

The Linux kernel is programmed in a mixture of C and assembly, with assembly relegated to low-level architecture and fast path code. The vast majority of kernel code is programmed in straight C.

Branch Annotation

The gcc C compiler has a built-in directive that optimizes conditional branches as either very likely taken or very unlikely taken. The compiler uses the directive to appropriately optimize the branch. The kernel wraps the directive in very easy-to-use macros, likely() and unlikely().

For example, consider an if statement such as the following:

if (foo) {
/* ... */
}

To mark this branch as very unlikely taken (that is, likely not taken):

/* we predict foo is nearly always zero ... */
if (unlikely(foo)) {
/* ... */
}

Conversely, to mark a branch as very likely taken:

/* we predict foo is nearly always nonzero ... */
if (likely(foo)) {
/* ... */
}

You should only use these directives when the branch direction is overwhelmingly a known priori or when you want to optimize a specific case at the cost of the other case. This is an important point: These directives result in a performance boost when the branch is correctly predicted, but a performance loss when the branch is mispredicted. A very common usage for unlikely() and likely() is error conditions. As one might expect, unlikely() finds much more use in the kernel because if statements tend to indicate a special case.

No Memory Protection

When a user-space application attempts an illegal memory access, the kernel can trap the error, send SIGSEGV, and kill the process. If the kernel attempts an illegal memory access, however, the results are less controlled. (After all, who is going to look after the kernel?) Memory violations in the kernel result in an oops, which is a major kernel error. It should go without saying that you must not illegally access memory, such as dereferencing a NULL pointerbut within the kernel, the stakes are much higher!

Additionally, kernel memory is not pageable. Therefore, every byte of memory you consume is one less byte of available physical memory. Keep that in mind next time you have to add one more feature to the kernel!

No (Easy) Use of Floating Point

When a user-space process uses floating-point instructions, the kernel manages the transition from integer to floating point mode. What the kernel has to do when using floating-point instructions varies by architecture, but the kernel normally catches a trap and does something in response.

Unlike user-space, the kernel does not have the luxury of seamless support for floating point because it cannot trap itself. Using floating point inside the kernel requires manually saving and restoring the floating point registers, among possible other chores. The short answer is: Don't do it; no floating point in the kernel.

Small, Fixed-Size Stack

User-space can get away with statically allocating tons of variables on the stack, including huge structures and many-element arrays. This behavior is legal because user-space has a large stack that can grow in size dynamically (developers of older, less intelligent operating systemssay, DOSmight recall a time when even user-space had a fixed-sized stack).

The kernel stack is neither large nor dynamic; it is small and fixed in size. The exact size of the kernel's stack varies by architecture. On x86, the stack size is configurable at compile-time and can be either 4 or 8KB. Historically, the kernel stack is two pages, which generally implies that it is 8KB on 32-bit architectures and 16KB on 64-bit architecturesthis size is fixed and absolute. Each process receives its own stack.

The kernel stack is discussed in much greater detail in later chapters.

Synchronization and Concurrency

The kernel is susceptible to race conditions. Unlike a single-threaded user-space application, a number of properties of the kernel allow for concurrent access of shared resources and thus require synchronization to prevent races. Specifically,

  • Linux is a preemptive multi-tasking operating system. Processes are scheduled and rescheduled at the whim of the kernel's process scheduler. The kernel must synchronize between these tasks.

  • The Linux kernel supports multiprocessing. Therefore, without proper protection, kernel code executing on two or more processors can access the same resource.

  • Interrupts occur asynchronously with respect to the currently executing code. Therefore, without proper protection, an interrupt can occur in the midst of accessing a shared resource and the interrupt handler can then access the same resource.

  • The Linux kernel is preemptive. Therefore, without protection, kernel code can be preempted in favor of different code that then accesses the same resource.

Typical solutions to race conditions include spinlocks and semaphores.

Later chapters provide a thorough discussion of synchronization and concurrency.

Portability Is Important

Although user-space applications do not have to aim for portability, Linux is a portable operating system and should remain one. This means that architecture-independent C code must correctly compile and run on a wide range of systems, and that architecture-dependent code must be properly segregated in system-specific directories in the kernel source tree.

A handful of rulessuch as remain endian neutral, be 64-bit clean, do not assume the word or page size, and so ongo a long way. Portability is discussed in extreme depth in a later chapter.


posted on 2010-05-22 21:09 chatler 閱讀(620) 評論(0)  編輯 收藏 引用 所屬分類: linux kernel
<2009年11月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用鏈接

留言簿(10)

隨筆分類(307)

隨筆檔案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美一区二区三区另类 | 久久综合精品国产一区二区三区| 国产精品国产三级国产a| 国产精品99久久久久久久女警| 亚洲黄色成人| 欧美精品免费观看二区| 夜夜嗨av一区二区三区四区| 日韩视频免费观看高清完整版| 欧美日韩精品一区二区三区| 亚洲欧美国产制服动漫| 先锋影院在线亚洲| 精东粉嫩av免费一区二区三区| 欧美成人小视频| 欧美日韩亚洲三区| 欧美一区二区三区在线观看| 久久精品免费观看| 亚洲美女精品成人在线视频| aaa亚洲精品一二三区| 国产日韩欧美高清免费| 久久久综合网站| 欧美经典一区二区三区| 午夜精品久久久久久久99黑人| 久久久久久久久岛国免费| 99精品欧美一区| 欧美主播一区二区三区美女 久久精品人 | 久久日韩粉嫩一区二区三区| 亚洲精品少妇30p| 亚洲欧美日韩国产精品| 最新日韩中文字幕| 午夜欧美精品久久久久久久| 亚洲国产精品视频一区| 亚洲午夜激情网站| 亚洲经典三级| 欧美专区第一页| 亚洲香蕉网站| 久久综合伊人77777尤物| 亚洲欧美日韩国产成人| 欧美高清视频一二三区| 久久天天躁夜夜躁狠狠躁2022 | 欧美日韩国产综合一区二区| 久久精品一区| 欧美午夜宅男影院| 亚洲高清一区二| 国产日韩精品一区二区三区在线 | 欧美黄色成人网| 国产欧美日韩一区| 一区二区三区国产盗摄| 最新日韩在线视频| 久久一区二区精品| 久久精品99| 国产精品午夜在线| 99视频精品全国免费| 亚洲黄色片网站| 久热这里只精品99re8久| 欧美在线免费观看| 国产精品女人久久久久久| 日韩亚洲综合在线| 一区二区三区成人| 欧美精品在线免费播放| 亚洲电影免费观看高清完整版在线 | 久久精品国产77777蜜臀| 欧美在线在线| 国产婷婷97碰碰久久人人蜜臀| 亚洲小视频在线观看| 亚洲午夜性刺激影院| 欧美日韩免费在线观看| 日韩网站在线| 亚洲一级免费视频| 欧美午夜电影一区| 亚洲午夜久久久久久久久电影院 | 亚洲与欧洲av电影| 国产精品激情av在线播放| 99精品欧美一区| 午夜精品一区二区三区四区| 国产精品你懂的| 午夜视频在线观看一区二区三区| 先锋影音一区二区三区| 国产美女一区二区| 亚洲欧美一级二级三级| 久久人人爽爽爽人久久久| 伊人蜜桃色噜噜激情综合| 久久免费视频观看| 亚洲人午夜精品免费| 亚洲一级一区| 国产一区91| 牛牛国产精品| 一本大道久久精品懂色aⅴ| 亚洲一区亚洲| 国内精品久久久久久久果冻传媒| 久久综合久久综合久久| 亚洲精品免费在线播放| 午夜欧美不卡精品aaaaa| 激情欧美国产欧美| 欧美韩日精品| 香蕉久久夜色精品国产| 欧美大片在线观看一区二区| 在线亚洲一区| 黄色成人精品网站| 欧美日韩国产综合一区二区| 欧美一区二区视频免费观看| 欧美激情中文字幕一区二区| 在线天堂一区av电影| 国产一区二区久久| 欧美乱大交xxxxx| 欧美在线播放一区二区| 亚洲人成在线观看一区二区| 久久久国产视频91| 日韩午夜三级在线| 黄色日韩在线| 国产精品theporn88| 免费成人高清视频| 亚洲欧美中文字幕| 亚洲人成毛片在线播放| 久久久噜噜噜| 亚洲欧美中文日韩在线| 亚洲精品一区中文| 精品999在线播放| 国产免费亚洲高清| 欧美日韩亚洲另类| 欧美顶级大胆免费视频| 欧美在线视频二区| 亚洲一区二区网站| av成人福利| 亚洲日本无吗高清不卡| 欧美大片免费观看| 久久久久久久综合狠狠综合| 亚洲综合三区| 中日韩美女免费视频网址在线观看| 玉米视频成人免费看| 国产香蕉久久精品综合网| 欧美色一级片| 欧美视频日韩视频| 欧美精品日韩一本| 欧美顶级大胆免费视频| 免费91麻豆精品国产自产在线观看| 欧美一区二区女人| 午夜精品久久久久99热蜜桃导演| 99热这里只有成人精品国产| 亚洲精品偷拍| 亚洲精品日韩一| 亚洲精品国产系列| 亚洲精品乱码久久久久久黑人 | 美女主播一区| 美女诱惑一区| 欧美福利专区| 欧美国产日韩二区| 欧美国产91| 亚洲高清一区二区三区| 亚洲国产精品123| 欧美激情精品久久久久久黑人 | 亚洲一级电影| 亚洲欧美日韩精品久久亚洲区| 亚洲最黄网站| 亚洲午夜羞羞片| 欧美一区=区| 久久一区二区三区超碰国产精品| 狼人社综合社区| 免费一级欧美片在线观看| 欧美不卡在线视频| 欧美日本一区| 国产精品久久久久影院亚瑟| 国产亚洲激情| 亚洲片在线资源| 亚洲一区二区在线免费观看| 午夜精品在线观看| 久久综合久久久久88| 亚洲电影在线免费观看| 一区二区三区福利| 久久精品国产久精国产一老狼| 久久视频一区| 欧美日韩一区精品| 国产日韩欧美在线播放不卡| 亚洲电影免费观看高清完整版在线 | 国产精品一区二区在线观看网站 | 欧美视频在线观看免费| 国产视频不卡| 亚洲精品一区中文| 久久国产精品久久久| 欧美激情欧美狂野欧美精品 | 欧美国产综合| 亚洲婷婷国产精品电影人久久 | 亚洲美女视频在线免费观看| 午夜精品电影| 欧美另类99xxxxx| 好看不卡的中文字幕| 一本色道婷婷久久欧美| 久久久久久久综合| 亚洲麻豆视频| 麻豆av一区二区三区久久| 国产精品久久午夜| 亚洲精品一二三区| 老牛影视一区二区三区| 9色国产精品| 欧美国产精品人人做人人爱| 国产欧美日韩视频在线观看| 日韩午夜剧场| 欧美成人精品高清在线播放| 亚洲欧美在线播放| 欧美特黄一区| 日韩午夜av电影|