⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kernel-hacking.tmpl

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 TMPL
📖 第 1 页 / 共 4 页
字号:
   </para>  </sect1>  <sect1 id="routines-init">   <title><type>__init</type>/<type>__exit</type>/<type>__initdata</type>    <filename class=headerfile>include/linux/init.h</filename></title>   <para>    After boot, the kernel frees up a special section; functions    marked with <type>__init</type> and data structures marked with    <type>__initdata</type> are dropped after boot is complete (within    modules this directive is currently ignored).  <type>__exit</type>    is used to declare a function which is only required on exit: the    function will be dropped if this file is not compiled as a module.    See the header file for use. Note that it makes no sense for a function    marked with <type>__init</type> to be exported to modules with     <function>EXPORT_SYMBOL()</function> - this will break.   </para>   <para>   Static data structures marked as <type>__initdata</type> must be initialised   (as opposed to ordinary static data which is zeroed BSS) and cannot be    <type>const</type>.   </para>   </sect1>  <sect1 id="routines-init-again">   <title><function>__initcall()</function>/<function>module_init()</function>    <filename class=headerfile>include/linux/init.h</filename></title>   <para>    Many parts of the kernel are well served as a module    (dynamically-loadable parts of the kernel).  Using the    <function>module_init()</function> and    <function>module_exit()</function> macros it is easy to write code    without #ifdefs which can operate both as a module or built into    the kernel.   </para>   <para>    The <function>module_init()</function> macro defines which    function is to be called at module insertion time (if the file is    compiled as a module), or at boot time: if the file is not    compiled as a module the <function>module_init()</function> macro    becomes equivalent to <function>__initcall()</function>, which    through linker magic ensures that the function is called on boot.   </para>   <para>    The function can return a negative error number to cause    module loading to fail (unfortunately, this has no effect if    the module is compiled into the kernel).  For modules, this is    called in user context, with interrupts enabled, and the    kernel lock held, so it can sleep.   </para>  </sect1>    <sect1 id="routines-moduleexit">   <title> <function>module_exit()</function>    <filename class=headerfile>include/linux/init.h</filename> </title>   <para>    This macro defines the function to be called at module removal    time (or never, in the case of the file compiled into the    kernel).  It will only be called if the module usage count has    reached zero.  This function can also sleep, but cannot fail:    everything must be cleaned up by the time it returns.   </para>  </sect1>  <sect1 id="routines-module-use-counters">   <title> <function>MOD_INC_USE_COUNT</function>/<function>MOD_DEC_USE_COUNT</function>    <filename class=headerfile>include/linux/module.h</filename></title>   <para>    These manipulate the module usage count, to protect against    removal (a module also can't be removed if another module uses    one of its exported symbols: see below).  Every reference to    the module from user context should be reflected by this    counter (e.g. for every data structure or socket) before the    function sleeps.  To quote Tim Waugh:   </para>   <programlisting>/* THIS IS BAD */foo_open (...){        stuff..        if (fail)                return -EBUSY;        sleep.. (might get unloaded here)        stuff..        MOD_INC_USE_COUNT;        return 0;}/* THIS IS GOOD /foo_open (...){        MOD_INC_USE_COUNT;        stuff..        if (fail) {                MOD_DEC_USE_COUNT;                return -EBUSY;        }        sleep.. (safe now)        stuff..        return 0;}   </programlisting>   <para>   You can often avoid having to deal with these problems by using the    <structfield>owner</structfield> field of the    <structname>file_operations</structname> structure. Set this field   as the macro <symbol>THIS_MODULE</symbol>.   </para>   <para>   For more complicated module unload locking requirements, you can set the   <structfield>can_unload</structfield> function pointer to your own routine,   which should return <returnvalue>0</returnvalue> if the module is   unloadable, or <returnvalue>-EBUSY</returnvalue> otherwise.   </para>     </sect1> </chapter> <chapter id="queues">  <title>Wait Queues   <filename class=headerfile>include/linux/wait.h</filename>  </title>  <para>   <emphasis>[SLEEPS]</emphasis>  </para>  <para>   A wait queue is used to wait for someone to wake you up when a   certain condition is true.  They must be used carefully to ensure   there is no race condition.  You declare a   <type>wait_queue_head_t</type>, and then processes which want to   wait for that condition declare a <type>wait_queue_t</type>   referring to themselves, and place that in the queue.  </para>  <sect1 id="queue-declaring">   <title>Declaring</title>      <para>    You declare a <type>wait_queue_head_t</type> using the    <function>DECLARE_WAIT_QUEUE_HEAD()</function> macro, or using the    <function>init_waitqueue_head()</function> routine in your    initialization code.   </para>  </sect1>    <sect1 id="queue-waitqueue">   <title>Queuing</title>      <para>    Placing yourself in the waitqueue is fairly complex, because you    must put yourself in the queue before checking the condition.    There is a macro to do this:    <function>wait_event_interruptible()</function>    <filename class=headerfile>include/linux/sched.h</filename> The    first argument is the wait queue head, and the second is an    expression which is evaluated; the macro returns    <returnvalue>0</returnvalue> when this expression is true, or    <returnvalue>-ERESTARTSYS</returnvalue> if a signal is received.    The <function>wait_event()</function> version ignores signals.   </para>   <para>   Do not use the <function>sleep_on()</function> function family -   it is very easy to accidentally introduce races; almost certainly   one of the <function>wait_event()</function> family will do, or a   loop around <function>schedule_timeout()</function>. If you choose   to loop around <function>schedule_timeout()</function> remember   you must set the task state (with    <function>set_current_state()</function>) on each iteration to avoid   busy-looping.   </para>   </sect1>  <sect1 id="queue-waking">   <title>Waking Up Queued Tasks</title>      <para>    Call <function>wake_up()</function>    <filename class=headerfile>include/linux/sched.h</filename>;,    which will wake up every process in the queue.  The exception is    if one has <constant>TASK_EXCLUSIVE</constant> set, in which case    the remainder of the queue will not be woken.   </para>  </sect1> </chapter> <chapter id="atomic-ops">  <title>Atomic Operations</title>  <para>   Certain operations are guaranteed atomic on all platforms.  The   first class of operations work on <type>atomic_t</type>   <filename class=headerfile>include/asm/atomic.h</filename>; this   contains a signed integer (at least 24 bits long), and you must use   these functions to manipulate or read atomic_t variables.   <function>atomic_read()</function> and   <function>atomic_set()</function> get and set the counter,   <function>atomic_add()</function>,   <function>atomic_sub()</function>,   <function>atomic_inc()</function>,   <function>atomic_dec()</function>, and   <function>atomic_dec_and_test()</function> (returns   <returnvalue>true</returnvalue> if it was decremented to zero).  </para>  <para>   Yes.  It returns <returnvalue>true</returnvalue> (i.e. != 0) if the   atomic variable is zero.  </para>  <para>   Note that these functions are slower than normal arithmetic, and   so should not be used unnecessarily.  On some platforms they   are much slower, like 32-bit Sparc where they use a spinlock.  </para>  <para>   The second class of atomic operations is atomic bit operations on a   <type>long</type>, defined in   <filename class=headerfile>include/asm/bitops.h</filename>.  These   operations generally take a pointer to the bit pattern, and a bit   number: 0 is the least significant bit.   <function>set_bit()</function>, <function>clear_bit()</function>   and <function>change_bit()</function> set, clear, and flip the   given bit.  <function>test_and_set_bit()</function>,   <function>test_and_clear_bit()</function> and   <function>test_and_change_bit()</function> do the same thing,   except return true if the bit was previously set; these are   particularly useful for very simple locking.  </para>    <para>   It is possible to call these operations with bit indices greater   than BITS_PER_LONG.  The resulting behavior is strange on big-endian   platforms though so it is a good idea not to do this.  </para>  <para>   Note that the order of bits depends on the architecture, and in   particular, the bitfield passed to these operations must be at   least as large as a <type>long</type>.  </para> </chapter> <chapter id="symbols">  <title>Symbols</title>  <para>   Within the kernel proper, the normal linking rules apply   (ie. unless a symbol is declared to be file scope with the   <type>static</type> keyword, it can be used anywhere in the   kernel).  However, for modules, a special exported symbol table is   kept which limits the entry points to the kernel proper.  Modules   can also export symbols.  </para>  <sect1 id="sym-exportsymbols">   <title><function>EXPORT_SYMBOL()</function>    <filename class=headerfile>include/linux/module.h</filename></title>   <para>    This is the classic method of exporting a symbol, and it works    for both modules and non-modules.  In the kernel all these    declarations are often bundled into a single file to help    genksyms (which searches source files for these declarations).    See the comment on genksyms and Makefiles below.   </para>  </sect1>  <sect1 id="sym-exportnosymbols">   <title><symbol>EXPORT_NO_SYMBOLS</symbol>    <filename class=headerfile>include/linux/module.h</filename></title>   <para>    If a module exports no symbols then you can specify    <programlisting>EXPORT_NO_SYMBOLS;    </programlisting>    anywhere in the module.    In kernel 2.4 and earlier, if a module contains neither    <function>EXPORT_SYMBOL()</function> nor    <symbol>EXPORT_NO_SYMBOLS</symbol> then the module defaults to    exporting all non-static global symbols.    In kernel 2.5 onwards you must explicitly specify whether a module    exports symbols or not.   </para>  </sect1>  <sect1 id="sym-exportsymbols-gpl">   <title><function>EXPORT_SYMBOL_GPL()</function>    <filename class=headerfile>include/linux/module.h</filename></title>   <para>    Similar to <function>EXPORT_SYMBOL()</function> except that the    symbols exported by <function>EXPORT_SYMBOL_GPL()</function> can    only be seen by modules with a    <function>MODULE_LICENCE()</function> that specifies a GPL    compatible license.   </para>  </sect1> </chapter> <chapter id="conventions">  <title>Routines and Conventions</title>  <sect1 id="conventions-doublelinkedlist">   <title>Double-linked lists    <filename class=headerfile>include/linux/list.h</filename></title>   <para>    There are three sets of linked-list routines in the kernel    headers, but this one seems to be winning out (and Linus has    used it).  If you don't have some particular pressing need for    a single list, it's a good choice.  In fact, I don't care    whether it's a good choice or not, just use it so we can get    rid of the others.   </para>  </sect1>  <sect1 id="convention-returns">   <title>Return Conventions</title>   <para>    For code called in user context, it's very common to defy C    convention, and return <returnvalue>0</returnvalue> for success,    and a negative error number    (eg. <returnvalue>-EFAULT</returnvalue>) for failure.  This can be    unintuitive at first, but it's fairly widespread in the networking    code, for example.   </para>   <para>    The filesystem code uses <function>ERR_PTR()</function>    <filename class=headerfile>include/linux/fs.h</filename>; to    encode a negative error number into a pointer, and    <function>IS_ERR()</function> and <function>PTR_ERR()</function>    to get it back out again: avoids a separate pointer parameter for    the error number.  Icky, but in a good way.   </para>  </sect1>  <sect1 id="conventions-borkedcompile">   <title>Breaking Compilation</title>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -