Reader small image

You're reading from  Linux Device Drivers Development

Product typeBook
Published inOct 2017
Reading LevelIntermediate
PublisherPackt
ISBN-139781785280009
Edition1st Edition
Languages
Right arrow
Author (1)
John Madieu
John Madieu
author image
John Madieu

John Madieu is an embedded Linux and kernel engineer living in Paris, France. His main activities consist of developing device drivers and Board Support Packages (BSPs) for companies in domains such as IoT, automation, transport, healthcare, energy, and the military. John is the founder and chief consultant at LABCSMART, a company that provides training and services for embedded Linux and Linux kernel engineering. He is an open source and embedded systems enthusiast, convinced that it is only by sharing knowledge that we can learn more. He is passionate about boxing, which he practiced for 6 years professionally, and continues to channel this passion through training sessions that he provides voluntarily.
Read more about John Madieu

Right arrow

Kernel habits

The kernel code tried to follow standard rules throughout its evolution. In this chapter, we will just be introduced to them. They are all discussed in a dedicated chapter; starting from Chapter 3, Kernel Facilities and Helper Functions, we get a better overview of the kernel development process and tips, up to Chapter 13, Linux Device Model.

Coding style

Before going deep into this section, you should always refer to the kernel coding style manual, at Documentation/CodingStyle in the kernel source tree. This coding style is a set of rules you should respect, at least if you need to get patches accepted by kernel developers. Some of these rules concern indentation, program flow, naming conventions, and so on.

The most popular ones are:

  • Always use a tab indentation of eight characters, and the line should be 80 columns long. If the indentation prevents you from writing your function, it is because this one has too many nesting levels. One can size the tabs and verify the line size using a scripts/cleanfile script from the kernel source:
scripts/cleanfile my_module.c 
  • You can also indent the code correctly using the indent tool:
      sudo apt-get install indent
      scripts/Lindent my_module.c
  • Every function/variable that is not exported should be declared as static.
  • No spaces should be added around (inside) parenthesized expressions. s = size of (struct file); is accepted, whereas s = size of( struct file ); is not.
  • Using typdefs is forbidden.
  • Always use /* this */ comment style, not // this:
    • BAD: // do not use this please
    • GOOD: /* Kernel developers like this */
  • You should capitalise macros, but functional macros can be in lowercase.
  • A comment should not replace code that is not illegible. Prefer rewriting the code rather than adding a comment.

Kernel structure allocation/initialization

The kernel always offers two possible allocation mechanisms for its data structures and facilities.

Some of these structures are:

  • Workqueue
  • List
  • Waitqueue
  • Tasklet
  • Timer
  • Completion
  • mutex
  • spinlock

Dynamical initializers are all macros, which means they are always capitalized: INIT_LIST_HEAD(), DECLARE_WAIT_QUEUE_HEAD(), DECLARE_TASKLET( ), and so on.

These are all discussed in Chapter 3, Kernel Facilities and Helper Functions. Data structures that represent framework devices are always allocated dynamically, each having its own allocation and deallocation API. These framework device types are:

  • Network
  • Input device
  • Char device
  • IIO device
  • Class
  • Framebuffer
  • Regulator
  • PWM device
  • RTC

The scope of the static objects is visible in the whole driver, and by every device this driver manages. Dynamically allocated objects are visible only by the device that is actually using a given instance of the module.

Classes, objects, and OOP

The kernel implements OOP by means of a device and a class. Kernel subsystems are abstracted by means of classes. There are almost as many subsystems as there are directories under /sys/class/. The struct kobject structure is the centerpiece of this implementation. It even brings in a reference counter, so that the kernel may know how many users actually use the object. Every object has a parent, and has an entry in sysfs (if mounted).

Every device that falls into a given subsystem has a pointer to an operations (ops) structure, which exposes operations that can be executed on this device.

Previous PageNext Page
You have been reading a chapter from
Linux Device Drivers Development
Published in: Oct 2017Publisher: PacktISBN-13: 9781785280009
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
John Madieu

John Madieu is an embedded Linux and kernel engineer living in Paris, France. His main activities consist of developing device drivers and Board Support Packages (BSPs) for companies in domains such as IoT, automation, transport, healthcare, energy, and the military. John is the founder and chief consultant at LABCSMART, a company that provides training and services for embedded Linux and Linux kernel engineering. He is an open source and embedded systems enthusiast, convinced that it is only by sharing knowledge that we can learn more. He is passionate about boxing, which he practiced for 6 years professionally, and continues to channel this passion through training sessions that he provides voluntarily.
Read more about John Madieu