外部世界的Linux内核接口定义良好(370多个系统调用,手册页等)。但是,是否有内部内核接口(内核子系统或设备驱动程序之间)的概述?
有一个 In-kernel API here部分,但它提供的信息很少。
这是一个很好的内部内核组织地图:
但是这些内核组件的交互呢?和他们和其他设备驱动程序之间的交互?
答案 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)