Главная » Просмотр файлов » Linux Device Drivers 2nd Edition

Linux Device Drivers 2nd Edition (779877), страница 35

Файл №779877 Linux Device Drivers 2nd Edition (Linux Device Drivers 2nd Edition) 35 страницаLinux Device Drivers 2nd Edition (779877) страница 352018-01-10СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 35)

The third argument to the system call is used to indicatewhether the flag is to be set or cleared. We’ll look at the role of the flag laterin this chapter. Note that the flag can also be changed by the fcntl system call,using the F_SETFL command.The last item in the list introduced a new system call, fcntl, which looks like ioctl.In fact, the fcntl call is very similar to ioctl in that it gets a command argument andan extra (optional) argument.

It is kept separate from ioctl mainly for historicalreasons: when Unix developers faced the problem of controlling I/O operations,they decided that files and devices were different. At the time, the only deviceswith ioctl implementations were ttys, which explains why -ENOTTY is the standard reply for an incorrect ioctl command. Things have changed, but fcntl remainsin the name of backward compatibility.Using the ioctl ArgumentAnother point we need to cover before looking at the ioctl code for the sculldriver is how to use the extra argument. If it is an integer, it’s easy: it can be useddirectly.

If it is a pointer, however, some care must be taken.When a pointer is used to refer to user space, we must ensure that the useraddress is valid and that the corresponding page is currently mapped. If kernelcode tries to access an out-of-range address, the processor issues an exception.13422 June 2001 16:36http://openlib.org.uaioctlExceptions in kernel code are turned to oops messages by every Linux kernel upthrough 2.0.x ; version 2.1 and later handle the problem more gracefully. In anycase, it’s the driver’s responsibility to make proper checks on every user-spaceaddress it uses and to return an error if it is invalid.Address verification for kernels 2.2.x and beyond is implemented by the functionaccess_ok, which is declared in <asm/uaccess.h>:int access_ok(int type, const void *addr, unsigned long size);The first argument should be either VERIFY_READ or VERIFY_WRITE, depending on whether the action to be performed is reading the user-space memory areaor writing it.

The addr argument holds a user-space address, and size is a bytecount. If ioctl, for instance, needs to read an integer value from user space, sizeis sizeof(int). If you need to both read and write at the given address, useVERIFY_WRITE, since it is a superset of VERIFY_READ.Unlike most functions, access_ok returns a boolean value: 1 for success (access isOK) and 0 for failure (access is not OK). If it returns false, the driver will usuallyreturn -EFAULT to the caller.There are a couple of interesting things to note about access_ok. First is that itdoes not do the complete job of verifying memory access; it only checks to seethat the memory reference is in a region of memory that the process might reasonably have access to.

In particular, access_ok ensures that the address does notpoint to kernel-space memory. Second, most driver code need not actually callaccess_ok. The memory-access routines described later take care of that for you.We will nonetheless demonstrate its use so that you can see how it is done, andfor backward compatibility reasons that we will get into toward the end of thechapter.The scull source exploits the bitfields in the ioctl number to check the argumentsbefore the switch:int err = 0, tmp;int ret = 0;/** extract the type and number bitfields, and don’t decode* wrong cmds: return ENOTTY (inappropriate ioctl) before access_ok()*/if (_IOC_TYPE(cmd) != SCULL_IOC_MAGIC) return -ENOTTY;if (_IOC_NR(cmd) > SCULL_IOC_MAXNR) return -ENOTTY;/** the direction is a bitmask, and VERIFY_WRITE catches R/W* transfers.

‘Type’ is user oriented, while* access_ok is kernel oriented, so the concept of "read" and* "write" is reversed*/13522 June 2001 16:36http://openlib.org.uaChapter 5: Enhanced Char Driver Operationsif (_IOC_DIR(cmd) & _IOC_READ)err = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd));else if (_IOC_DIR(cmd) & _IOC_WRITE)err = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd));if (err) return -EFAULT;After calling access_ok, the driver can safely perform the actual transfer.

In addition to the copy_fr om_user and copy_to_user functions, the programmer canexploit a set of functions that are optimized for the most-used data sizes (one, two,and four bytes, as well as eight bytes on 64-bit platforms). These functions aredescribed in the following list and are defined in <asm/uaccess.h>.put_user(datum, ptr)_ _put_user(datum, ptr)These macros write the datum to user space; they are relatively fast, andshould be called instead of copy_to_user whenever single values are beingtransferred. Since type checking is not performed on macro expansion, youcan pass any type of pointer to put_user, as long as it is a user-space address.The size of the data transfer depends on the type of the ptr argument and isdetermined at compile time using a special gcc pseudo-function that isn’tworth showing here.

As a result, if ptr is a char pointer, one byte is transferred, and so on for two, four, and possibly eight bytes.put_user checks to ensure that the process is able to write to the given memory address. It returns 0 on success, and -EFAULT on error. _ _put_user performs less checking (it does not call access_ok), but can still fail on somekinds of bad addresses.

Thus, _ _put_user should only be used if the memoryregion has already been verified with access_ok.As a general rule, you’ll call _ _put_user to save a few cycles when you areimplementing a read method, or when you copy several items and thus callaccess_ok just once before the first data transfer.get_user(local, ptr)_ _get_user(local, ptr)These macros are used to retrieve a single datum from user space. Theybehave like put_user and _ _put_user, but transfer data in the opposite direction. The value retrieved is stored in the local variable local; the return valueindicates whether the operation succeeded or not.

Again, _ _get_user shouldonly be used if the address has already been verified with access_ok.If an attempt is made to use one of the listed functions to transfer a value thatdoes not fit one of the specific sizes, the result is usually a strange message fromthe compiler, such as ‘‘conversion to non-scalar type requested.’’ In such cases,copy_to_user or copy_fr om_user must be used.13622 June 2001 16:36http://openlib.org.uaioctlCapabilities and Restricted OperationsAccess to a device is controlled by the permissions on the device file(s), and thedriver is not normally involved in permissions checking.

There are situations, however, where any user is granted read/write permission on the device, but someother operations should be denied. For example, not all users of a tape driveshould be able to set its default block size, and the ability to work with a diskdevice does not mean that the user can reformat the drive.

In cases like these, thedriver must perform additional checks to be sure that the user is capable of performing the requested operation.Unix systems have traditionally restricted privileged operations to the superuseraccount. Privilege is an all-or-nothing thing—the superuser can do absolutely anything, but all other users are highly restricted. The Linux kernel as of version 2.2provides a more flexible system called capabilities. A capability-based systemleaves the all-or-nothing mode behind and breaks down privileged operations intoseparate subgroups. In this way, a particular user (or program) can be empoweredto perform a specific privileged operation without giving away the ability to perform other, unrelated operations.

Capabilities are still little used in user space, butkernel code uses them almost exclusively.The full set of capabilities can be found in <linux/capability.h>. A subsetof those capabilities that might be of interest to device driver writers includes thefollowing:CAP_DAC_OVERRIDEThe ability to override access restrictions on files and directories.CAP_NET_ADMINThe ability to perform network administration tasks, including those whichaffect network interfaces.CAP_SYS_MODULEThe ability to load or remove kernel modules.CAP_SYS_RAWIOThe ability to perform ‘‘raw’’ I/O operations. Examples include accessingdevice ports or communicating directly with USB devices.CAP_SYS_ADMINA catch-all capability that provides access to many system administration operations.CAP_SYS_TTY_CONFIGThe ability to perform tty configuration tasks.Before performing a privileged operation, a device driver should check that thecalling process has the appropriate capability with the capable function (defined in<sys/sched.h>):13722 June 2001 16:36http://openlib.org.uaChapter 5: Enhanced Char Driver Operationsint capable(int capability);In the scull sample driver, any user is allowed to query the quantum and quantumset sizes.

Only privileged users, however, may change those values, since inappropriate values could badly affect system performance. When needed, the scullimplementation of ioctl checks a user’s privilege level as follows:if (! capable (CAP_SYS_ADMIN))return -EPERM;In the absence of a more specific capability for this task, CAP_SYS_ADMIN waschosen for this test.The Implementation of the ioctl CommandsThe scull implementation of ioctl only transfers the configurable parameters of thedevice and turns out to be as easy as the following:switch(cmd) {#ifdef SCULL_DEBUGcase SCULL_IOCHARDRESET:/** reset the counter to 1, to allow unloading in case* of problems. Use 1, not 0, because the invoking* process has the device open.*/while (MOD_IN_USE)MOD_DEC_USE_COUNT;MOD_INC_USE_COUNT;/* don’t break: fall through and reset things */#endif /* SCULL_DEBUG */case SCULL_IOCRESET:scull_quantum = SCULL_QUANTUM;scull_qset = SCULL_QSET;break;case SCULL_IOCSQUANTUM: /* Set: arg points to the value */if (! capable (CAP_SYS_ADMIN))return -EPERM;ret = _ _get_user(scull_quantum, (int *)arg);break;case SCULL_IOCTQUANTUM: /* Tell: arg is the value */if (! capable (CAP_SYS_ADMIN))return -EPERM;scull_quantum = arg;break;13822 June 2001 16:36http://openlib.org.uaioctlcase SCULL_IOCGQUANTUM: /* Get: arg is pointer to result */ret = _ _put_user(scull_quantum, (int *)arg);break;case SCULL_IOCQQUANTUM: /* Query: return it (it’s positive) */return scull_quantum;case SCULL_IOCXQUANTUM: /* eXchange: use arg as pointer */if (! capable (CAP_SYS_ADMIN))return -EPERM;tmp = scull_quantum;ret = _ _get_user(scull_quantum, (int *)arg);if (ret == 0)ret = _ _put_user(tmp, (int *)arg);break;case SCULL_IOCHQUANTUM: /* sHift: like Tell + Query */if (! capable (CAP_SYS_ADMIN))return -EPERM;tmp = scull_quantum;scull_quantum = arg;return tmp;default: /* redundant, as cmd was checked against MAXNR */return -ENOTTY;}return ret;scull also includes six entries that act on scull_qset.

These entries are identicalto the ones for scull_quantum and are not worth showing in print.The six ways to pass and receive arguments look like the following from thecaller’s point of view (i.e., from user space):int quantum;ioctl(fd,SCULL_IOCSQUANTUM, &quantum);ioctl(fd,SCULL_IOCTQUANTUM, quantum);ioctl(fd,SCULL_IOCGQUANTUM, &quantum);quantum = ioctl(fd,SCULL_IOCQQUANTUM);ioctl(fd,SCULL_IOCXQUANTUM, &quantum);quantum = ioctl(fd,SCULL_IOCHQUANTUM, quantum);Of course, a normal driver would not implement such a mix of calling modes inone place.

We have done so here only to demonstrate the different ways in whichthings could be done. Normally, however, data exchanges would be consistentlyperformed, either through pointers (more common) or by value (less common),and mixing of the two techniques would be avoided.13922 June 2001 16:36http://openlib.org.uaChapter 5: Enhanced Char Driver OperationsDevice Control Without ioctlSometimes controlling the device is better accomplished by writing controlsequences to the device itself. This technique is used, for example, in the consoledriver, where so-called escape sequences are used to move the cursor, change thedefault color, or perform other configuration tasks.

Характеристики

Тип файла
PDF-файл
Размер
7,36 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6358
Авторов
на СтудИзбе
311
Средний доход
с одного платного файла
Обучение Подробнее