Major and Minor Numbers 及 註冊和撤銷

來源:互聯網
上載者:User

Char
devices are accessed

through





names in the filesystem. Those names are
called special files or device files or simply nodes of the
filesystem tree; they are conventionally located in the
/dev


directory. Special files
for char drivers are identified by a
"c" in the first column of the
output of ls -l
. Block devices appear in
/dev
as well, but they are identified by a
"b." The focus of this chapter is
on char devices, but much of the following information applies to
block devices as well.

 


If you
issue the ls -l
command, you'll
see two numbers

(separated by a comma) in the device file entries
before the date of the last modification, where the file length
normally appears. These numbers are the major and minor device number
for the particular device. The following listing shows a few devices
as they appear on a typical system. Their major numbers are 1, 4, 7,
and 10, while the minors are 1, 3, 5, 64, 65, and 129.

 crw-rw-rw-    1 root     root       1,   3 Apr 11  2002 null

crw------- 1 root root 10, 1 Apr 11 2002 psaux

crw------- 1 root root 4, 1 Oct 28 03:04 tty1

crw-rw-rw- 1 root tty 4, 64 Apr 11 2002 ttys0

crw-rw---- 1 root uucp 4, 65 Apr 11 2002 ttyS1

crw--w---- 1 vcsa tty 7, 1 Apr 11 2002 vcs1

crw--w---- 1 vcsa tty 7, 129 Apr 11 2002 vcsa1

crw-rw-rw- 1 root root 1, 5 Apr 11 2002 zero

 

Traditionally, the major number identifies the driver associated with
the device.

For example, /dev/null
and
/dev/zero
are both managed by driver 1, whereas
virtual consoles and serial terminals are managed by driver 4;
similarly, both vcs1
and
vcsa1
devices are managed by driver 7. Modern
Linux kernels allow multiple drivers to share major numbers, but most
devices that you will see are still organized on the
one-major-one-driver principle
.



The minor number is used by the
kernel to determine exactly which device is being referred to


.
Depending on how your driver is written (as we will see below), you
can either get a direct pointer to your device from the kernel, or
you can use the minor number yourself as an index into a local array
of devices. Either way, the kernel itself knows almost nothing about
minor numbers beyond the fact that they refer to devices implemented
by your driver.

3.2.1. The Internal Representation of Device Numbers

Within the kernel, the dev_t
type (defined in
<linux/types.h>
)
is
used to hold device numbers—both
the major and

minor parts. As of
Version 2.6.0 of the kernel, dev_t
is a 32-bit
quantity with 12 bits set aside for the

major number and 20 for the
minor number. Your code should, of course, never make any assumptions
about the internal organization of device numbers; it should,
instead, make use of a set of

macros found
in <linux/kdev_t.h>
. To obtain the major
or minor parts of a dev_t
, use:

MAJOR



(dev_t dev);




MINOR



(dev_t dev);

 

If, instead, you have the major and minor numbers and need to turn
them into a dev_t
, use:

MKDEV



(int major, int minor);

 

Note that the 2.6 kernel can accommodate a vast number of devices,
while previous kernel versions were limited to 255 major and 255
minor numbers. One assumes that the wider range will be sufficient
for quite some time, but the computing field is littered with
erroneous assumptions of that nature. So you should expect that the
format of dev_t
could change again in the future;
if you write your drivers carefully, however, these changes will not
be a problem.

3.2.2. Allocating and Freeing Device Numbers

One of the first things your
driver



will need to do

when setting up a char
device is to obtain one or more device numbers to work with. The
necessary function for this task is
register_chrdev_region
, which is declared in
<linux/fs.h>
:

int register_chrdev_region



(dev_t first, unsigned int count,




char *name);

 

Here, first
is the beginning

device number of the range you would
like to allocate. The minor number portion of
first
is often 0
, but there is
no requirement to that effect. count
is the total
number of contiguous device numbers you are requesting. Note that, if
count
is large, the range you request could spill
over to the next major number; but everything will still work
properly as long as the number range you request is available.
Finally, name
is the name of the device that
should be associated with this number range; it will appear in
/proc/devices
and sysfs.

As with most kernel functions, the return value from
register_chrdev_region
will be
0
if the allocation was successfully performed. In
case of error, a negative error code will be returned, and you will
not have access to the requested region.

register_chrdev_region
works well if you know
ahead of time exactly which device numbers you want. Often, however,
you will not know which major numbers your device will use; there is
a constant effort within the Linux kernel development community to
move over to the use of dynamicly-allocated
device numbers. The
kernel will happily allocate a major number for you on the fly, but
you must request this allocation by using a different function:

int alloc_chrdev_region

(dev_t *dev, unsigned int firstminor,

unsigned int count, char *name);

成功了後,就會在/proc/device檔案中有該裝置的裝置號了



 

With this function, dev
is an output-only
parameter that will, on successful completion, hold the first number
in your allocated range. firstminor
should be the
requested first minor number to use; it is usually
0
. The count
and
name
parameters work like those given to
request_chrdev_region
.

Regardless of how you allocate your device numbers, you should free
them when they are no longer in use. Device numbers are freed with:

void unregister_chrdev_region

(dev_t first, unsigned int count);

 

The usual place to call unregister_chrdev_region
would be in your module's cleanup function
.

 

The above functions allocate device numbers for your
driver's use, but they do not tell the kernel
anything about what you will actually do with those numbers. Before a
user-space program can access one of those device numbers, your
driver needs to connect them to its internal functions that implement
the device's operations. We will describe how this
connection is accomplished shortly, but there are a couple of
necessary digressions to take care of first.

 

When a device file is accessed, the kernel uses the major number of the file to determine
which driver should be used to handle the access. This means that the kernel doesn't really need to use or even know
about the minor number. The driver itself is the only thing that cares about the minor number. It uses the minor
number to distinguish between different pieces of hardware.

Kernel就知道major裝置號,通過這個major裝置號來找到driver。由driver本身來根據minor裝置號區分具體的硬體。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.