µ±Ç°Î»ÖãºLinux½Ì³Ì - Linux×ÊѶ - Äں˲Ù×÷ Linux2.6ÄÚºËÇý¶¯ÒÆÖ²²Î¿¼

Äں˲Ù×÷ Linux2.6ÄÚºËÇý¶¯ÒÆÖ²²Î¿¼

¡¡¡¡Ëæ×ÅLinux2.6µÄ·¢²¼£¬ÓÉÓÚ2.6ÄÚºË×öÁ˽̵ĸĶ¯£¬¸÷¸öÉ豸µÄÇý¶¯³ÌÐòÔÚ²»Í¬³Ì¶ÈÉÏÒª½øÐиÄд¡£ÎªÁË·½±ã¸÷λLinux°®ºÃÕßÎÒ°Ñ×Ô¼ºÕûÀíµÄÕâ·ÖÎĵµshare³öÀ´¡£¸ÃÎĵ±ÁоÙÁË2.6ÄÚºËͬÒÔÇ°°æ±¾µÄ¾ø´ó¶àÊý±ä»¯£¬¿ÉϧµÄÊÇÓÉÓÚʱ¼äºÍ¾«Á¦ÓÐÏÞûÓÐÏêϸÁгö¸÷¸öº¯ÊýµÄÓ÷¨¡£

¡¡¡¡ÌرðÉùÃ÷£º¸ÃÎĵµÖеÄÄÚÈÝÀ´×Ôhttp://lwn.net£¬¸ÃÍøÒ²ÉÏÒ²Óи÷¸öº¯ÊýµÄ½ÏΪÏêϸµÄ˵Ã÷¿É¹©¸÷λ²Î¿¼¡£

¡¡¡¡1¡¢Ê¹ÓÃеÄÈë¿Ú

¡¡¡¡±ØÐë°üº¬ £¼linux/init.h£¾

¡¡¡¡module_init(your_init_func);

¡¡¡¡module_exit(your_exit_func);

¡¡¡¡ÀÏ°æ±¾£ºint init_module(void);

¡¡¡¡void cleanup_module(voi);

¡¡¡¡2.4ÖÐÁ½ÖÖ¶¼¿ÉÒÔÓ㬶ÔÈçºóÃæµÄÈë¿Úº¯Êý²»±ØÒªÏÔʾ°üº¬ÈκÎÍ·Îļþ¡£

¡¡¡¡2¡¢GPL

¡¡¡¡MODULE_LICENSE("Dual BSD/GPL");

¡¡¡¡ÀÏ°æ±¾£ºMODULE_LICENSE("GPL");

¡¡¡¡3¡¢Ä£¿é²ÎÊý

¡¡¡¡±ØÐëÏÔʽ°üº¬£¼linux/moduleparam.h£¾

¡¡¡¡module_param(name, type, perm);

¡¡¡¡module_param_named(name, value, type, perm);

¡¡¡¡²ÎÊý¶¨Òå

¡¡¡¡module_param_string(name, string, len, perm);

¡¡¡¡module_param_array(name, type, num, perm);

¡¡¡¡ÀÏ°æ±¾£ºMODULE_PARM(variable,type);

¡¡¡¡MODULE_PARM_DESC(variable,type);

¡¡¡¡4¡¢Ä£¿é±ðÃû

¡¡¡¡MODULE_ALIAS("alias-name");

¡¡¡¡ÕâÊÇÐÂÔöµÄ£¬ÔÚÀÏ°æ±¾ÖÐÐèÔÚ/etc/modules.confÅäÖã¬ÏÖÔÚÔÚ´úÂëÖоͿÉÒÔʵÏÖ¡£

¡¡¡¡5¡¢Ä£¿é¼ÆÊý

¡¡¡¡int try_module_get(&module);

¡¡¡¡module_put();

¡¡¡¡ÀÏ°æ±¾£ºMOD_INC_USE_COUNT ºÍ MOD_DEC_USE_COUNT

¡¡¡¡6¡¢·ûºÅµ¼³ö

¡¡¡¡Ö»ÓÐÏÔʾµÄµ¼³ö·ûºÅ²ÅÄܱ»ÆäËûÄ£¿éʹÓã¬Ä¬Èϲ»µ¼³öËùÓеķûºÅ£¬²»±ØʹÓÃEXPORT_NO_SYMBOLS

¡¡¡¡ÀÏ°å±¾£ºÄ¬Èϵ¼³öËùÓеķûºÅ£¬³ý·ÇʹÓÃEXPORT_NO_SYMBOLS

¡¡¡¡7¡¢Äں˰汾¼ì²é

¡¡¡¡ÐèÒªÔÚ¶à¸öÎļþÖаüº¬£¼linux/module.h£¾Ê±£¬²»±Ø¶¨Òå__NO_VERSION__

¡¡¡¡ÀÏ°æ±¾£ºÔÚ¶à¸öÎļþÖаüº¬£¼linux/module.h£¾Ê±£¬³ýÔÚÖ÷ÎļþÍâµÄÆäËûÎļþÖбØÐ붨Òå__NO_VERSION__£¬·ÀÖ¹°æ±¾Öظ´¶¨Òå¡£

¡¡¡¡8¡¢É豸ºÅ

¡¡¡¡kdev_t±»·Ï³ý²»¿ÉÓã¬ÐµÄdev_tÍØÕ¹µ½ÁË32룬12λÖ÷É豸ºÅ£¬20λ´ÎÉ豸ºÅ¡£

¡¡¡¡unsigned int iminor(strUCt inode *inode);

¡¡¡¡unsigned int imajor(struct inode *inode);

¡¡¡¡ÀÏ°æ±¾£º8λÖ÷É豸ºÅ£¬8λ´ÎÉ豸ºÅ

¡¡¡¡int MAJOR(kdev_t dev);

¡¡¡¡int MINOR(kdev_t dev);

¡¡¡¡9¡¢ÄÚ´æ·ÖÅäÍ·Îļþ±ä¸ü

¡¡¡¡ËùÓеÄÄÚ´æ·ÖÅ亯Êý°üº¬ÔÚÍ·Îļþ£¼linux/slab.h£¾£¬¶øÔ­À´µÄ£¼linux/malloc.h£¾²»´æÔÚ

¡¡¡¡ÀÏ°æ±¾£ºÄÚ´æ·ÖÅ亯Êý°üº¬ÔÚÍ·Îļþ£¼linux/malloc.h£¾

¡¡¡¡10¡¢½á¹¹ÌåµÄ³õÊÔ»¯

¡¡¡¡gcc¿ªÊ¼²ÉÓÃANSI CµÄstruct½á¹¹ÌåµÄ³õʼ»¯ÐÎʽ£º

¡¡¡¡static struct some_structure = {

¡¡¡¡.field1 = value,

¡¡¡¡.field2 = value,

¡¡¡¡..

¡¡¡¡};

¡¡¡¡ÀÏ°æ±¾£º·Ç±ê×¼µÄ³õÊÔ»¯ÐÎʽ

¡¡¡¡static struct some_structure = {

¡¡¡¡field1: value,

¡¡¡¡field2: value,

¡¡¡¡..

¡¡¡¡};

¡¡¡¡11¡¢Óû§Ä£Ê½°ïÖúÆ÷

¡¡¡¡int call_usermodehelper(char *path, char **argv, char **envp,int wait);

¡¡¡¡ÐÂÔöwait²ÎÊý

¡¡¡¡12¡¢request_module()

¡¡¡¡request_module("foo-device-%d", number);

¡¡¡¡ÀÏ°æ±¾£º

¡¡¡¡char module_name[32];

¡¡¡¡printf(module_name, "foo-device-%d", number);

¡¡¡¡request_module(module_name);


[1] [2] [3] ÏÂÒ»Ò³ 

¡¡¡¡13¡¢dev_tÒý·¢µÄ×Ö·ûÉ豸µÄ±ä»¯

¡¡¡¡1¡¢È¡Ö÷´ÎÉ豸ºÅΪ

¡¡¡¡unsigned iminor(struct inode *inode);

¡¡¡¡unsigned imajor(struct inode *inode);

¡¡¡¡2¡¢ÀϵÄregister_chrdev()Ó÷¨Ã»±ä£¬±£³ÖÏòºó¼æÈÝ£¬µ«²»ÄÜ·ÃÎÊÉ豸ºÅ´óÓÚ256µÄÉ豸¡£

¡¡¡¡3¡¢ÐµĽӿÚΪ

¡¡¡¡a)×¢²á×Ö·ûÉ豸·¶Î§

¡¡¡¡int register_chrdev_region(dev_t from, unsigned count, char *name);

¡¡¡¡b)¶¯Ì¬ÉêÇëÖ÷É豸ºÅ

¡¡¡¡int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, char

¡¡¡¡*name);

¡¡¡¡¿´ÁËÕâÁ½¸öº¯ÊýÓôÃÆ°É^_^£¡ÔõôºÍfile_operations½á¹¹ÁªÏµÆðÀ´°¡£¿±ð¼±£¡

¡¡¡¡c)°üº¬ £¼linux/cdev.h£¾£¬ÀûÓÃstruct cdevºÍfile_operationsÁ¬½Ó

¡¡¡¡struct cdev *cdev_alloc(void);

¡¡¡¡void cdev_init(struct cdev *cdev, struct file_operations *fops);

¡¡¡¡int cdev_add(struct cdev *cdev, dev_t dev, unsigned count);

¡¡¡¡£¨·Ö±ðΪ£¬ÉêÇëcdev½á¹¹£¬ºÍfopsÁ¬½Ó£¬½«É豸¼ÓÈ뵽ϵͳÖУ¡ºÃ¸´ÔÓ°¡£¡£©

¡¡¡¡d)void cdev_del(struct cdev *cdev);

¡¡¡¡Ö»ÓÐÔÚcdev_addÖ´Ðгɹ¦²Å¿ÉÔËÐС£

¡¡¡¡e)¸¨Öúº¯Êý

¡¡¡¡kobject_put(&cdev-£¾kobj);

¡¡¡¡struct kobject *cdev_get(struct cdev *cdev);

¡¡¡¡void cdev_put(struct cdev *cdev);

¡¡¡¡ÕâÒ»²¿·Ö±ä»¯ºÍÐÂÔöµÄ/sys/devÓÐÒ»¶¨µÄ¹ØÁª¡£

¡¡¡¡14¡¢ÐÂÔö¶Ô/procµÄ·ÃÎʲÙ×÷

¡¡¡¡£¼linux/seq_file.h£¾

¡¡¡¡ÒÔÇ°µÄ/procÖÐÖ»Äܵõ½string, seq_file²Ù×÷Äܵõ½ÈçlongµÈ¶àÖÖÊý¾Ý¡£

¡¡¡¡Ïà¹Øº¯Êý£º

¡¡¡¡static struct seq_operations ±ØÐëʵÏÖÕâ¸öÀàËÆfile_operationsµÃÊý¾ÝÖеø÷¸ö³É

¡¡¡¡Ô±º¯Êý¡£

¡¡¡¡seq_printf()£»

¡¡¡¡int seq_putc(struct seq_file *m, char c);

¡¡¡¡int seq_puts(struct seq_file *m, const char *s);

¡¡¡¡int seq_escape(struct seq_file *m, const char *s, const char *esc);

¡¡¡¡int seq_path(struct seq_file *m, struct vfsmount *mnt,

¡¡¡¡struct dentry *dentry, char *esc);

¡¡¡¡seq_open(file, &ct_seq_ops);

¡¡¡¡µÈµÈ

¡¡¡¡15¡¢µ×²ãÄÚ´æ·ÖÅä

¡¡¡¡1¡¢£¼linux/malloc.h£¾Í·Îļþ¸ÄΪ£¼linux/slab.h£¾

¡¡¡¡2¡¢·ÖÅä±êÖ¾GFP_BUFFER±»È¡Ïû£¬È¡¶ø´úÖ®µÄÊÇGFP_NOIO ºÍ GFP_NOFS

¡¡¡¡3¡¢ÐÂÔö__GFP_REPEAT£¬__GFP_NOFAIL£¬__GFP_NORETRY·ÖÅä±êÖ¾

¡¡¡¡4¡¢Ò³Ãæ·ÖÅ亯Êýalloc_pages()£¬get_free_page()±»°üº¬ÔÚ£¼linux/gfp.h£¾ÖÐ

¡¡¡¡5¡¢¶ÔNUMAϵͳÐÂÔöÁ˼¸¸öº¯Êý£º

¡¡¡¡a) struct page *alloc_pages_node(int node_id,

¡¡¡¡unsigned int gfp_mask,

¡¡¡¡unsigned int order);

¡¡¡¡b) void free_hot_page(struct page *page);

¡¡¡¡c) void free_cold_page(struct page *page);

¡¡¡¡6¡¢ ÐÂÔöMemory pools

¡¡¡¡£¼linux/mempool.h£¾

¡¡¡¡mempool_t *mempool_create(int min_nr,

¡¡¡¡mempool_alloc_t *alloc_fn,

¡¡¡¡mempool_free_t *free_fn,

¡¡¡¡void *pool_data);

¡¡¡¡void *mempool_alloc(mempool_t *pool, int gfp_mask);

¡¡¡¡void mempool_free(void *element, mempool_t *pool);

¡¡¡¡int mempool_resize(mempool_t *pool, int new_min_nr, int gfp_mask);

¡¡¡¡16¡¢ per-CPU±äÁ¿

¡¡¡¡get_cpu_var();

¡¡¡¡put_cpu_var();

¡¡¡¡void *alloc_percpu(type);

¡¡¡¡void free_percpu(const void *);

¡¡¡¡per_cpu_ptr(void *ptr, int cpu)

¡¡¡¡get_cpu_ptr(ptr)

¡¡¡¡put_cpu_ptr(ptr)

¡¡¡¡Àϰ汾ʹÓÃ

¡¡¡¡DEFINE_PER_CPU(type, name);


ÉÏÒ»Ò³ [1] [2] [3] ÏÂÒ»Ò³ 

¡¡¡¡EXPORT_PER_CPU_SYMBOL(name);

¡¡¡¡EXPORT_PER_CPU_SYMBOL_GPL(name);

¡¡¡¡DECLARE_PER_CPU(type, name);

¡¡¡¡DEFINE_PER_CPU(int, mypcint);

¡¡¡¡2.6Äں˲ÉÓÃÁË¿É°þ¶áµÃµ÷¶È·½Ê½ÕâЩºê¶¼²»°²È«¡£

¡¡¡¡17¡¢ÄÚºËʱ¼ä±ä»¯

¡¡¡¡1¡¢ÏÖÔڵĸ÷¸öƽ̨µÄHZΪ

¡¡¡¡Alpha: 1024/1200; ARM: 100/128/200/1000; CRIS: 100; i386: 1000; IA-64:

¡¡¡¡1024; M68K: 100; M68K-nommu: 50-1000; MIPS: 100/128/1000; MIPS64: 100;

¡¡¡¡PA-RISC: 100/1000; PowerPC32: 100; PowerPC64: 1000; S/390: 100; SPARC32:

¡¡¡¡100; SPARC64: 100; SuperH: 100/1000; UML: 100; v850: 24-100; x86-64: 1000.

¡¡¡¡2¡¢ÓÉÓÚHZµÄ±ä»¯£¬Ô­À´µÄjiffies¼ÆÊýÆ÷ºÜ¿ì¾ÍÒç³öÁË£¬ÒýÈëÁËеļÆÊýÆ÷jiffies_64

¡¡¡¡3¡¢#include £¼linux/jiffies.h£¾

¡¡¡¡u64 my_time = get_jiffies_64();

¡¡¡¡4¡¢ÐµÄʱ¼ä½á¹¹Ôö¼ÓÁËÄÉÃë³ÉÔ±±äÁ¿

¡¡¡¡struct timespec current_kernel_time(void);

¡¡¡¡5¡¢ËûµÄtimerº¯Êýû±ä£¬ÐÂÔö

¡¡¡¡void add_timer_on(struct timer_list *timer, int cpu);

¡¡¡¡6¡¢ÐÂÔöÄÉÃ뼶ÑÓʱº¯Êý

¡¡¡¡ndelay()£»

¡¡¡¡7¡¢POSIX clocks ²Î¿¼kernel/posix-timers.c

¡¡¡¡18¡¢¹¤×÷¶ÓÁУ¨workqueue£©

¡¡¡¡1¡¢ÈÎÎñ¶ÓÁУ¨task queue £©½Ó¿Úº¯Êý¶¼±»È¡Ïû£¬ÐÂÔöÁËworkqueue½Ó¿Úº¯Êý

¡¡¡¡struct workqueue_struct *create_workqueue(const char *name);

¡¡¡¡DECLARE_WORK(name, void (*function)(void *), void *data);

¡¡¡¡INIT_WORK(struct work_struct *work,

¡¡¡¡void (*function)(void *), void *data);

¡¡¡¡PREPARE_WORK(struct work_struct *work,

¡¡¡¡void (*function)(void *), void *data);

¡¡¡¡2¡¢ÉêÃ÷struct work_struct½á¹¹

¡¡¡¡int queue_work(struct workqueue_struct *queue,

¡¡¡¡struct work_struct *work);

¡¡¡¡int queue_delayed_work(struct workqueue_struct *queue,

¡¡¡¡struct work_struct *work,

¡¡¡¡unsigned long delay);

¡¡¡¡int cancel_delayed_work(struct work_struct *work);

¡¡¡¡void flush_workqueue(struct workqueue_struct *queue);

¡¡¡¡void destroy_workqueue(struct workqueue_struct *queue);

¡¡¡¡int schedule_work(struct work_struct *work);

¡¡¡¡int schedule_delayed_work(struct work_struct *work, unsigned long

¡¡¡¡delay);

£¨³ö´¦£ºhttp://www.sheup.com£©


ÉÏÒ»Ò³ [1] [2] [3] 

¡¡¡¡int queue_work(struct workqueue_struct *queue,

¡¡¡¡struct work_struct *work);

¡¡¡¡int queue_delayed_work(struct workqueue_struct *queue,

¡¡¡¡struct work_struct *work,

¡¡¡¡unsigned long delay);

¡¡¡¡int cancel_delayed_work(struct work_struct *work);

¡¡¡¡void flush_workqueue(struct workqueue_struct *queue);

¡¡¡¡void destroy_workqueue(struct workqueue_struct *queue);

¡¡¡¡int schedule_work(struct work_struct *work);

¡¡¡¡int schedule_delayed_work(struct work_struct *work, unsigned long

¡¡¡¡delay);

£¨³ö´¦£ºhttp://www.sheup.com£©


ÉÏÒ»Ò³ [1] [2] [3] [4]