Document directory
- "Porting the Module Program of Linux Device Driver II on Linux kernel 2.6.x" Project
- "Porting the Module Program of Linux Device Driver II on Linux kernel 2.6.x" Project
"Porting the Module Program of Linux Device Driver II on Linux kernel 2.6.x" Project
----- Linux-2.6.x Device Driver scull -----
It is very simple. Hehe.
You just type:
Insmod scull. Ko
./Scull_user
Early, I want to modified deeply, but I think we just can learn linux-2.6
. X interface, that is all.
If you want to run the programming, you must recompile the Linux 2.6.x K
Ernel, add devfs support, Mount devfs and sysfs.
The result is:
1.
[Caolingzi @ localhost caolingzi] $ CAT/proc/version
Linux version 2.6.10 (root@localhost.localdomain) (GCC version 3.2.2 20030222 (R
Ed Hat Linux 3.2.2-5) #6 sat Feb 19 11:58:16 CST 2005
2.
[Caolingzi @ localhost caolingzi] $ ls/sys/module/scull/
Refcnt sections
3.
[Caolingzi @ localhost caolingzi] $ ls/devfs/scull/
0
4.
[Caolingzi @ localhost caolingzi] $ CAT/proc/devices
...
180 USB
253 scull
254 devfs
...
5.
[Root @ localhost scull_user] #./scull_user
Hello, Kernel-2.6.10_scull!
OK, good lucky!
2005.2.21
CaolingziPosted
"Porting the Module Program of Linux Device Driver II on Linux kernel 2.6.x" Project
Linux Kernel Driver porting
Author: Ji weichuan
With the release of linux2.6, the driver of each device needs to be rewritten to varying degrees due to the modifications made to the 2.6 kernel. To facilitate Linux fans, I will share this article. This article lists the vast majority of changes in the 2.6 kernel compared with previous versions. Unfortunately, due to limited time and energy, the usage of each function is not listed in detail.
Special statement: the content of this document from the http://lwn.net, the network also has a more detailed description of each function for your reference. If you need the word version of this document, please mail to the weiriver@sohu.com.
1. Use a new portal
Must contain <Linux/init. h>
Module_init (your_init_func );
Module_exit (your_exit_func );
Old Version: int init_module (void );
Void cleanup_module (voi );
2.4 can be used in both cases. For example, you do not need to display any header files for the entry function.
2. GPL
Module_license ("dual BSD/GPL ");
Old Version: module_license ("GPL ");
3. Module Parameters
Must explicitly include <Linux/moduleparam. h>
Module_param (name, type, Perm );
Module_param_named (name, value, type, Perm );
Parameter Definition
Module_param_string (name, String, Len, Perm );
Module_param_array (name, type, num, Perm );
Old Version: module_parm (variable, type );
Module_parm_desc (variable, type );
4. Module alias
Module_alias ("alias-name ");
This is newly added. In the old version, you need to configure in/etc/modules. conf, which can be implemented in the code now.
5. Module count
Int try_module_get (& module );
Module_put ();
Earlier versions: mod_inc_use_count and mod_dec_use_count
6. Export symbols
Only the displayed exported symbols can be used by other modules. By default, no symbols are exported, and export_no_symbols is not required.
Boss: All symbols are exported by default, unless export_no_symbols is used
7. kernel version check
When you need to include <Linux/module. h> in multiple files, you do not need to define _ no_version __
Earlier versions: when multiple files contain <Linux/module. h>, _ no_version __must be defined in other files except the main file to prevent duplicate versions.
8. device number
Kdev_t is abolished and unavailable. The new dev_t is extended to 32-bit, 12-bit master device number, and 20-bit device number.
Unsigned int iminor (struct inode * inode );
Unsigned int imajor (struct inode * inode );
Old Version: eight-digit master device number, eight-digit master device number
Int major (kdev_t Dev );
Int minor (kdev_t Dev );
9. Memory Allocation header file change
All memory allocation functions are included in the header file <Linux/slab. h>, but the original <Linux/malloc. h> does not exist.
Old Version: the memory allocation function is included in the header file <Linux/malloc. h>
10. initial trial of struct
GCC starts to use the initialization form of the ansi c struct:
Static struct some_structure = {
. Field1 = value,
. Field2 = value,
...
};
Old Version: non-standard preliminary trial form
Static struct some_structure = {
Field1: value,
Field2: value,
...
};
11. User Mode helper
Int call_usermodehelper (char * path, char ** argv, char ** envp,
Int wait );
Add wait Parameters
12. request_module ()
Request_module ("foo-device-% d", number );
Old Version:
Char module_name [32];
Printf (module_name, "foo-device-% d", number );
Request_module (module_name );
13. Change of character devices caused by dev_t
1. Take the Primary and Secondary device numbers
Unsigned iminor (struct inode * inode );
Unsigned imajor (struct inode * inode );
2. The old register_chrdev () usage remains unchanged and backward compatible, but cannot access devices with a device number greater than 256.
3. The new interface is
A) device range of registered characters
Int register_chrdev_region (dev_t from, unsigned count, char * Name );
B) dynamically apply for the master device number
Int alloc_chrdev_region (dev_t * Dev, unsigned baseminor, unsigned count, char * Name );
Look down at these two functions. ^_^! How can we associate with the file_operations structure? Don't worry!
C) include <Linux/cdev. h> and connect with file_operations using struct cdev
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 );
(Apply for the cdev structure, connect to the FoPs, and add the devices to the system! So complicated !)
D) void cdev_del (struct cdev * cdev );
It can be run only when the cdev_add operation is successful.
E) Auxiliary Functions
Kobject_put (& cdev-> kobj );
Struct kobject * cdev_get (struct cdev * cdev );
Void cdev_put (struct cdev * cdev );
This change is related to the newly added/sys/dev.
14. added access to/proc.
<Linux/seq_file.h>
In the previous/proc, only strings can be obtained. The seq_file operation can obtain multiple types of data, such as long.
Related functions:
Static struct seq_operations must implement each member function in the data similar to 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 );
And so on.
15. Underlying Memory Allocation
1. Change the <Linux/malloc. h> header file to <Linux/slab. h>
2. The allocation flag gfp_buffer is canceled and replaced by gfp_noio and gfp_nofs.
3. Add the _ gfp_repeat ,__ gfp_nofail ,__ gfp_noretry allocation flag.
4. The page allocation function alloc_pages (). get_free_page () is included in <Linux/green. h>.
5. Several functions are added to the NUMA system:
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. added 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 variable
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)
Old Version
Define_per_cpu (type, name );
Export_per_cpu_symbol (name );
Export_per_cpu_symbol_gpl (name );
Declare_per_cpu (type, name );
Define_per_cpu (INT, mypcint );
2.6 these macros are not secure when the kernel uses the scalability and winning scheduling method.
17. Kernel Time Changes
1. The current Hz of each platform is
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. Due to Hz changes, the original jiffies counter quickly overflows and a new counter jiffies_64 is introduced.
3. # include <Linux/jiffies. h>
U64 my_time = get_jiffies_64 ();
4. The new time structure adds the nanosecond member variable.
Struct timespec current_kernel_time (void );
5. His timer function is not changed.
Void add_timer_on (struct timer_list * timer, int CPU );
6. New latency Functions
Ndelay ();
7. POSIX clocks reference kernel/posix-timers.c
18. workqueue)
1. The task queue interface function is canceled, and the workqueue interface function is added.
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. Declare the structure of 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 );
19. added "libfs" for creating VFS"
Libfs provides a large number of APIS for creating a new file system.
It mainly implements struct file_system_type.
Reference source code:
Drivers/hotplug/pci_hotplug_core.c
Drivers/USB/CORE/inode. c
Drivers/oprofile/oprofilefs. c
FS/ramfs/inode. c
FS/nfsd/nfsctl. C (simple_fill_super () example)
20. DMA changes
Not changed:
Void * pci_alloc_consistent (struct pci_dev * Dev, size_t size,
Dma_addr_t * dma_handle );
Void pci_free_consistent (struct pci_dev * Dev, size_t size,
Void * cpu_addr, dma_addr_t dma_handle );
Changes include:
1. Void * dma_alloc_coherent (struct device * Dev, size_t size,
Dma_addr_t * dma_handle, int flag );
Void dma_free_coherent (struct device * Dev, size_t size,
Void * cpu_addr, dma_addr_t dma_handle );
2. lists the ing directions:
Enum dma_data_direction {
Dma_bidirectional = 0,
Dma_to_device = 1,
Dma_from_device = 2,
Dma_none = 3,
};
3. Single ing
Dma_addr_t dma_map_single (struct device * Dev, void * ADDR,
Size_t size,
Enum dma_data_direction direction );
Void dma_unmap_single (struct device * Dev, dma_addr_t dma_addr,
Size_t size,
Enum dma_data_direction direction );
4. Page ing
Dma_addr_t dma_map_page (struct device * Dev, struct page * page,
Unsigned long offset, size_t size,
Enum dma_data_direction direction );
Void dma_unmap_page (struct device * Dev, dma_addr_t dma_addr,
Size_t size,
Enum dma_data_direction direction );
5. functions related to scatter/gather:
Int dma_map_sg (struct device * Dev, struct scatterlist * SG,
Int nents, Enum dma_data_direction direction );
Void dma_unmap_sg (struct device * Dev, struct scatterlist * SG,
Int nhwentries, Enum dma_data_direction direction );
6. noncoherent DMA Mappings)
Void * dma_alloc_noncoherent (struct device * Dev, size_t size,
Dma_addr_t * dma_handle, int flag );
Void dma_sync_single_range (struct device * Dev, dma_addr_t dma_handle,
Unsigned long offset, size_t size,
Enum dma_data_direction direction );
Void dma_free_noncoherent (struct device * Dev, size_t size,
Void * cpu_addr, dma_addr_t dma_handle );
7. DAC (double address cycle)
Int pci_dac_set_dma_mask (struct pci_dev * Dev, u64 mask );
Void pci_dac_dma_sync_single (struct pci_dev * Dev,
Dma64_addr_t dma_addr,
Size_t Len, int direction );
21. Mutual Exclusion
The new seqlock is mainly used:
1. A small amount of data protection
2. Data is relatively simple (no pointer) and frequently used
3. Access to data without any side effects
4. Writers are not starved to death during access
<Linux/seqlock. h>
Initialization
Seqlock_t lock1 = seqlock_unlocked;
Or seqlock_t lock2; seqlock_init (& lock2 );
Void write_seqlock (seqlock_t * SL );
Void write_sequnlock (seqlock_t * SL );
Int write_tryseqlock (seqlock_t * SL );
Void write_seqlock_irqsave (seqlock_t * SL, long flags );
Void write_sequnlock_irqrestore (seqlock_t * SL, long flags );
Void write_seqlock_irq (seqlock_t * SL );
Void write_sequnlock_irq (seqlock_t * SL );
Void write_seqlock_bh (seqlock_t * SL );
Void write_sequnlock_bh (seqlock_t * SL );
Unsigned int read_seqbegin (seqlock_t * SL );
Int read_seqretry (seqlock_t * SL, unsigned int IV );
Unsigned int read_seqbegin_irqsave (seqlock_t * SL, long flags );
Int read_seqretry_irqrestore (seqlock_t * SL, unsigned int IV, long flags );
22. kernel deprivation
<Linux/preempt. h>
Preempt_disable ();
Preempt_enable_no_resched ();
Preempt_enable_noresched ();
Preempt_check_resched ();
23. Sleep and awakening
1. The original function is available. The following functions are added:
Prepare_to_wait_exclusive ();
Prepare_to_wait ();
2. Waiting for queue changes
Typedef int (* wait_queue_func_t) (wait_queue_t * wait,
Unsigned mode, int sync );
Void init_waitqueue_func_entry (wait_queue_t * queue,
Wait_queue_func_t func );
24. Completion events)
<Linux/completion. h>
Init_completion (& my_comp );
Void wait_for_completion (struct completion * comp );
Void complete (struct completion * comp );
Void complete_all (struct completion * comp );
25. RCU (read-copy-Update)
Rcu_read_lock ();
Void call_rcu (struct rcu_head * head, void (* func) (void * Arg ),
Void * Arg );
26. interrupt handling
1. There is a return value for the interrupt processing.
Irq_retval (handled );
2. cli (), STI (), save_flags (), and restore_flags () are no longer valid. Use local_save_flags () or local_irq_disable ().
3. The synchronize_irq () function has been modified.
4. Int can_request_irq (unsigned int IRQ, unsigned long flags) is added );
5. Change request_irq () and free_irq () from <Linux/sched. h> to <Linux/interrupt. h>
27. asynchronous I/O (AIO)
<Linux/AIO. h>
Ssize_t (* aio_read) (struct kiocb * iocb, char _ User * buffer,
Size_t count, loff_t POS );
Ssize_t (* aio_write) (struct kiocb * iocb, const char _ User * buffer,
Size_t count, loff_t POS );
INT (* aio_fsync) (struct kiocb *, int datasync );
Added to the file_operation structure.
Is_sync_kiocb (struct kiocb * iocb );
Int aio_complete (struct kiocb * iocb, long res, long RES2 );
28. Network-driven
1. struct net_device * alloc_netdev (INT sizeof_priv, const char * Name,
Void (* setup) (struct net_device *));
Struct net_device * alloc_etherdev (INT sizeof_priv );
2. New APIs)
Void netif_rx_schedule (struct net_device * Dev );
Void netif_rx_complete (struct net_device * Dev );
Int netif_rx_ni (struct sk_buff * SKB );
(The old version is netif_rx ())
29. USB driver
The old version of struct usb_driver is canceled, and the new struct is
Struct usb_class_driver {
Char * Name;
Struct file_operations * fops;
Mode_t mode;
Int minor_base;
};
Int usb_submit_urb (struct urb * urb, int mem_flags );
INT (* probe) (struct usb_interface * INTF,
Const struct usb_device_id * ID );
30. Block I/O layer
This part makes the most changes. Ominous.
31. MMAP ()
Int remap_page_range (struct vm_area_struct * VMA, unsigned long from,
Unsigned long to, unsigned long size,
Pgprot_t prot );
Int io_remap_page_range (struct vm_area_struct * VMA, unsigned long from,
Unsigned long to, unsigned long size,
Pgprot_t prot );
Struct page * (* nopage) (struct vm_area_struct * area,
Unsigned long address,
Int * type );
INT (* populate) (struct vm_area_struct * area, unsigned long address,
Unsigned long Len, pgprot_t Prot, unsigned long pgoff,
Int nonblock );
Int install_page (struct mm_struct * Mm, struct vm_area_struct * VMA,
Unsigned long ADDR, struct page * page,
Pgprot_t prot );
Struct page * vmalloc_to_page (void * address );
32. Zero-copy block I/O (zero-copy block I/O)
Struct bio * bio_map_user (struct block_device * bdev,
Unsigned long uaddr,
Unsigned int Len,
Int write_to_vm );
Void bio_unmap_user (struct bio * bio, int write_to_vm );
Int get_user_pages (struct task_struct * task,
Struct mm_struct * mm,
Unsigned long start,
Int Len,
Int write,
Int force,
Struct page ** pages,
Struct vm_area_struct ** VMAs );
33. High-end Memory Operation kmaps
Void * kmap_atomic (struct page * Page, Enum km_type type );
Void kunmap_atomic (void * address, Enum km_type type );
Struct page * kmap_atomic_to_page (void * address );
Earlier versions: kmap () and kunmap ().
34. Driver Model
It is mainly used for device management.
1. sysfs
2. kobjects
Recommended articles:
Http://www-900.ibm.com/developerWorks/cn/linux/kernel/l-kernel26/index.shtml#1
Http://www-900.ibm.com/developerWorks/cn/linux/l-inside/index.shtml#h1