Module parameters, system calls, an important character device programming data structures, equipment and registration number of the application, API on the cdev

1, the module parameters
  Application Programming:
      int main (int argc, char * the argv [])
      {
         
      }
      ./a.out XXX yyy ZZZ
  kernel programming:
      
      the insmod xxx.ko parameter information    
      
  desired parameters can also be passed to the kernel module which, when installed , required module parameter
 
 
  module parameters implemented steps of:
     1) define the global variables in the module
     2)
        module_param (name, type, perm) ; or
        module_param_array (name, type, nump, perm);
        make the variable parameter module
        
  module_param (name, type, Perm);
     name, global variable name
     type, type of variable
           variable type core statement of support for the module parameters int Short Long charp
     Perm, access
  module_param_array (name, type, nump,   perm);
     effect: will be declared as an array parameter module
     name, the name of the array
     type, the data type of the array member variable
     nump, the array element number of pointers
     perm, access to     
   
  the experimental procedure:
    the insmod moduleparam.ko
    rmmod moduleparam
    
    the insmod moduleparam.ko STR IRQ = 100 = "Hello" FISH = 1,2,3,4,5   
   
    LS / SYS / Module1 / moduleparam / parameters / no display
    CD / SYS / Module1 / moduleparam / parameters /   
    CAT FISH
    CAT IRQ
    1234> IRQ echo
    11,22,33,44,55,66> FISH echo
    CD /
    rmmod moduleparam
  use scenario module parameters:
    debugging code when use
    
    REG1 = IRQ;
    
    insmod xxx.ko IRQ = 100
    rmmod xxx.ko
    insmod xxx.ko IRQ = 101;  

2, the system call
   to talk about the understanding of system calls?
   
   What is the system call?
       The operating system provides a set of application programmer calls a special function
   the role of system calls?
       Kernel security protection
       to ensure the security of user space to kernel calls the function of
   the system call is how to achieve
       
       the specified user space system call number
       to produce soft interrupt abnormal execution into kernel mode
       execution jumps to abnormal soft interrupt vector table exception handling code
       in soft interrupt exception handling code according to the system call number
       to find the corresponding kernel function
       and performing the function
       is finished the results will backtrack to the user space
       
       
       system calls: arch / arm / include / asm / unistd.h
       software interrupt instruction:
                   ARM, SWI / svc
                   intel, int
       exception to the scale: arch / arm / kernel / entry -armv.S
       soft interrupt exception handling code: arch / arm / kernel / entry -common.S
       system call table: calls.S
  add a new system call
     CD / Home / tarena / Driver / Kernel /
     VI Arch / ARM / Kernel / sys_arm.c
        the asmlinkage sys_add int (int X, Y int)
    {
        the printk ( "<. 1>" "Enter% S \ n-", __func__ in);
        return X + Y;
    }
     VI Arch / ARM / the include / ASM / unistd.h // add new system calls
        #define __NR_add (__NR_SYSCALL_BASE + 378)
     vi Arch / ARM / kernel / calls.S // update the system call table
        390 the cALL (sys_add)   
   the make uImage
   lets developers use the new kernel board
   
   vi test.c
       
      Open = ( "a.txt", O_RDWR) is equivalent to
      syscall (. 5, "a.txt", O_RDWR)
      
      Read (FD, buf, len) is equivalent to
      the syscall (. 3, FD, buf, len)
   ARM-Linux-gnueabi cortex_a9-GCC-Test test.c -o
   CP Test. ./../rootfs
   
   ./test // Notice the difference between old and new kernel
 

3, character device driver programming

  linux is implemented using the C programming
  , but kernel implementation process, extensive use of object-oriented programming ideas
 
 
  Implement a character device (e.g., the LCD touch screen button mouse ...) in linux
  driver, its essence is to instantiate an object of type struct cdev
 
  struct cdev
  {
     // device number
     the dev_t dev;
     const struct the file_operations OPS *;   
     ...
  }
 3.1 device number
     is essentially a 32bit unsigned data of the
     
     device number = device number of the main (high 12bit) + minor number (low 20bit)
     
     major number, for distinguishing between different types of devices
     minor number, for distinguishing the same type equipment in different individuals
     
     ls / dev / ttySAC * -l
     
     application and registration number of the device in two ways:
         1) static
         2) dynamically
   3.1.1 static
        view which has been occupied by major number
            cat / proc / devices
        
        has never occupied a major number pick as I used      
         
        int register_chrdev_region (dev_t from, unsigned count ,
                                   const char * name)
            action: the plurality of devices registered consecutive numbers
            from, the starting device number register to
            COUNT, the number to be registered
            name, the name of
            a return value success 0
                    <0 Failed
        void unregister_chrdev_region (dev_t from, unsigned count             )
                    
        experimental procedure:
            the insmod led_drv.ko
            CAT / proc / devices
            rmmod led_drv.ko
            CAT / proc / devices
    3.1.2 dynamically
         dynamically allocated by the kernel using the master device is not a number
         
         int alloc_chrdev_region (the dev_t * dev,
                  unsigned baseminor, unsigned COUNT,
            name char * const)       
            dev, outgoing parameters   
                Returns the dispensing device to obtain a first number
            baseminor, starting minor number
            count, the number of consecutive equipment numbers application
            name, name
            
         cancellation: unregister_chrdev_region       
  3.2 operating (driving) the collection function
      driver implemented a hardware device character
      actually is an example of a struct cdev object is
      instantiated objects struct cdev main coding process
      focused on the file_operations struct   
      
      struct the file_operations
      {
          owner
          Open
          Read
          Write
          the mmap
          Release
          unlocked_ioctl
          poll
          ...
      }
      particular character of a particular hardware device, only Some of these functions can be implemented
  API of about 3.3 cdev kernel provided  
      cdev_init void (* struct cdev cdev,
               const struct the file_operations * FOPS)
      {
          cdev-> OPS = FOPS;
          ...
          
      }
      
      // Register the cdev a student records into the database
      cdev_add (struct cdev * p, dev_t dev, unsigned count )
      {
          p-> dev = dev;
          ...
      }
      // cdev recorded a cancellation deleted from the database of students
      void cdev_del (struct cdev * p)    
          
     experimental Procedure:
         . 1) the insmod led_drv.ko
            find the master device using the driving and minor No.
         2) development board create the device files in
            the mknod / dev / myleds C 244. 5
         . 3) VI test.c
            
            FD = Open ( "/ dev / myleds", O_RDWR);  
         4) arm-cortex_a9-linux- gnueabi-gcc test.c -o test
         execution on 5) board the Test
            cp the Test ../../rootfs
            
            ./test
     summary:
         everything is a file in addition to socket under linux

Module parameter passing // 
#include " ../../global.h " int IRQ = 0 ; char * STR = " tarena " ; int fish [ 10 ] = { 0 }; / * save the number of fish of elements * / int num_fish = 10 ; module_param(irq, int, 0644); module_param(str, charp, 0); module_param_array(fish, int, &num_fish,0600); int __init moduleparam_init(void) { int i = 0; printk("<1>" "irq=%d\n", irq); printk("<1>" "str=%s\n", str); for(; i<num_fish; i++) { printk("<1>" "fish[%d]=%d\n", i, fish[i]); } return 0; } void __exit moduleparam_exit(void) { int i = 0; printk("<1>" "irq=%d\n", irq); printk("<1>" "str=%s\n", str); for(; i<num_fish; i++) { printk("<1>" "fish[%d]=%d\n", i, fish[i]); } } module_init(moduleparam_init); module_exit(moduleparam_exit);
// Register the device number. 
#include " ../../global.h " #include <Linux / fs.h> unsigned int major = 200; unsigned int minor = 5; dev the dev_t; // device number int __init led_drv_init(void) { //dev = major<<20|minor; dev = MKDEV(major, minor); register_chrdev_region(dev, 1, "myleds"); return 0; } void __exit led_drv_exit(void) { unregister_chrdev_region(dev, 1); } module_init(led_drv_init); module_exit(led_drv_exit);
// dynamic registration device number 
. 1
#include " ../../global.h " 2 #include <Linux / fs.h> . 3 . 4 unsigned int Major = 0 ; . 5 unsigned int Minor = . 5 ; . 6 the dev_t dev; // device number . 7 . 8 . 9 int the __init led_drv_init ( void ) 10 { . 11 IF (Major) // static 12 is { 13 is // dev = 20 is Major << | Minor; 14 dev = MKDEV(major, minor); 15 16 register_chrdev_region(dev, 1, "myleds"); 17 } 18 else //动态注册 19 { 20 alloc_chrdev_region(&dev, minor, 1, "myleds"); 21 printk("<1>" "major=%d minor=%d\n", 22 MAJOR(dev), MINOR(dev)); 23 } 24 return 0; 25 } 26 void __exit led_drv_exit(void) 27 { 28 unregister_chrdev_region(dev, 1); 29 } 30 module_init(led_drv_init); 31 module_exit(led_drv_exit);
#include "../../global.h"
#include <linux/fs.h>
#include <linux/cdev.h>

unsigned int major = 0;
unsigned int minor = 5;
dev the dev_t; // device number

/ * 1 defines a struct cdev variable * / 
struct the cdev led_cdev;


static int led_open(struct inode *inode, 
                    struct file *filp)
{
    printk("<1>" "enter %s\n", __func__);
    return 0;
}
static int led_close(struct inode *inode, 
                    struct file *filp)
{
    printk("<1>" "enter %s\n", __func__);
    return 0;
}

struct file_operations led_fops =
{
    .owner = THIS_MODULE,
    .open  = led_open,
    .release = led_close,
};
int __init led_drv_init(void)
{
    if(major) //静态
    {
        //dev = major<<20|minor;
        dev = MKDEV(major, minor);

        register_chrdev_region(dev, 1, "myleds");
    }
    the else  // dynamic registration 
    {
        alloc_chrdev_region(&dev, minor, 1, "myleds");
        printk("<1>" "major=%d minor=%d\n",
                MAJOR(dev), MINOR(dev));
    }
    / * 2 cdev initialize variables * / 
    cdev_init ( & led_cdev, & led_fops);
     / * . 3 cdev register variables * / 
    cdev_add ( & led_cdev, dev, . 1 );

    return 0;
}
void __exit led_drv_exit(void)
{
    / * 4 Chu销Cdev * / 
    Cdev_del ( Ando Led_cdev);

    unregister_chrdev_region(dev, 1);
}
module_init(led_drv_init);
module_exit(led_drv_exit);

Guess you like

Origin www.cnblogs.com/DXGG-Bond/p/11844642.html