内部Linux内核接口

时间:2014-12-30 09:54:59

标签: linux kernel linux-device-driver

外部世界的Linux内核接口定义良好(370多个系统调用,手册页等)。但是,是否有内部内核接口(内核子系统或设备驱动程序之间)的概述?

有一个 In-kernel API here部分,但它提供的信息很少。

这是一个很好的内部内核组织地图:

enter image description here

但是这些内核组件的交互呢?和他们和其他设备驱动程序之间的交互?

2 个答案:

答案 0 :(得分:5)

您最好的选择是源代码中的内核文档。下载源存档或从https://www.kernel.org/签出git存储库。然后在文件目录下有很多文件,或者使用' make htmldocs'用于html导航。它也托管在互联网上的几个网站上,例如https://www.kernel.org/doc/

答案 1 :(得分:0)

源代码中找到的一些接口(内核版本3.18.1):(源代码几乎逐字逐句,除了外观更改;对于内联函数和宏,我没有复制它们的正文)(这是不完整的答案 - 这意味着只是一瞥大量的内核内部接口函数。我将逐渐添加一些选定的接口,因为我通过内核)

同步和工作流并发

旋转锁定

(来自档案 include/linux/spinlock.h

static inline void spin_lock(spinlock_t *lock)
static inline void spin_lock_bh(spinlock_t *lock)
static inline int spin_trylock(spinlock_t *lock)
static inline void spin_lock_irq(spinlock_t *lock)
static inline void spin_unlock(spinlock_t *lock)
static inline void spin_unlock_bh(spinlock_t *lock)
static inline void spin_unlock_irq(spinlock_t *lock)
static inline void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
static inline int spin_trylock_bh(spinlock_t *lock)
static inline int spin_trylock_irq(spinlock_t *lock)
static inline void spin_unlock_wait(spinlock_t *lock)
static inline int spin_is_locked(spinlock_t *lock)
static inline int spin_is_contended(spinlock_t *lock)
static inline int spin_can_lock(spinlock_t *lock)

信号灯

(来自档案 include/linux/semaphore.h

static inline void sema_init(struct semaphore *sem, int val);
extern void down(struct semaphore *sem);
extern int __must_check down_interruptible(struct semaphore *sem);
extern int __must_check down_killable(struct semaphore *sem);
extern int __must_check down_trylock(struct semaphore *sem);
extern int __must_check down_timeout(struct semaphore *sem, long jiffies);
extern void up(struct semaphore *sem);

达成

(来自档案 include/linux/completion.h

static inline void init_completion(struct completion *x)
static inline void reinit_completion(struct completion *x)
extern void wait_for_completion(struct completion *);
extern void wait_for_completion_io(struct completion *);
extern int wait_for_completion_interruptible(struct completion *x);
extern int wait_for_completion_killable(struct completion *x);
extern unsigned long wait_for_completion_timeout(struct completion *x, unsigned long timeout);
extern unsigned long wait_for_completion_io_timeout(struct completion *x, unsigned long timeout);
extern long wait_for_completion_interruptible_timeout(struct completion *x, unsigned long timeout);
extern long wait_for_completion_killable_timeout(struct completion *x, unsigned long timeout);
extern bool try_wait_for_completion(struct completion *x);
extern bool completion_done(struct completion *x);
extern void complete(struct completion *);
extern void complete_all(struct completion *);

处理中断

硬件中断

(来自档案 include/linux/hardirq.h

extern void synchronize_irq(unsigned int irq);
extern void synchronize_hardirq(unsigned int irq);
extern void rcu_nmi_enter(void);
extern void rcu_nmi_exit(void);
#define __irq_enter()                   \
extern void irq_enter(void);
#define __irq_exit()                    \
extern void irq_exit(void);
#define nmi_enter()                     \
#define nmi_exit()                      \

(来自档案 include/linux/interrupt.h

extern irqreturn_t no_action(int cpl, void *dev_id);
extern int __must_check
request_threaded_irq(unsigned int irq, irq_handler_t handler,
             irq_handler_t thread_fn,
             unsigned long flags, const char *name, void *dev);
static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
        const char *name, void *dev)
extern int __must_check
request_any_context_irq(unsigned int irq, irq_handler_t handler,
            unsigned long flags, const char *name, void *dev_id);
extern int __must_check
request_percpu_irq(unsigned int irq, irq_handler_t handler,
           const char *devname, void __percpu *percpu_dev_id);
extern void free_irq(unsigned int, void *);
extern void free_percpu_irq(unsigned int, void __percpu *);
extern int __must_check
devm_request_threaded_irq(struct device *dev, unsigned int irq,
              irq_handler_t handler, irq_handler_t thread_fn,
              unsigned long irqflags, const char *devname,
              void *dev_id);
static inline int __must_check
devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler,
         unsigned long irqflags, const char *devname, void *dev_id)
extern int __must_check
devm_request_any_context_irq(struct device *dev, unsigned int irq,
         irq_handler_t handler, unsigned long irqflags,
         const char *devname, void *dev_id);
extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id);
# define local_irq_enable_in_hardirq() \
extern void disable_irq_nosync(unsigned int irq);
extern void disable_irq(unsigned int irq);
extern void disable_percpu_irq(unsigned int irq);
extern void enable_irq(unsigned int irq);
extern void enable_percpu_irq(unsigned int irq, unsigned int type);
extern void irq_wake_thread(unsigned int irq, void *dev_id);
extern void suspend_device_irqs(void);
extern void resume_device_irqs(void);
extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask, bool force);
static inline int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
static inline int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
extern int irq_can_set_affinity(unsigned int irq);
extern int irq_select_affinity(unsigned int irq);
extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m);
extern int irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify);
static inline void disable_irq_nosync_lockdep(unsigned int irq)
static inline void disable_irq_nosync_lockdep_irqsave(unsigned int irq, unsigned long *flags)
static inline void disable_irq_lockdep(unsigned int irq)
static inline void enable_irq_lockdep(unsigned int irq)
static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long *flags)
extern int irq_set_irq_wake(unsigned int irq, unsigned int on);
static inline int enable_irq_wake(unsigned int irq)
static inline int disable_irq_wake(unsigned int irq)
#define set_softirq_pending(x) (local_softirq_pending() = (x))
#define or_softirq_pending(x)  (local_softirq_pending() |= (x))
#define hard_irq_disable()  do { } while(0)
asmlinkage void do_softirq(void);
asmlinkage void __do_softirq(void);
void do_softirq_own_stack(void);
extern void open_softirq(int nr, void (*action)(struct softirq_action *));
extern void softirq_init(void);
extern void __raise_softirq_irqoff(unsigned int nr);
extern void raise_softirq_irqoff(unsigned int nr);
extern void raise_softirq(unsigned int nr);
static inline struct task_struct *this_cpu_ksoftirqd(void)
extern unsigned long probe_irq_on(void);    /* returns 0 on failure */
extern int probe_irq_off(unsigned long);    /* returns 0 or negative on failure */
extern unsigned int probe_irq_mask(unsigned long);  /* returns mask of ISA interrupts */
extern void init_irq_proc(void);
int show_interrupts(struct seq_file *p, void *v);
int arch_show_interrupts(struct seq_file *p, int prec);
extern int early_irq_init(void);
extern int arch_probe_nr_irqs(void);
extern int arch_early_irq_init(void);

常用例程和帮助程序宏

各种助手宏

(来自档案 include/asm-generic/bug.h arch/<architecture>/include/asm/bug.h

#define BUG()
#define BUG_ON(<condition>)

用户空间内存访问

(来自档案 arch/<architecture>/include/asm/uaccess.h

#define MAKE_MM_SEG(s)  ((mm_segment_t) { (s) })
#define KERNEL_DS   MAKE_MM_SEG(-1UL)
#define USER_DS     MAKE_MM_SEG(TASK_SIZE_MAX)
#define get_ds()    (KERNEL_DS)
#define get_fs()    (current_thread_info()->addr_limit)
#define set_fs(x)   (current_thread_info()->addr_limit = (x))
#define segment_eq(a, b)    ((a).seg == (b).seg)
#define user_addr_max() (current_thread_info()->addr_limit.seg)
#define __addr_ok(addr)     \
static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, unsigned long limit)
#define __range_not_ok(addr, size, limit)               \
#define access_ok(type, addr, size) \
extern int fixup_exception(struct pt_regs *regs);
extern int early_fixup_exception(unsigned long *ip);
extern int __get_user_1(void);
extern int __get_user_2(void);
extern int __get_user_4(void);
extern int __get_user_8(void);
extern int __get_user_bad(void);
#define __inttype(x) \
#define get_user(x, ptr)                        \
#define __put_user_x(size, x, ptr, __ret_pu)            \
#define __put_user_asm_u64(x, addr, err, errret)            \
#define __put_user_asm_ex_u64(x, addr)                  \
#define __put_user_x8(x, ptr, __ret_pu)             \
#define __put_user_asm_u64(x, ptr, retval, errret) \
#define __put_user_asm_ex_u64(x, addr)  \
#define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu)
extern void __put_user_bad(void);
extern void __put_user_1(void);
extern void __put_user_2(void);
extern void __put_user_4(void);
extern void __put_user_8(void);
#define put_user(x, ptr)                    \
#define __put_user_size(x, ptr, size, retval, errret)           \
#define __put_user_size_ex(x, ptr, size)                \
#define __get_user_asm_u64(x, ptr, retval, errret)  (x) = __get_user_bad()
#define __get_user_asm_ex_u64(x, ptr)           (x) = __get_user_bad()
#define __get_user_size(x, ptr, size, retval, errret)           \
#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)   \
#define __get_user_size_ex(x, ptr, size)                \
#define __get_user_asm_ex(x, addr, itype, rtype, ltype)         \
#define __put_user_nocheck(x, ptr, size)            \
#define __get_user_nocheck(x, ptr, size)                \
#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)   \
#define __put_user_asm_ex(x, addr, itype, rtype, ltype)         \
#define uaccess_try do {                        \
#define uaccess_catch(err)                      \
#define __get_user(x, ptr)                      \
#define __put_user(x, ptr)                      \
#define __get_user_unaligned __get_user
#define __put_user_unaligned __put_user
#define get_user_try        uaccess_try
#define get_user_catch(err) uaccess_catch(err)
#define get_user_ex(x, ptr) do {                    \
#define put_user_try        uaccess_try
#define put_user_catch(err) uaccess_catch(err)
#define put_user_ex(x, ptr)                     \
extern unsigned long copy_from_user_nmi(void *to, const void __user *from, unsigned long n);
extern __must_check long strncpy_from_user(char *dst, const char __user *src, long count);
extern __must_check long strlen_user(const char __user *str);
extern __must_check long strnlen_user(const char __user *str, long n);
unsigned long __must_check clear_user(void __user *mem, unsigned long len);
unsigned long __must_check __clear_user(void __user *mem, unsigned long len);
#define __user_atomic_cmpxchg_inatomic(uval, ptr, old, new, size)   \
#define user_atomic_cmpxchg_inatomic(uval, ptr, old, new)       \
unsigned long __must_check _copy_from_user(void *to, const void __user *from, unsigned n);
unsigned long __must_check _copy_to_user(void __user *to, const void *from, unsigned n);
static inline void __copy_from_user_overflow(int size, unsigned long count)
static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)