How tty drivers work

From Crashcourse Wiki

Jump to: navigation, search

Contents

[edit] Overview

Follow the code that explains these character devices in /proc/devices:

  ...
  5 /dev/tty
  5 /dev/console
  5 /dev/ptmx
  5 ttyprintk
  ...
That is, how do those different tty drivers all end up with major number 5?

From include/linux/major.h:

#define TTYAUX_MAJOR            5

[edit] /proc/tty/drivers

$ cat /proc/tty/drivers
/dev/tty             /dev/tty        5       0 system:/dev/tty
/dev/console         /dev/console    5       1 system:console
/dev/ptmx            /dev/ptmx       5       2 system
/dev/vc/0            /dev/vc/0       4       0 system:vtmaster
rfcomm               /dev/rfcomm   216 0-255 serial
ttyprintk            /dev/ttyprintk   5       3 console
serial               /dev/ttyS       4 64-111 serial
pty_slave            /dev/pts      136 0-1048575 pty:slave
pty_master           /dev/ptm      128 0-1048575 pty:master
unknown              /dev/tty        4 1-63 console
$

The source for this file is in fs/proc/proc_tty.c.

[edit] drivers/char/tty_io.c

struct tty_driver *alloc_tty_driver(int lines)
{
        struct tty_driver *driver;

        driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
        if (driver) {
                kref_init(&driver->kref);
                driver->magic = TTY_DRIVER_MAGIC;
                driver->num = lines;
                /* later we'll move allocation of tables here */
        }
        return driver;
}
EXPORT_SYMBOL(alloc_tty_driver);

[edit] drivers/tty/tty_io.c

/*
 * Ok, now we can initialize the rest of the tty devices and can count
 * on memory allocations, interrupts etc..
 */
int __init tty_init(void)
{
        cdev_init(&tty_cdev, &tty_fops);
        if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
                panic("Couldn't register /dev/tty driver\n");
        device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");

        cdev_init(&console_cdev, &console_fops);
        if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
                panic("Couldn't register /dev/console driver\n");
        consdev = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
                              "console");
        if (IS_ERR(consdev))
                consdev = NULL;
        else
                WARN_ON(device_create_file(consdev, &dev_attr_active) < 0);

#ifdef CONFIG_VT
        vty_init(&console_fops);
#endif
        return 0;
}

[edit] The examples (all major number 5)

[edit] drivers/char/ttyprintk.c

static int __init ttyprintk_init(void)
{
        int ret = -ENOMEM;
        void *rp;

        ttyprintk_driver = alloc_tty_driver(1);
        if (!ttyprintk_driver)
                return ret;
Personal tools