+ All Categories
Home > Documents > Linux Device Driver Sum Up

Linux Device Driver Sum Up

Date post: 30-May-2018
Category:
Upload: nguyenvan-thanh
View: 221 times
Download: 0 times
Share this document with a friend

of 53

Transcript
  • 8/9/2019 Linux Device Driver Sum Up

    1/53

    1. Nhung van de can hoc

    Kernel Space Timer Services

    Timer Interrupts - HZ and jiffi es

    Delaying Execution

    Using Task Queues

    Kernel Space Timers

    Interrupt Handling

    Linux and Interrupts

    IRQ Action Table

    Register, Enabling and Disabling Interrupts

    Minimizing Interrupt Latency

    2. Explain the differences between user memory and kernel memory

    The cs register has one important function: it includes a 2bit fieldthat specifies the Current Privilege Level (CPL) of the CPU.

    The value 0 denotes the highest privilege leve l, while the value

    3 denotes the lowest one.

    Linux uses only levels 0 and 3 , which are respectively called Kernel

    Mode and User Mode.

    A similar situation occurs for the ss register: it must refer to

    a User Mode stack inside the user data segment when the CPL is 3,

    and it must refer to a Kernel Mode stack inside the kernel data

    segment when the CPL is 0. When switching from User Mode to KernelMode.

    A process can run in two modes:1.user mode 2.kernel mode

    User Mode(Space)

    A mode of the CPU when running a pr ogram.

    In this mode ,the user process has no access to the memory

    locations used by the kernel.

    When a program is running in User Mode, it cannot directly access

    the kernel data structures or the kernel programs.

    Kernel Mode A mode of the CPU when running a program

    In this mode, it is the kernel that is running on behalf of the

    user process and directly access the kernel data structures or

    the kernel programs.

    Once the system call returns,the CPU switches back to user mode.

  • 8/9/2019 Linux Device Driver Sum Up

    2/53

    It provides the main functions of the abstract machine (system

    calls and Interrupt and traps).

    user and kernel mode : When you execute a C program,the CPU runs in user mode till the

    system call is invoked

    In this mode,the user process has access to a limited section

    of the computer's memory and can execute a restricted set of

    machine instructions.

    However,when the process invokes a system call,the CPU switches

    from user mode to a more privileged mode - kernel mode

    In this mode ,it is the kernel that runs on behalf of the user

    process,but it has access to any memory location and can executeany machine instruction.

    After the system call has returned,the CPU switches back to user

    mode

    User/Kernel Interactions

    Transfer of Control between User and Kernel Mode

    System Calls

    Interrupts (timer or device)

    Transfer of Data between User and Kernel Space

    Memory copy /proc/ file system

    Approximate structure of generic UNIX kernel

    3. Explain the differences between user memory and kernel memory

    The kernel offers several subroutines or functions in user space, which allow the

    end-user application programmer to interact with the hardware.

  • 8/9/2019 Linux Device Driver Sum Up

    3/53

    Usually, in UNIX or Linux systems, this dialogue is performed through functions or

    subroutines in order to read and write files. The reason for this is that in Unix devices

    are seen, from the point of view of the user, as files.

    Linux and Unix use the file which is a well understood data structure

    for handling byte sequences to represent I/O device s.

    A device driver consists of a set of routines that control a

    peripheral device attached to a workstation

    On the other hand, in kernel space Linux also offers several functions or subroutines to

    perform the low level interactions directly with the hardware, and allow the transfer of

    information from kernel to user space.

    Usually, for each function in user space (allowing the use of devices or files), there

    exists an equivalent in kernel space (allowing the transfer of information from the

    kernel to the user and vice-versa).

    4. List the major subsystems of the Linux kernel

  • 8/9/2019 Linux Device Driver Sum Up

    4/53

    Kernel subsystems

    Process management

    The kernel is in charge of creating and destroying processesandhandling their connection to the outside world (input and

    output). Communication among different processes (through

    signals, pipes, or interprocesscommunication primitives) is

    basic to the overall system functionality and is also handled

    by the kernel. In addition, the scheduler, which controls how

  • 8/9/2019 Linux Device Driver Sum Up

    5/53

    processes share the CPU, is part of process management. More

    generally, the kernel's process management activity implements

    the abstraction of several processes on top of a single CPU or

    a f e w o f t h e m .

    Process Management(PM): The Process Management system controls

    the creation, termination, accounting, and scheduling of

    processes. It also facilitates and manages the complex task of

    the creation of child processes.

    Memory management

    The computer's memory is a major resource, and the policy used

    to deal with it is a critical one for system performance. The

    kernel builds up a virtual addressing space for any and allprocesses on top of the limited available resources. The

    d i f f e r e n t p a r t s o f t h e k e r n e l i n t e r a c t w i t h t h e

    memory-management subsystem through a set of function calls,

    ranging from the simple malloc/free pair to much more exotic

    f u n c t i o n a l i t i e s .

    File systems

    Unix is heavily based on the filesystem concept; almost

    everything in Unix can be treated as a file. The kernel builds

    a structured filesystem on top of unstructured hardware, andthe resulting file abstraction is heavily used throughout the

    whole system. In addition, Linux supports multiple filesystem

    types, that is, different ways of organizing d ata on the physical

    medium.For example, diskettes may be formatted with either the

    Linuxstandard ext2 filesystem or with the commonly used FAT

    filesystem.

    Device control

    Almost every system operation eventually maps to a physical

    device. With the excepti on of the processor, memory, and a veryfew other entities, any and all device control operations are

    performed by code that is specific to the device being addressed.

    That code is called a device driver. The kernel must have

    embedded in it a device driver for every peripheral present on

    a system, from the hard drive to the keyboard and the tape

  • 8/9/2019 Linux Device Driver Sum Up

    6/53

    streamer. This aspect of the kernel's functions is our primary

    interest in this book.

    A set of routines needed to operate a specific device is known

    as device driver. They hide completely the details of how the

    device works.

    Networking

    Networking must be managed by the operating system because most

    network operations are not specific to a process: incoming

    packets are asynchronous events. The packets must be collected,

    identified, and dispatched before a process takes care of them.

    The system is in charge of delivering data packets across program

    and network interfaces, and it must control the execution ofprograms according to their network activity. Addition ally, all

    the routing and address resolution issues are implemented within

    the kernel

    networking in the Linux kernel is implemented by three

    layers of software:

    The socket interface

    Protocol drivers

    Network device drivers

    Any network interconnection is made through the interface(device), that is able to exchange data with other hosts.

    Transactions made using an Interface

    Interface can be hardware or software

    Interface is incharge of sending and receiving data

    packets

  • 8/9/2019 Linux Device Driver Sum Up

    7/53

    Network Interface isnt easily mapped to a node in the

    filesystem

    Though UNIX will map it as eth0

    I/O Software Layers

    Chu y: Kernel features

    One of the good features of Linux is the ability to extend at

    runtime the set of features offered by the kernel. This means

    that you can add functionality to the kernel while the system

    is up and running. Each piece of code that can be added to the

    kernel at runtime is called a module. The Linux kernel offers

    support for quite a few different types (or classes) of modules,including, but not limited to, device drivers. Each module is

    made up of object code (not linked into a complete executable)

    that can be dynamically linked to the running kernel by the

    insmod program and can be unlinked by the rmmod program.

    Devices and Modules

    Adriver is the part of the OS that manages communication with devices;

    thus, they are usually calleddevicedrivers.

  • 8/9/2019 Linux Device Driver Sum Up

    8/53

    Differences between software and hardware are clearly specified in

    this scheme. At the left side, user programs may interact with the

    devices (for example, a hard disk) through a set ofhigh-levellibraryfunctions. For example, we can open and write to a file of the hard disk

    calling the Clibrary functions fopen, fprintf and close:

    FILE *fid=fopen("filename", "w");

    fprintf(fid, "Hello, world!");

    fclose(fid);

    The user can also write to a file (or to another device such as a printer)

    from the OS shell, using commands such as:

    echo "Hello, world!" >

    echo "Hello, world!" > /dev/lpTo execute this command, both the shell and the library functions

    perform a call to a low level function of the OS, e.g., open(), write() or

    close():

    fid = open("/dev/lp", O_WRONLY);

    write(fid, "Hello, world!");

    close(fid);

    Each device can be referred to as a special file named /dev/*. Internally,

    the OS is composed of a set of drivers, which are pieces of software

    that perform the low-level communication with each device. At thisexecute level, the kernel calls driver functions such as lp_open() or

    lp_write().

    Finally, the device driver is the physical interface between the

    software and the hardware. The driver reads from and writes to the

    hardware through ports (memory addresses where the hardware links

  • 8/9/2019 Linux Device Driver Sum Up

    9/53

    physically), using the internal functions

    out_p(0x3a, 0x1f);

    data = in_p(0x3b);

    Note that these functions are not available to the user .

    Since the Linux kernel runs in protected mode, the low

    memory addresses , where the ports addresses reside, are not

    user accessible.

    The Unix way of looking at devices distinguishes between three

    device types. Each module usually implements one of these types,

    and thus is classifiable as a char module, a block module, or

    a network module.

    Characterdriverstransmitinformation from theuserto thedevice(orviceversa) byteperbyte

    Two examplesaretheprinter, /dev/lp, andthememory (yes, the

    memory isalso adevice), /dev/mem

    Blockdrivers(seeFigure3) transmit information blockperblock. This

    meansthat theincoming data (from theuserorfrom thedevice) are

    storedin a bufferuntilthebufferisfull. When thisoccurs, thebuffer

    content isphysically sent to thedeviceorto theuser.

    Theclearest examplesof thistypeofdriveraredisks: floppy disks

    (/dev/fd0), IDE harddisks(/dev/hda) andSCSI harddisks(/dev/sd1)

    Streamsaretheyoungestdrivers(seeFigure5) and aredesigned for

  • 8/9/2019 Linux Device Driver Sum Up

    10/53

    very high speed data flows. Both the kernel and the driver include

    severalprotocollayers. The best example of this type is a network

    driver

    Terminaldrivers(seeFigure4) constituteaspecialset of character

    driversforusercommunication. Forexample, commandtoolsinan

    open windowsenvironment, anX terminalora console, aredeviceswhich requirespecial functions, e.g., theupanddownarrowsfora

    commandbuffermanagerortabbing in thebash shell. Examplesof

    block driversare/dev/tty0 or/dev/ttya (aserialport). In both casesthe

    kernelincludesspecialroutines, andthedriverspecialprocedures, to

    copewith allparticularfeatures.

    Userlevel programs communicate with the kernel using system calls,

    for instance, open(), read(), write(), ioctl(), close() , and the

    like.

  • 8/9/2019 Linux Device Driver Sum Up

    11/53

  • 8/9/2019 Linux Device Driver Sum Up

    12/53

    5. Explain how Linux implements file and device Input/Output (I/O) operations

    I/O Architecture

    The 80 x 86 microprocessors use 16 of their address pins to address I/O devices and 8, 16, or 32 of

    their data pins to transfer data.

    The data path that connects a CPU to an I/O device is generically called an I/O bus.

    The I/O bus, in turn, is connected to each I/O device by means of a hierarchy of hardware components

    including up to three elements: I/O ports , interfaces, and device controllers

    I/O Ports

    Each device connected to the I/O bus has its own set of I/O addresses, which are usually called

    I/O ports .

    In the IBM PC architecture, the I/O address space provides up to 65,536 8-bit I/O ports.

  • 8/9/2019 Linux Device Driver Sum Up

    13/53

    Four special assembly language instructions called in, ins , out , and outs allow the CPU to read

    from and write into an I/O port. While executing one of these instructions, the CPU selects the

    required I/O port and transfers the data between a CPU register and the port.

    I/O ports may also be mapped into addresses of the physical address space

    The CPU writes the commands to be sent to the device into the device control registerand reads

    a value that represents the internal state of the device from the device status register.

    The CPU also fetches data from the device by reading bytes from the device input registerand

    pushes data to the device by writing bytes into the device output register.

    Accessing I/O ports

    The in, out, ins, and outs assembly language instructions access I/O ports. The following

    auxiliary functions are included in the kernel to simplify such accesses: The suffix "b," "w,"

    or "l" refers, respectively, to a byte (8 bits), a word (16 bits), and a long (32 bits).

    inb( ), inw( ), inl( )

    inb_p( ), inw_p( ), inl_p( ) outb( ), outw( ), outl( )

    outb_p( ), outw_p( ), outl_p( )

    insb( ), insw( ), insl( )

    outsb( ), outsw( ), outsl( )

    I/O Interfaces

    An I/O interface is a hardware circuit inserted between a group of I/O ports and the

    corresponding device controller. It acts as an interpreter that translates the values in the I/O ports

    into commands and data for the device.

    In the opposite direction, it detects changes in the device state and correspondingly updates the

    I/O port that plays the role of status register.

    This circuit can also be connected through an IRQ line to a Programmable Interrupt Controller, so

    that it issues interrupt requests on behalf of the device

    There are two types of interfaces:

    Custom I/O interfaces

  • 8/9/2019 Linux Device Driver Sum Up

    14/53

    Keyboard interface

    Graphic interface

    Disk interface

    Bus mouse interface

    Network interface

    General-purpose I/O interfaces

    Parallel port

    Serial port

    PCMCIA interface

    SCSI (SmallComputerSystem Interface) interface

    Universal serial bus (USB)

    Device Controllers

    It interprets the high-level commands received from the I/O interface and forces the device to

    execute specific actions by sending proper sequences of electrical signals to it.

    It converts and properly interprets the electrical signals received from the device and modifies

    (through the I/O interface) the value of the status register.

    6. Device Files

    Major number, identifies the device type. Traditionally, all device files that have the same major number and

    the same type share the same set of file operations, because they are handled by the same device driver.

    minor number, identifies a specific device among a group of devices that share the same major number.

    For instance, a group of disks managed by the same disk controller have the same major number and

    different minor numbers .

    the major and minor numbers of the device files are 8 bits long. Thus, there could be at most 65,536 block

    device files and 65,536 character device files. You might expect they will suffice, but unfortunately they don't.

    Major device numbers are used by the Linux system to map I/O requests

    to the driver code, thereby deciding which devic e driver to execute,

    when a user reads from or writes to the special file.

    The minor numbers are entirely under the control of the driver

    writer, and usually refer to ysubdevicesy of the device. Tuc la co

    nhieu thiet bi thuoc cung 1 chung? Loai,dung minor number de phanbiet cac thiet bi do voi nhau chang han nhu hard disk

    The mknod( ) system call is used to create device files. It receives the name of the device file, its type, and

    the major and minor numbers as its parameters. Device files are usually included in the/devdirectory. Notice

    that character and block devices have independent numbering, so block device (3,0) is different from

    character device (3,0).

  • 8/9/2019 Linux Device Driver Sum Up

    15/53

    a device file is not associated with any real hardware device, but represents a fictit ious logical device. device.

    For instance, /dev/null is a device file corresponding to a "black hole;" all data written into it is simply

    discarded, and the file always appears empty

    CHU Y rang: ten thiet bi thuc ra khogn quan trong doi voi 1 so application programs vi chi can 3 tham so :

    kieu thiet bi, major number va minor number la xac dinh duco thiet bi, ten thiet bi ko quan trong. Tuy nhien doi

    voi 1 so application programs thi lai giao tiep thong qua ten thiet bi ao

    As far as the kernel is concerned, the name of the device file is irrelevant

    If you create a device fil e named/tmp/diskof type "block" with the major number 3 and minor number 0,

    it would be equivalent to the/dev/hda device file shown in the table.

    On the other hand, device filenames may be significant for some application programs

    7. Assigning Device Numbers

    There are essentially two methods for assigning a range of device numbers to a character device driver. The first method, which should be used for all new device drivers, relies on the

    register_chrdev_region( ) and alloc_chrdev_region( ) functions, and assigns an arbitrary range of

    device numbers. For instance, to get an interval of numbers starting from the dev_t value dev and of

    size size:

    register_chrdev_region(dev, size, "foo");

  • 8/9/2019 Linux Device Driver Sum Up

    16/53

    These functions do not execute cdev_add( ), so the device driver must execute cdev_add( ) after the

    requested interval has been successfully assigned.

    The second method makes use of the register_chrdev( ) function and assigns a fixed interval of device

    numbers including a single major number and minor numbers from 0 to 255. In this case, the device

    driver must not invoke cdev_add( ).

    The register_chrdev( ) function is used by drivers that require an old-style interval of device

    numbers: a single major number and minor numbers ranging from 0 to 255.

    The function receives as its parameters the requested major number major (zero for dynamic

    allocation), the name of the device driver name, and a pointer fops to a table of file operations

    specific to the character device files in the interval.

    8. Use the printk( ) function to print messages from within the Linux kernel

    printk(): A version of printf() for the kernel.

    9. Linux System Calls

    The kernel is not a separate task under Linux. It is as if each

    process has a copy of the kernel . When a user process executes a

    system call, it does not transfer control to another process, but

    changes its execution mode from user to kernel mode.

    In kernel mode, while executing the system call, the process has

    access to the kernel address space, and through supporting

    functions , it has access to the address space of the user executing

    the call.

    Device Driver Development Supporting Functions

    The table below contains most of the common supp orting functions

    available for writing device drivers.

    add_timer()

    cli()

    end_request()

    free_irq()

    get_fs*(): Allows a driver to access data in user space, a memory

    area distinct from the kernel inb(), inb_p():Reads a byte from a port. Here, inb() goes as fast

    as it can, while inb_p() pauses before returning.

    irqaction()

    IS_*(inode)

    kfree*(): Frees memory previously allocated with kmalloc()

  • 8/9/2019 Linux Device Driver Sum Up

    17/53

    kmalloc():Allocates a chu nk of memory no larger than 4096 bytes.

    MAJOR():Reports the major device number for a device.

    MINOR():Reports the minor device number for a device.

    memcpy_*fs():Copies chunks of memory between user space and

    kernel space

    outb(), outb_p() :Writes a byte to a port. Here, outb() goes as

    fast as it can, while outb_p() pauses before returning.

    printk():A version of printf() for the kernel.

    put_fs*(): Allows a driver to write data in user space.

    register_*dev() :Registers a device with the kernel.

    request_irq():Requests an IRQ from the kernel, and, if

    successful, installs an IRQ interrupt handler.

    A device driver provides the I/O system with a standard interfaceto the hardware, hiding the unique characteristics of the hardware

    device from the user to the greatest extent possible.

    illustrates a user program that employs some basic system calls to

    read characters from a device into a buffer. When a system call is

    requested, the kernel transfers control to the appropriate device

    driver routine that executes on behalf of the calling user process flow of execution of a system call within th e Linux operating system

  • 8/9/2019 Linux Device Driver Sum Up

    18/53

    major subsystem oflinux kernel

  • 8/9/2019 Linux Device Driver Sum Up

    19/53

    System Call Interface(SCI)

    Asystem call is an interface between a user-space application and a service

    that the kernelprovides. Because the service is provided in the kernel, a

    direct call cannot be performed; instead, you must use a process of crossingthe user-space/kernel boundary.

    A system call is the method that the user process uses to ask for

    an action from the O.S.

    The SCI is a thin layer that provides the means to perform

    function calls from user space into the kernel.

    A system call is an interface between a user s spaceapplication

    and a service that the kernelprovides.

    To access the services available in the operating system, all

    Unix/Linux system offer around 200 special functions calledsystem calls.

    System calls provide a layer between the hardware and userspace

    processes.This layer serves three primary purposes : First, it provides an abstracted hardware interface for

    userspace.When reading or writing from a file, for example,

    applications need not concern themselves with the type of

    disk, media, or even the filesystem on which the file resides

    Second, system calls ensure system se and stability.For

    example, this prevents applications from incorrectly usinghardware, stealing o ther processes' resources, or doing harm

    to the system.

    A system call is nothing but a routine built into the

    kernel and performs a very basic function that requires

    communication with the CPU , memory,and devices.

    All activities related to file handling, process and

    memory management and maintenance of the user are handled

    by the kernel using these system calls.

    Finally, a single common layer between user space and therest of the system allows for the virtualized system provided

    to processes.If applications were free to access systemresources without the kernel's knowledge, it would be nearly

    impossible to implement multitasking and virtual memor y, and

    certainly impossible to do so with stability and security.

  • 8/9/2019 Linux Device Driver Sum Up

    20/53

    user and kernel mode :

    When you execute a C program,the CPU runs in user mode till

    the system call is invoked

    In this mode,the user process has access to a limited sectionof the computer's memory and can execute a restricted set

    of machine instructions.

    However,when the process invokes a system call,the CPU

    switches from user mode to a more privileged mode - kernel

    mode

    In this mode ,it is the kernel that runs on behalf of the

    user process,but it has access to any memory location and

    can execute any machine instruction.

    After the system call has returned,the CPU switches back touser mode

    System call and Library Function call

    If you are a C programmer on GNU/Linux and have not used

    system calls,then you must have used the library functions

    A set of functions available in the standard library that

    is shipped with the C compiler for Linux and nonLinux system

    Nhu vay chung tat hay rang co 2 cach de lam: hoac la tu tao

    ra cac system call hoac la su dung thu vien libraries. Hay noi

    cach khac thu vien nay da xay dung cho ta san cac system call

    va chung ta chi viec sudung chang han nhu sau:

    For example, we can open and write to a file of the hard disk calling

    the Clibrary functions fopen, fprintf and close:FILE *fid=fopen("filename", "w");

    fprintf(fid, "Hello, world!");

    fclose(fid);

    On Linux systems ,these library functions are built on top

    of the system calls.

  • 8/9/2019 Linux Device Driver Sum Up

    21/53

    system call is built into the kernel.

    The standard C library offers separate functions to read a

    block of data(fread),and a line(fgets),and a single

    character(fgetc). All these functions ultima tely invoke the only system call

    available for reading input read.

    using system call is usually the most efficient way to

    perform I/O operations and is some time more convenient ,too.

    For example: fopen can create a file in read or write mode

    but can't set the file permissions(in chmod style)which open

    does easily.

    A library function can't tell you the size of a file which

    the stat system call does by looking up a structureassociated with the inode.

    when a program makes system calls ,the arguments are packaged

    up and handed to the kernel ,which takes over execution of

    the program untill the call completes

    API System Call OS Relationship

    Standard CLibrary Example

  • 8/9/2019 Linux Device Driver Sum Up

    22/53

    System CallParameter Passing

    Three general methods used to pass parameters to the OS

    Simplest: pass the parameters in registers. In some

    cases, may be more parameters than registers Parameters stored in a block, or table, in memory, and

    address of blockpassed as a parameter in a register . This

    approach taken by Linux and Solaris

    Parameters placed, or pushed, onto the stack by the

    program and popped off the stackby the operating system

    Block and stack methods do not limit the number or

    length ofparameters being passed

    Parameter Passing via Table

  • 8/9/2019 Linux Device Driver Sum Up

    23/53

    10.Introducing LKMprogramming There are several kernel architectures, but the two most important are:

    Monolithic

    Micro-kernell

    Monolithicn kernel

    The monolithic term means that the kernel is implemented as an only one

    process, with an only address space. It is like when you create a single .c file,

    and it is executed as a single process. People that are in favour of this model,

    cite the simplicity as the main goal. With a monolithic kernel, communication

    is simple, and it is possible to call a defined function from wherever in thekernel. Most of the UNIX kernels are monolithic (Hurd is an exception)

    Micro-kernel

    The approach for micro-kernel design is simple: Let the kernelperform only theessential operations. Everything else that can be performed in user space

    should be done there. In a micro-kernel scenario, the kernel must communicate

    with the other operating system parts. Typically, the memory management, file

    systems and IPC communications are not inside the kernel. This model can

    take advantage of memory protection features provided by modern processors.

  • 8/9/2019 Linux Device Driver Sum Up

    24/53

    The drawback is the extra communication caused by this distributed schema

    where every subsystem has it's own address space.

    Linux kernel is Monolithic, but it is also modular, i.e. the kernel can

    dynamically load parts of the kernel code. This is a really nice feature since in

    this way, it is possible to extend the kernel capabilities without modifying the

    rest of the code. With traditional UNIX kernels, it was necessary to recompile

    the kernel to add a new feature. Now, it is possible to insert the module while

    the kernel is running. This doesn't produce any problem. Modern UNIX kernels

    support modules loading.

    Linux kernel module:

    a kernel module is a part of the kernel code. In fact, if you have evercompiled your kernel, surely you know this: when we set preferences for

    our customized kernel, we can choose a feature to be compiled as a module

    or to be integrated in the kernel code.

    Almost everything in kernel code can be implemented as a module.

    However, it is common to implement file systems, drivers or some

    programs that need kernel mode (e.g. performance analysers like vtune)

    if your program needs to work in kernel mode, the best you can do is to

    implement it as a module instead of modifying the rest of the kernel.

    structure of a kernel module

  • 8/9/2019 Linux Device Driver Sum Up

    25/53

    11.Kernel command using Linux system calls

    Trong he dieu hanh linux chung ta co 2 che do la user mode va kernel mode.

    User mode is non-privileged in that processes in this mode are not allowed

    to access those portions ofmemory that have been allocated to the kernelor to other programs.

    The kernel is a program that constitutes the core of an operating system,

    and it has complete control over all resources on the system and

    everything that occurs on it.

    When a usermode process(i.e., a processcurrently in usermode) wantsto

    utilize a service providedby the kernel (i.e., accesssystemresourcesother

    than the limitedmemory space that is allocated to the user program), it

    must switch temporarily into kernelmode, also called system mode, by

    meansof a systemcall. Kernel mode has root (i.e., administrative) privileges, including root access

    permissions (i.e., permission to access any memory space or other

    resources on the system). This allows the operating system to perform

    restricted actions such as accessing hardware devices or the memory

    management unit (MMU). When the kernel has satisfied the request made

    by a process, it restores that process to user mode

    Chu y rang: chung ta co 2 cach de co the su dung cac dich vu cua kernel thong

    qua system call hoac la thogn qua viec doc file /proc filesystem

    Access the linux kernel using the /proc filesystem The /proc filesystem is a virtual filesystem that permits a novel approach

    for communication between the Linux kernel and user space.

    the content of these virtual files is dynamically created.

    The /proc filesystem contains directories (as a way of organizing

    information) and virtual files . Avirtual file can present information from

  • 8/9/2019 Linux Device Driver Sum Up

    26/53

    the kernel to the user and also serve as a means of sending information

    from the user to the kernel.

    System call:

    Asystem call is used by application (user) programs to request service fromthe operating system.

    An operating system can access a system's hardware directly, but a

    user program is not given direct access to the hardware. This is done so

    that the kernel can keep the system safe and secure from malicious

    user programs.

    But often, a user program requires some information from the

    hardware (e.g., from a web camera to show you the picture), but it

    cannot get the information directly. So, it requests the operating

    system to supply it the information. This request is made by using anappropriate system call.

    System calls can be classified into six groups

    process management

    interprocess communication,

    memory management

    file system

    initialization and other.

    The kernel maintains a list of all registered system calls in the system call

    table. This table assigns each valid system call a unique system callnumber which cannot be changed or recycled. Processes do not refer to

    system calls by name, but rather by their system call number.

    There are 294 syscalls defined in a 2.6 linux kernel (#define NR_syscalls

    294). You can see the list at unistd.h file.

    Asystem call executes in the kernel mode.

    Every system call has a number associated with it. This number is

    passed to the kernel and that's how the kernel knows which system

    call was made.

    When a user program issues a system call, it is actually calling alibraryroutine.

    The library routine issues a trap to the Linux operating system by

    executing INT0x80assembly instruction.

    It also passes the system call number to the kernel using the EAX

    register.

  • 8/9/2019 Linux Device Driver Sum Up

    27/53

    The arguments of the system call are also passed to the kernel using

    other registers (EBX, ECX, etc.).

    The kernel executes the system call and returns the result to the user

    program using a register. If the system call needs to supply the userprogram with large amounts of data, it will use another mechanism

    (e.g., copy_to_user call).

    System calls: mechanism

    A process is able to use services provided by the kernel by making a

    system call [2].Every system call has a specific number.This number iswritten into the EAX register. There can be up to 6 parameters, which are

    set into the registers EBX, ECX, EDX, EDI, ESI and EBP. If a system call

    needs more than 6 values to pass, it has to use pointers to structures,

    where the additionalparameters are stored.

    To switch to kernel mode the software interrupt 0x80 is called and the

  • 8/9/2019 Linux Device Driver Sum Up

    28/53

    system call handler calls the system call services routine according to the

    system call number found in the EAX register. The address of every

    system call service routine is stored in the system call table. The system

    calls return value is stored in the EAX register.

    Each system call is multiplexed into the kernel through a single entry

    point. The eax register is used to identify the particular system call that

    should be invoked, which is specified in the Clibrary (per the call from the

    user-space application). When the C library has loaded the system call

    index and any arguments, a software interrupt is invoked (interrupt 0x80),

    which results in execution (through the interrupt handler) of the

    system_call function. This function handles all system calls, as identified

    by the contents of eax. After a few simple tests, the actual system call is

    invoked using the system_call_table and index contained in eax. Upon

    return from the system call, syscall_exit is eventually reached, and a

    call to resume_userspace transitions back to user-space. Execution

    resumes in the Clibrary, which then returns to the user application.

    This table, shown in Figure 2, uses the indexprovided in eax to identify

    which system call to invoke from the table (sys_call_table )

  • 8/9/2019 Linux Device Driver Sum Up

    29/53

    List of files to be modified or created

    Kernel files to be modified are listed below:

    /usr/src/linux/arch/i386/kernel/syscall_table.S Add an entry to system call

    dispatch table

    /usr/src/linux/include/asm-i386/unistd.h Include a macro definition for

    NR_XYZThis file contains the system call number that is passed to the

    kernel through the register (EAX) when a system call is invoked.

    /usr/src/linux/include/linux/syscalls.h This file contain the declarations for

    system calls. /usr/src/linux/Makefile

    New kernel files/directories to be created are listed below:

    /usr/src/linux/mycall - Directory that will contain the source file, header file

    and the Makefile for our system call (You can also implement your system

    call in an existing file).

    /usr/src/linux/mycall/mycall.c - Source file containing our system call code.

    Write the corresponding service routine in kernesource tree (e.g., sys_XYZ())

    CHUY cai ham nay duoc goi la Service Routine /usr/src/linux/mycall/Makefile Makefile

    New user space files, to be created, to test our system call are listed below:

    testmycall.c Source file that will call our system call.

    testmycall.h - Header file.

  • 8/9/2019 Linux Device Driver Sum Up

    30/53

    /usr/src/linux/arch/i386/kernel/syscall_table.S

    Add a line to the end of this file (Let's assume that the name of our system

    call is mycall).

    Add ".long sys_mycall" at the end of the list.

    /usr/src/linux/include/asm-i386/unistd.h

    This file contains the system call number that is passed to the kernel

    through the register (EAX) when a system call is invoked.

    Muc dich: ta khai bao so hieu number cho system call ma chung ta tao ra

    Add "#define __NR_mycall " at the end of the

  • 8/9/2019 Linux Device Driver Sum Up

    31/53

    list.

    If the last system call defined here is:

    "#define __NR_vmsplice316", then add:

    "#define __NR_mycall317" at the end of the list.

    Increment the "NR_syscalls" by 1. So, if NR_syscalls is defined as:

    "#define NR_syscalls 317", then change it to:

    "#define NR_syscalls 318"

    /usr/src/linux/include/linux/syscalls.h

    This file contain the declarations for system calls.

    Add the following line at the end of the file:

    "asmlinkage long sys_mycall(int i);"

    Nhu vay rang khi mycall() duoc goi thi no se goi den ham duoc khai bao

    nhu o tren va duoi hinh sau

    /usr/src/linux/Makefile

    Add mycall/ to core-y (Search for regex: core-y.*+=). You will be creating

    this directory. This directory will contain the source file, header file andthe Makefile for our system call.

    /usr/src/linux/mycall (new kernel files/directories to be created)

    Create a new directory in /usr/src/linux and name it "mycall"

    /usr/src/linux/mycall/mycall.c

    Create a source file named "mycall.c" in dir "mycall". mycall.c will have the

  • 8/9/2019 Linux Device Driver Sum Up

    32/53

    code for our system call. The definition of the system call in the source file

    would be asmlinkage long sys_mycall(...){...} . It should include the file

    linux/linkage.h So, the file "mycall.c" willlook like:

    Hoac chang han chung ta viet nhu sau:

    Asmlinkage is used to look for the arguments on the kernel stack.

    Reading and writing user memory

    The Linux kernelprovides several functions that you can use to move

    system call arguments to and from user-space. Options include simple

    functions for basic types (such as get_user or put_user). For movingblocks of data such as structures or arrays, you can use another set of

    functions: copy_from_user and copy_to_user . Moving

    null-terminated strings have their own calls: strncpy_from_user

    and strlen_from_user . You can also test whether a user-space

    pointer is valid through a call to access_ok. These functions are

  • 8/9/2019 Linux Device Driver Sum Up

    33/53

    defined in linux/include/asm/uaccess.h

    Moving simple types between the kernel and user-space (such as ints

    or longs) is accomplished easily with get_user and put_user. These

    macros each take a value and a pointer to a variable. The get_user

    function moves the value that the user-space address specifies (ptr)

    into the kernel variable specified (var). The put_user function moves

    the value that the kernel variable (var) specifies into the user-space

    address (ptr). The functions return zero on success:

    To move larger objects, such as structures or arrays, you can use the

    copy_from_user and copy_to_user functions. These functions move

    an entire block of data between user-space and the kernel. The

    copy_from_user function moves a block of data from user-space into

    kernel-space, and copy_to_user moves a block of data from the

    kernel into user-space:

    Finally, you can copy a NULL-terminated string from user-space to

    the kernel by using the strncpy_from_user function. Before calling

    this function, you can get the size of the user-space string with a call to

    the strlen_user macro:

    These functions provide the basics for memory movement between the

    kernel and user-space. Some additional functions exist (such as those

    that reduce the amount of checking performed). You can find these

    functions in uaccess.h.

    /usr/src/linux/mycall/Makefile

    The Makefile in dir "mycall" will have only one line:

    testmycall.h (new user space header file to be created) new user space files, to

  • 8/9/2019 Linux Device Driver Sum Up

    34/53

    be created, to test our system call

    Create a header file called testmycall.h. This header file should be

    included by any program calling our system call.

    Add three lines to it

    Line 1: This is needed because we need the definition of_syscall1.

    #include

    Line 2: This is needed because we need the number of our system ca ll

    #define __NR_mycall 317

    Line 3: This is needed for system calls with 1 argument. It is explained

    in detail below.

    _syscall1(long, mycall, int, i)

    So, our user header file looks like:

    The syscall0 macro takes two arguments. The first specifies the type of

    the value returned by the system call; the second argument is the name of the system

    call. The name is used to identify the system call number that is stored in the

    hardware register before the trap instruction is executed.

    Ifyour system call requires arguments, then a different macro (such as syscall0,

    where the suffix indicates the number of arguments) could be used to instantiate the

    assembly code required for performing the system call.

    The traditional method requires that you create function calls that match

    those in the kernel in terms of system call index (so that you're calling the

    right kernel service) and that the arguments match. Linuxprovides a set

    of macros to provide this capability. The _syscallN macros are defined in/usr/include/linux/unistd.h and have the following format:

  • 8/9/2019 Linux Device Driver Sum Up

    35/53

    testmycall.c (new user space source file to be created)

    Create a C file called testmycall.c in the same directory as testmycall.h. The C

    file willlook like:

    Return Value:Long integer (in 32-bit architecture) (unsigned long)0(unsigned long)(-126):System call succeeded

    (unsigned long)(-125)(unsigned long)(-1)

    System call failed

    Set errno.

    CHU Y: khi lap trinh chung ta co the su dung cac loai cau lenh sau:get_user(), put_user(),copy_from_user(), copy_to_user(), ...

    12.Virtual File system Switch (VFS)

    The principal interface between a device driver and t he rest of the

    Linux kernel comprises a set of standard entry points and driver

    specific data structures

  • 8/9/2019 Linux Device Driver Sum Up

    36/53

    Listing 2 illustrates how the entry points are registered with the

    Virtual File system Switch using the file_operations structure.

    This structure, which is defined in /usr/include/linux/fs.h ,

    constitutes a list of the functions written for the driver. The

    initialization routine, xxx_init()registers the file_operationsstructure with the VFS and allocates a major number for the device.

    Name space

    The name of the driver should be a short string. Throughout this

    article we have used "xxx" as our device name.

    For instance, the parallel (printer) device is the `lp'' device,

    the floppies are the `fd'' devices, and the SCSI disk s are the

    ``sd'' devices.

    To avoid name space confusion, the entry point names are formedby concatenating this unique driver prefix with a generic name

    that describes the routine.For instance, xxx_open() is the

    ``open'' routine for the ``xxx'' driver.

    13.Driver implementation in Linux

    Writing LinuxDevice Driver Header files

  • 8/9/2019 Linux Device Driver Sum Up

    37/53

    #include

    Writing LinuxDevice Driver #include

    #include

    #include #include

    #include

    #include

    Writing LinuxDevice Driver Initialize register (clear)

    static int test_open(struct inode *inodePtr, struct file *fp)

    {

    printk( "Enter open routine.n" );

    return 0;

    }static int test_release(struct inode *inodePtr, struct file *fp)

    {

    MOD_DEC_USE_COUNT;

    printk( "Enter test_releasen" );

    return 0;

    }

    Writing LinuxDevice Driver Operation

    static ssize_t test_read(struct file *fp, char *buf, size_t len, loff_t *offset){

    printk( "Enter test_readn" );

    return len;

    }

    static ssize_t test_write(struct file *fp, char *buf, size_t len, loff_t *offset)

    {

    printk( "Enter test_writen" );

    return len;

    }

    Writing LinuxDevice Driver Mapping

    struct file_operations test_fops =

    {

    read: test_read,

  • 8/9/2019 Linux Device Driver Sum Up

    38/53

    write: test_write,

    open: test_open,

    release: test_release,

    ioctl: test_ioctl,};

    Writing LinuxDevice Driver

    static int test_ioctl(struct inode *inodePtr, struct file *fp, unsigned int cmd,

    unsigned long arg)

    {

    switch( cmd ){

    default:

    break;

    }return 0;

    }

    Writing LinuxDevice Driver Entry point V.S. Exit point

    int test_init_module(void)

    {

    register_chrdev( 100, testName, &test_fops );

    printk( "Init test modulen" );

    return 0;}

    void test_cleanup_module(void)

    {

    unregister_chrdev( 100, testName );

    printk( "UnInit testn" );

    }

    module_init ( test_init_module );

    module_exit ( test_cleanup_module );

    Using Interrupts

    void foo_interrupt(unsigned int irq, struct pt_reg *reg);

    irq is the number of the irq which triggered this routine

    regs is a copy of the CPU registers

    Create Environment

  • 8/9/2019 Linux Device Driver Sum Up

    39/53

    Compiler: gcc -D__KERNEL__ -DMODULE -I/usr/src/linux-2.4.22/include

    -c -O -Wall drv.c -o drv.o

    Make node: mknod /dev/test c 100 0

    Check node:crw-rw-rw- 1 root dialout 4, 64 Jun 30 11:19 test

    crw-rw-rw- 1 root dialout 4, 65 Aug 16 00:00 ttyS1

    Writing Application

    int main(int argc, char *argv[])

    {

    int fd;

    char buf[256] = "Hello World!!";

    fd = open( "/dev/test, O_RDWR );

    if ( fd == -1 ){

    printf( "Open drv driver fail.[Application]n );

    return -1;

    }

    write( fd, buf, 6 );

    close( fd );

    return 0;

    }

    14.Accessing Hardware Memory

    A Linux user process can not access physical memory directly.

    The memory management sc heme which is a demand paged virtual

    memory system means that each process has its own address space

    (user virtual address space ) that begins at virtual location

    zero.

    The kernel has its own distinct address space known as the systemvirtual address space .

    De chuyen du lieu tu user space vao kernel space: The device driver

    copies data between the kernel'y s address space and the user

    program'ys address space whenever the user makes a read()or write()

    system call

  • 8/9/2019 Linux Device Driver Sum Up

    40/53

    Several Linux routines such as, memcpy_*fs() and put_fs*()

    enable device drivers to transfer data across the usersystem

    boundary.Data may be transferred in bytes, words, or in buffers

    of arbitrary sizes

    For example, memcpy_fromfs() transfers an arbitrary number of

    bytes of data from user space to the device, while get_fs_byte()

    transfers a byte of data from user space.

    Similarly, memcpy_tofs() and put_fs_byte() write data to user

    space memory

    De chuyen du lieu tu kernel space den driver: The transfer of data

    between the memory accessible to the kernel and the device itself

    is machine dependent.

    Some machines require that the CPU execute specia l I/Oinstructions to move data between a device register and

    addressable memory often called direct memory access (DMA).

    Another scheme, known as memory mapped I/O , implements the

    device interface as one or more locations in the memory address

    space.

    The most common method uses I/O instructions, provided by

    the system to allow drivers access the data in a general way

    Linux provides inb() to read a single byte from an I/O address

    (port) and outb() to write a single byte to an I/O address.The calling syntax is shown here:

    unsigned char inb(int port)

    outb(char data, int port)

    15.Writing a Character Device Drive

    Operation Modes

    Polling

    Interrupt

    DMA xxx_write(): The xxx_writ e() routine transfers a character string

    of count bytes from the user space memory to the device.

    Using interrupts, the hardware is able to interrupt when it is

    ready to transfer data and so there is no waiting.

    chung ta se co 2 cach viet cho driver: Interrupts vs. Polling

  • 8/9/2019 Linux Device Driver Sum Up

    41/53

    In a polling driver:

    Ham nay se duoc viet trong xxx.c

    Interrupt-driven drivers are a little more difficult. Here is an example of a

    xxx_write() that is interrupt-driven:

  • 8/9/2019 Linux Device Driver Sum Up

    42/53

  • 8/9/2019 Linux Device Driver Sum Up

    43/53

    memcpy_fromfs() transfers an arbitrary number of bytes of

    data from user space to the device,

    xxx_table[] is an array of structures, eac h of which have

    several members. Some of the members include

    xxx_wait_queue and bytes_xfered , which are used for both

    reading and writing. The interrupt handling code can use

    either request_irq() or irqaction() in the xxx_open()

    routine to call xxx_irq[] is an array of 16 integers, and is used for looking up which

    entry in xxx_table[] is associated with the irq generated and

    reported to the xxx_interrupt() function.

    To tell the interrupt-handling code to callxxx_interrupt() , you need

    to use either request_irq() or irqaction().This is either done

    when xxx_open() is called, or if you want to keep things simple, when

    xxx_init()is called. request_irq() is the simpler of the two, and

    works rather like an old-style signal handler. It takes two arguments:

    the first is the number of the irq you are requesting, and the second isa pointer to your interrupt handler, which must take an integer

    argument (the irq that was generated) and have a return type ofvoid.

    request_irq() returns -EINVAL ifirq > 15 or if the pointer to the

    interrupt handler is NULL, -EBUSY if that interrupt has already been

    taken, or 0 on success.

  • 8/9/2019 Linux Device Driver Sum Up

    44/53

    16.Device Driver Initialization

    In order that the device driver is correctly initialized when the

    operating system is booted, the xxx_init() routine must be executed.

    To ensure this happens, add the following line to the end of the

    chr_drv_init() function in the /usr/src/linux/driver/char/mem.c

    file:

    mem_start = xxx_init(mem_start);

    and resave the file back to disk.

    17.Installing the Driver in the Kernel

    Besides functions defined by the file_operations structure, there is at least

    one other function that you will have to write, the xxx_init() function.

    In order that the device driver is correctly initialized when the

    operating system is booted, the xxx_init() routine must be executed.

    To ensure this happens, add the following line to the end of the

    chr_drv_init() function in the /usr/src/linux/driver/char/mem.c

    file:

    mem_start = xxx_init(mem_start);

    and resave the file back to disk.

    xxx_init() should first callregister_chrdev() to register itself and avoiddevice number contention.

  • 8/9/2019 Linux Device Driver Sum Up

    45/53

    int major: This is the major number which the driver wishes to a llocate

    char *name: This is the symbolic name of the driver. This is used, among

    other things, to report the driver's name in the /proc filesystem.

    struct file_operations * xxx_ops (xxx: la ten cua driver): This

    is the address of your file_operations structure.

    Returns:

    0 if no other character device has registered with the same major

    number.

    non-0 if the call fails, presumably because another character devicehas already allocated that major number.

    File Operation on Block Devices

  • 8/9/2019 Linux Device Driver Sum Up

    46/53

    18.Writing LinuxDevice Driver Header files

    #include #include

    #include

    #include

    #include

    #include

    #include

    19.Device File Creation

    In order to access the device using system calls, a special file

    is created. The driver files are normally stored in the /dev

    directory of the system. The following commands create the special

    device file:

    mknod /dev/xxx c 22 0

  • 8/9/2019 Linux Device Driver Sum Up

    47/53

    Creates a special character file named xxx and gives it major number

    22 and minor number 0.

    chmod 0666 /dev/xxx

    Ensures that every user in the system has read/write access to the

    device.

    20.System call and Library Function call

    If you are a C programmer on GNU/Linux and have not used system

    calls,then you must have used the library functions

    A set of functions available in the standard library that is shipped

    with the C compiler for Linux and nonLinux system.

    On Linux systems,these library functions are built on top of the

    system calls.

    system call is built into the kernel. The standard C library offers separate functions to read a block

    of data(fread),and a line(fgets),and a single character(fgetc). All

    these functions ultimately invoke the only system call available

    for reading input read

    using system call is usually the most efficient way to perform I/O

    operations and is some timemore convenient ,too.

    A call to a library function is just like any other function call.

    The arguments are placed in the processor register or on to the

    stack ,and execution is transfered to the start of the function'scode.

    when a program makes system calls ,the arguments are packaged up

    and handed to the kernel ,which takes over execution of the program

    untill the call completes.

    C language:

    The first I/O function you likely encountered when you first

    learned the C language was printf.This formats a text string and

    then prints it to standard output.

    The generalized version, fprintf, can print the text to a streamother than standard output.

    A stream is represented by a FILE* pointer.

    You obtain a FILE* pointer by opening a file with fopen.

    When youre done, you can close it with fclose. In addition to fprintf, you can use such functions as fputc,

  • 8/9/2019 Linux Device Driver Sum Up

    48/53

    fputs, and fwrite to write data to the stream, or fscanf, fgetc,

    fgets, and fread to read data.

    With the Linux low-level I/O operations, you use a handle called

    a file descriptor instead of a FILE* pointer. Include the header files , if you use any

    of the lowlevel I/O functions described here.

    Open

    Close

    Read

    Write

    Opening a File Using Open Call

    You don't need to open a file to access its attributes.

    But,you can't read or write a file unless you first open it. To create a new file descriptor,we need to use the open system

    call.

    It takes as arguments the path name of the file to open, as

    a character string, and flags specifying how to open it(read

    or write).

    You can use open to create a new file; if you do, pass a third

    argument that specifies the access permissions to set for

    the new file.

    Open returns the file descriptor (nonnegative integer) ifsuccessful,or 1if it fails.

    If the second argument is O_RDONLY(or 0), the file is opened

    for reading only.

    O_WRONLY(or 1) ,the file is opened for writing only.

    O_RDWR produces a file descriptor that can be used both for

    reading and for writing.

    You can specify additional options by using the bitwise or

    of this value with one or more flags.

    These are the most commonly used values: Specify O_CREAT to create a new file. If the filename that

    you provide to open does not exist.

    Specify O_EXCL with O_CREAT to force creation of a new

    file. If the file already exists, the open call will fail.

    Closing a File Using Close call

  • 8/9/2019 Linux Device Driver Sum Up

    49/53

  • 8/9/2019 Linux Device Driver Sum Up

    50/53

    HEADER

    Contains pointers that allow it to chain to other drivers loaded

    in the system

    First doubleword ( -1) informs that this is last driver in chain. It is followed by attribute word, which indicates type of header

    included for driver and type of device the driver installs

    The structure of the header attribute word

  • 8/9/2019 Linux Device Driver Sum Up

    51/53

    Strategy Procedure

    It is called whenever device driver is loaded in to memory or

    whenever I/O requests are issued

    Its main purpose is to save the Request header and its address Return Status Word Communicates information back to DOS from

    Device Driver.

    INTERRUPT PROCEDRE

    It uses request header to determine the function requested by

    DOS.

    It performs all functions for Device Driver

    Interrupt Procedure is different from Interrupt Handler.

    22.Definition ofDevice

    23.Useful Functions #include

    int printk(char *fmt, ...);

    24.VFS Functions

    inode and filp are big kernel structures with data regarding the file and the

    device . See

    inode: A data structure holding information about files in a Unix file

    system. There is an inode for each file and a file is uniquely identified bythe file system on which it resides and its inode number on that system.

    Each inode contains the following information:

    the device where the inode resides,

    locking information,

    mode and type of file,

    the number oflinks to the file,

    the owner's user and

    group ids,

    the number of bytes in the file, access and modification times,

    the time the inode itself was last modified and

    The addresses of the file's blocks on disk.

    some inportant members

    inode->i_rdev: device number of this device, use

  • 8/9/2019 Linux Device Driver Sum Up

    52/53

    MINOR(inode->i_rdev) and MAJOR(inode->i_rdev);

    all share the same MAJOR number, but are distinguished by their

    MINOR numbers

    unsigned int minor = MINOR(inode->i_rdev); /* minor number of device */

    ERRNO is one of the error numbers from . Some useful

    ERRNOs are

    ENODEV - no such device

    EBUSY - device busy

    EINVAL - invalid operation

    fill in the file_operations struct

    use NULL for not-implemented members. For example:

    25.Giai thich cac cau lenh trong lap trinh driver

    interruptible_sleep_on(&xxx_wait_queue); set timeout in case interrupt is

    missed. xxx_wait_queue is a FIFO queue of processes that are sleeping; once

    initialized (to NULL) the kernel handles the queue and to access it, then supply

    a pointer

  • 8/9/2019 Linux Device Driver Sum Up

    53/53

    26.

    27.


Recommended