# Device drivers migration in Linux — Liran Tal

Moving from linux 2.4 to 2.6 by recompiling linux kernel device drivers

Canonical: https://lirantal.com/blog/2007-10-15

Migrating drivers is always a fun thing to do.

All most all migrations of device drivers from a 2.4 kernel to a 2.6 kernel has one thing in common and that’s handling of device node registration. If the 2.6 kernel supports `devfs` (`CONFIG_DEVFS_FS`) then it may be possible that API changes are very small if any although if the 2.6 version of the kernel you’re running doesn’t support `DEVFS` and requires manually allocating major and minor numbers to the new /dev structure then you’re up to some work, nothing too serious of course.

So this is really just the basics of things, starting with the includes it is possible to add backward compatibility for the driver to compile on a 2.4 kernel as well with something along the lines of:

```
#ifdef CONFIG_DEVFS_FS
#include

#else
#include
#endif
```

Then we need to deal with major and minor numbers, specifically if this is some third party, vendor owned driver then it is common that they make up major/minor pairs of their own imagination, thus:

```
#ifndef CONFIG_DEVFS_FS
#define DRV_MAJOR 200
#define DRV_MINOR 99
#define DRV_COUNT 1
char dev_name_DRV[] = "sample_drv";
#endif
```

when defining the driver’s structure there’s also a distinction that has to be made in how the device node is approached, and so:

```
typedef struct gpio_dev_stc {
int device_id;
char drvif_name[80];
#ifdef CONFIG_DEVFS_FS
devfs_handle_t handle;
#else
int major;
#endif
struct proc_dir_entry *procfs_entry;
} DRV_DEV;
```

And we continue on with these distinctions:

```
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_dir_handle = NULL;
#else
static char devname[]="0";
static struct cdev drv_cdev;
#endif
```

Then we can jump right away to the `__init` module function and make appropriate changes for device registration, starting by defining 2 new variables:

```
int retval;
dev_t dev_id;
```

and then, for the actual device registration code

```
drv_dev->major = DRV_MAJOR;
if (drv_dev->major) {
dev_id = MKDEV(drv_dev->major, DRV_MINOR);
retval = register_chrdev_region(dev_id, DRV_COUNT, devname);
} else {
retval = alloc_chrdev_region(&dev_id, DRV_MINOR, DRV_COUNT, devname);
drv_dev->major = MAJOR(dev_id);
}

if (retval) {
printk(KERN_ERR "%s: can't get drivers major! %d\n", devname, drv_dev->major);
return -1;
}

cdev_init(&drv_dev, &drv_fops);
cdev_add(&drv_cdev, dev_id, DRV_COUNT);
```

and of course unregistering the driver is also required, so adding to `__exit` the following:

```
dev_t dev_id = MKDEV(drv_dev->major, 0);

cdev_del(&drv_cdev);
unregister_chrdev_region(dev_id, DRV_COUNT);
```

And we’re mostly done.

Don’t make of it a template, it’s simple an overview to give some general idea of how the API changes in 2.6 and how you can deal with device drivers migration.

## More writing

[All writing →](/blog)

*   Sep 5, 2026

    ### [Self-Hosting Hermes Agent with Matrix E2EE on Proxmox](/blog/self-host-hermes-agent-matrix-e2ee-proxmox)

*   Aug 2, 2026

    ### [The Practical Second Brain: Building an LLM-Operated Markdown Knowledge Graph](/blog/practical-second-brain-llm-markdown-knowledge-graph)

*   Aug 1, 2026

    ### [Building a Second Brain with LLMs and AI Agents](/blog/building-second-brain-llms-ai-agents)


* * *

Liran Tal is the author of the book [Node.js Secure Coding: Defending Against Command Injection Vulnerabilities](https://www.nodejs-security.com/)

[Start Building Secure Node.js Applications ↗](https://www.nodejs-security.com/)

 [![](/_astro/nodejs-secure-coding-book-3d-style.DiTWpzFs_Z3c7s1.png)](https://www.nodejs-security.com/)
