Writing a Linux Driver
Access to the hardware interface (the card) is provided through low-memory addressing. The I/O registers of the card, where we can read/write information, are physically connected to memory addresses of the PC (i.e., ports). For instance, the motor/sonar card of the MRV-4 mobile robot is associated with the address 0x1b0. Sixteen registers are used in this card, so the port map includes addresses from 0x1b0 to 0x1be. A typical list of port addressing is shown in Table 1.:
Table 1. Typical Port Addresses
A free address region must be found to allocate the ports for the new card. In Table 1, addresses from 1b0 to 1be were free. The source code example, foo.c, is available on the SSC FTP site (see end of article) and includes a call to a system function that allows us to see the previous table of addresses. Finally, access to the ports is granted via the functions inb_p and outb_p.
Interrupts are the other main topic when talking about low-level programming and hardware control. Interrupt handling versus polling has the main advantage that hardware is usually slow. We cannot stop all processes in a computer until a printer finishes a job. Instead, we can continue with normal work until the printer finishes, then send an interrupt signal that is handled by a specific function.
Continuing with our example, we need three handlers, one for each of the hardware interrupts that the card can generate: sonars handler (at irq 0x0a), home handler (at irq 0x0b) and bumper handler (at irq 0x0c). As example of what the source code must do, we show the structure of the sonar_irq_hdlr function. Each time an echo from a sonar is received, it must:
Disable hardware interrupts.
Read sonar value from its port and store it in a driver internal variable.
Enable interrupts again.
If a user program wants to read the incoming data from the sonars, it must perform a mrv4_read operation, which returns the data stored in the internal variables of the driver.
Although we will explain the guidelines to implement each of the driver functions, when programming your own driver it is a good idea to use the driver most similar to yours as an example. In our case, the models for mrv4.c and mrv4.h are lp.c and lp.h, respectively.
The file mrv4.c includes the initialisation and I/O functions. The initialisation function mrv4_init must follow these steps (see guidelines in file foo.c):
Check in the device.
Get a free region for port addressing.
Test if hardware is present.
Test if irq numbers are free.
Initialise driver internal variables.
Return an OK status.
If an error is detected in any of these steps, it must undo all previous operations and return an error status. To implement the I/O functions, the following structure (or similar) must be defined and initialized in mrv4.c:
static struct file_operations mrv4_fops = {
NULL, /* mrv4_lseek */
mrv4_read, /* mrv4_read */
mrv4_write, /* mrv4_write */
NULL, /* mrv4_readdir */
NULL, /* mrv4_select */
mrv4_ioctl, /* mrv4_ioctl */
NULL, /* mrv4_mmap */
mrv4_open, /* mrv4_open */
mrv4_release /* mrv4_release */
};
Pointers to all existent I/O functions must be set in this structure. Then, the I/O function code can be implemented, following the guidelines shown in the sidebar.
The available commands are defined in the file mrv4.h (see guidelines in file foo.h also available on the FTP site):
#define MRV4_MAGIC, 0x07
#define MRV4_RESET _IO(MRV4_MAGIC, 0x01
#define MRV4_GOTOHOME _IO(MRV4_MAGIC, 0x02
#define MRV4_RESETHOME _IO(MRV4_MAGIC, 0x03
#define MRV4_JOYSTICK _IOW(MRV4_MAGIC, 0x04,
unsigned int
#define MRV4_PREPMOVE _IOW(MRV4_MAGIC, 0x05,
unsigned int
#define MRV4_INITODOM _IO(MRV4_MAGIC, 0x06
#define MRV4_SONTOFIRE _IOW(MRV4_MAGIC, 0x07,
unsigned int
The _IO macro is used for commands without arguments. The _IOW is used for commands with input arguments. In this case, the macro needs the argument type, for example a pointer might be of type unsigned int. The magic number must be chosen by the programmer. Try to select one not reserved by the system (see other header files at /usr/include/linux). Constants are defined in the file /usr/include/linux/mrv4.h, which must be included by both the driver (mrv4.c) and the user programs. In general, the mrv4.h file can include:
Constants and macros definitions
ioctl commands
Port names
Type definitions
Data structures to be exchanged between the driver and the user
mrv4_init() function prototype
Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
| Trying to Tame the Tablet | May 08, 2013 |
| Dart: a New Web Programming Experience | May 07, 2013 |
- RSS Feeds
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Drupal Is a Framework: Why Everyone Needs to Understand This
- A Topic for Discussion - Open Source Feature-Richness?
- Home, My Backup Data Center
- Dart: a New Web Programming Experience
- Developer Poll
- What's the tweeting protocol?
- May 2013 Issue of Linux Journal: Raspberry Pi
- Reply to comment | Linux Journal
3 hours 32 min ago - Reply to comment | Linux Journal
4 hours 18 min ago - Web Hosting IQ
5 hours 52 min ago - Thanks for taking the time to
7 hours 29 min ago - Linux is good
9 hours 27 min ago - Reply to comment | Linux Journal
9 hours 44 min ago - Web Hosting IQ
10 hours 14 min ago - Web Hosting IQ
10 hours 14 min ago - Web Hosting IQ
10 hours 15 min ago - Reply to comment | Linux Journal
13 hours 16 min ago




Comments
I like this one
Good introduction, I think, for those who is not familiar with Linux drivers at all.
Thanks a lot to the author. I enjoyed the article.
This article twice uses the
This article twice uses the term "protected mode" where it should be using the term "supervisor mode".
Protected mode is a mode of the Intel x86 processor which provides various protection features, such as memory protection and the ability to disable privileged instructions. Under Linux, all software runs in protected mode, but user applications run at a different privilege level to the kernel.
Of course this article is quite out of date (though surprisingly much of it is still relevant) but on this point it was wrong even back when it was written.
sidebar & port table ?
where is the sidebar & port table that were discussed in this article..?
links and sidebars
This is not the magazine so there are no "sidebars" Check the links in the articles they have what you are looking for.
"I have always wished that my computer would be as easy to use as my telephone.
My wish has come true. I no longer know how to use my telephone."
-- Bjarne Stroustrup