
Character Drivers and Kernel Devlopment
- 7 minsIn my free time I have been learning the C programming language. With current proficiencies in bash, python, javascript, and …yaml…if you want to call it ar (markup) language, I thought it would be easy. What I quickly learned is that I should have learned C first and then learned all the other languages after! My goal in learning C is to become a kernel/driver developer. This blog is to try and explain a list of what I have learned and built so far. Below is a list of what I’m trying to convey with the presumption that your technically savvy and understand Linux enough to be dangerous.
My objective
- What is a device drivers
- What is a character driver
- What I have built so far
Device Drivers
So, Linux is an operating system, maybe we should start there. Device drivers are programs written and baked into the Linux Kernel (or any kernel for that matter) that help communicate with hardware. Its the magic that has software and hardware tango on the digital dance floor. Drivers for Bluetooth and Usb for example help with connecting your apple airpods to your iphone. Without drivers most devices couldn’t be recognized and communicate properly. Dave’s Garage youtube channel explains Blue screens of Death that used to haunt Windows systems back in the day. Many blue screen errors, at least the ones that got me into my tech journey are bug checks or error messages that halt system operations to prevent futher damage of your system. These bug checks or cracks can be attributed to device drivers being loaded, unloaded, or functioning incorectly. They are typically warning signs that a device driver wasn’t able to function but Blue screens can also be things like segfaults and memory leaks, not just device failure (that was merely an example). A better example of device drivers would be the magic that happens when you plug your printer into your computer. Your computer searches for that printer and downloads drivers for that printer so that the printer and computer can do commands like print, scan, and copy. These drivers use memory management, file operations, and a lot of other parts on your computer that need to be checked within the user space of your computer.
User Space and Kernel Space
The user space and kernel spaces are two specific memory regions on your computer that have different purposes and access rights. The user space is where applications, user-facing programs, and some drivers will run in memory. Adobe Photoshop is an application in the user space that takes up memory on your computer. When you check the running processes on your computer or double click chrome to open up your web browser your using software in the user space that is connecting to available memory to run processes on your computer in the user space. The Kernel space is reserved for operating system memory calls and kernel extensions. A driver driver is part of a kernel extention. So if you click on your printer settings to print a test page, there is a conversation between the kernel space and user space to handle memory allocation and file operations that need to be performed for the computer to communicate back to the printer and have the printer continue to print that test page.
In UNIX, hardware devices are accessed by the user through special device files. These files are grouped into the /dev directory, and system calls open, read, write, close, lseek, mmap etc. are redirected by the operating system to the device driver associated with the physical device. The device driver is a kernel component (usually a module) that interacts with a hardware device.
Device Files
In the UNIX world there are two categories of device files a.k.a device drivers: character and block.
In one category, there are slow devices, which manage a small amount of data. Such access to data does not require frequent queries. Examples are devices like a keyboard, mouse, serial ports, sound card, or joystick. In general, these read and write operations are performed sequentially byte by byte.
The second category includes devices where data volume is large, data is organized on blocks, and search is common or frequent. Examples of devices that fall into this category are hard drives, cdroms, and ram disks. With those devices, reading and writing is done at the data block level.
Character drivers
Character device drivers, or character drivers support devices being handled within the kernel and user space. Character devices support byte streams; that is, data sent from one place in memory to another must be broken into bytes before being transferred across an operating system’s memory space
File operations, console drivers, embedded systems like UART and more can be considered as character drivers. Typical character drivers are serial drivers and console drivers.
Character drivers (cont)
A character-device interface is a set of subroutines that control access to such devices. This means only one program can use the device at a time, but other programs can still use it through the same interface. Character drivers are used by user programs and system programs, however, there are some differences between them:
In the case of User Programs: User programs use the interface directly without any help or instructions from system software or hardware drivers. They don’t need to know how their requests are handled by the operating system because they do not write any code themselves.
In the case of System Programs: System programs must always have some knowledge about how they interact with hardware. They often depend on external libraries like libc which has additional functions needed for accessing devices in Linux systems. System programs are also able to use their own device drivers, which are software that allows the operating system to interact with hardware devices.
A good example of System programs that use their own drivers would be software like Crowdstrike and how it uses its own drivers that, when untested, can cause nationwide system failure like the 2024 CrowdStrike-related IT outages.
In layman’s terms
In Linux, a device driver is a piece of software that allows the operating system to communicate with hardware devices, like a keyboard or printer, by translating system commands into instructions the hardware understands. A character driver is a specific type of device driver that handles character-based devices, such as serial ports or keyboards, which deal with streams of data rather than blocks of data like a hard drive. Idealy, character drivers manage devices that don’t need to store data in fixed chunks, while other device drivers, like block drivers, handle storage devices. Both act like a bridge between the Linux system and your hardware.
- Device driver example: printer drivers that connect a printer to a computer
- Character driver example: the stream of data that handles opearions that get a printer to print a stream of data onto a blank sheet of paper.
What’s been done so far
In my free time I have been doing my best to put it all together using books like The C programming language 2nd edition, Linux Kernel Development, and Linux Device Drivers. I’m doing my best to “build in public” and keep a live record of all the fun and faults im making in learning all of this.
SO FAR
- Learned C programming and created loops, arrays, switch statements, temp coverters.
- I’m actively working on goggles
- created a hello world module
- created an character module
the character module is currently printing kernel notices echoing “Hello world and Good bye” as of writing this blog post, but will be handling file operations soon.
In Conclusion
Now that I have found some free time as a parent of smart 3 year old, I should be sharing more my journey into kernel development. We will see how that goes. To keep following my journey on what im building or learn by doing yourself you can clone or download this repo link. The books were discovered online in public spaces like reddit but ill make sure to have resouces below if you wanted to buy they and have copies or send financial love to the authors and people behind the books.
Resources
- Linux Kernel Development by Robert Love
- Linux Device Drivers by Greg Kroah-Hartman
- The C Programming Language 2nd edition by Brian Kernighan and by Dennis Ritchie