Linux Block device drivers <8>

Source: Internet
Author: User

8th Chapter

+---------------------------------------------------+
| Write a block device driver |
+---------------------------------------------------+
| Zhao Lei |
| Email[email protected]|
+---------------------------------------------------+
| The copyright of the article belongs to the original author. |
| You are free to reprint this article, but the original copyright information must be retained.
| For commercial use, be sure to contact the original author if you have not obtained |
| Copyright disputes arising from the authorization shall be the sole responsibility of the infringer.
+---------------------------------------------------+

The purpose of this chapter is to keep the reader on the rest, so decide to still do something simple

For example: Add module parameters to our driver module so that the size of the block device can be set by parameter when loading the module

It's not difficult to add parameters to our module, which involves 1 macros:
Module_param_named (name, value, type, perm)
Names is the name of the parameter
Value is the variable that the parameter corresponds to in the module
Type is the kind of parameter
Perm is a parameter's permission

For example, to add in a module

int disk_size = 1024;
module_param_named (size, disk_size, int, s_irugo);
You can add a parameter named "Size" to the module, and if the module is loaded using Insmod thismodule size=1, then
The value of Disk_size in the module code is 1.
Conversely, if you do not specify a parameter when loading the module, the value of Disk_size in the module code is still the default of 1024
S_IRUGO specifies that the value of this parameter can be passed by everyone after the module is loaded/sys/module/
[module_name]/parameters/See, but cannot modify

-----------------------Page-----------------------

Well, about module_param_named is introduced here, the details can be Google or look
Linux/include/linux/moduleparam.h

And then we're going to add a parameter to the module to specify the size of the block device at load time.

Parameters of the name have been thought of, called size bar, type, 32-bit unsigned integer maximum can be set to 4G, and our ambition to see

May be a little bigger,

In order for this module to support more than 4G of virtual disks (of course memory is sufficient), we intend to use the 64-bit unsigned integer
This can set the maximum value of 16777216T, should be enough

Then we try to find out the type of the module_param_named parameter that corresponds to unsigned long long to
The result: Google, did not find, see linux/include/linux/moduleparam.h, still did not find
The conclusion is that the current Linux (2.6.28) does not yet support unsigned long long type of module parameter

Update some of the kernel will not have a future thing, as soon as possible to solve the function of this chapter is now facing the problem

Then we started looking for solutions:

1: A patch to the kernel, it looks good, but at least today and so on the completion of our program
And in this way, our program can only run in the future kernel, and lose the compatibility with the old version of Linux
2: Specifies that the set disk size is in units of M. The largest number that can be set is the 4g*1m, which is the 4096T
The idea looks good. And it looks like the machine's memory should not be able to reach this capacity in 1 years.
3: Specify size with string
This can solve all the problems, and we can support 16M, 1G and other settings, so that our program looks more fancy

The disadvantage should be that we need to parse the incoming string in the program itself, fortunately, the actual parsing code is easier than expected

A few

Therefore, in the 3rd scenario, we add a parameter called size, a string of type to the module, and support parsing to
K,m,g,t setting for the unit

1th Step:

Add the following parameter declarations to your program

static char *simp_blkdev_param_size = "16M";
module_param_named (Size, simp_blkdev_param_size, Charp, S_irugo);
Char *simp_blkdev_param_size is used to store the set disk size, we specify the disk size default value of 16M

Currently we do not allow users to change the size of the disk after the module load, in the future, it is possible to increase this function, looks very dazzling

2nd Step:

The original program uses

#define Simp_blkdev_bytes (16*1024*1024)

Define the disk size, and now we don't need this line.

At the same time, we need a unsigned long long variable to store the user-defined disk size, so we add this variable:

Static unsigned long long simp_blkdev_bytes;
Then change all the places in the program using Simp_blkdev_bytes to use the simp_blkdev_bytes variable
3rd Step:

-----------------------Page-----------------------

Parse the module parameters at module load, set the value of the simp_blkdev_bytes variable

We add a function to parse the work:

int GetParam (void)
{
char unit;
Char TAILC;

if (sscanf (simp_blkdev_param_size, "%llu%c%c", &simp_blkdev_bytes,
&unit, &TAILC)! = 2) {
Return-einval;
}

if (!simp_blkdev_bytes)
Return-einval;

Switch (unit) {
Case ' G ':
Case ' G ':
Simp_blkdev_bytes <<= 30;
Break
Case ' m ':
Case ' M ':
Simp_blkdev_bytes <<= 20;
Break
Case ' K ':
Case ' K ':
Simp_blkdev_bytes <<= 10;
Break
Case ' B ':
Case ' B ':
Break
Default
Return-einval;
}

/* Make simp_blkdev_bytes fits sector ' s size */
Simp_blkdev_bytes = (simp_blkdev_bytes + (1<<9)-1) & ~ ((1ull<<9)-1);

return 0;
}
This function is then called in Simp_blkdev_init ():
ret = GetParam ();

-----------------------Page-----------------------

if (Is_err_value (ret))
Goto Err_getparam;
Of course, Err_getparam's location, the reader should be able to guess.

As a result, the work is probably done, so let's look at the results:

Use default values:

# Insmod Simp_blkdev.ko
# Fdisk/dev/simp_blkdev
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF
Disklabel
Building a new DOS disklabel. Changes'll remain in memory only,
Until decide to write them. After that, of course, the previous
Content won ' t be recoverable.

Warning:invalid flag 0x of partition Table 4 'll be corrected by W (rite)

Command (M for help): P

Disk/dev/simp_blkdev:16 MB, 16777216 bytes
1 heads, Sectors/track, 1024x768 cylinders
Units = Cylinders of * 16384 bytes

Device Boot Start End Blocks Id System

Command (M for help): Q

#
Set to 20M:
# Rmmod Simp_blkdev
# Insmod Simp_blkdev.ko size=20m
# Fdisk/dev/simp_blkdev
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF
Disklabel
Building a new DOS disklabel. Changes'll remain in memory only,
Until decide to write them. After that, of course, the previous
Content won ' t be recoverable.

The number of cylinders for this disk was set to 1280.
There is nothing wrong with the, but this is larger than 1024,
And could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from the other OSs
(e.g., DOS fdisk, OS/2 fdisk)

-----------------------Page-----------------------

Warning:invalid flag 0x of partition Table 4 'll be corrected by W (rite)

Command (M for help): P

disk/dev/simp_blkdev:20 MB, 20971520 bytes
1 heads, Sectors/track, cylinders
Units = Cylinders of * 16384 bytes

Device Boot Start End Blocks Id System

Command (M for help): Q

#
Metamorphosis, or set to 20M, but with K units:
# Rmmod Simp_blkdev
# Insmod Simp_blkdev.ko size=20480k
# Fdisk/dev/simp_blkdev
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF
Disklabel
Building a new DOS disklabel. Changes'll remain in memory only,
Until decide to write them. After that, of course, the previous
Content won ' t be recoverable.

The number of cylinders for this disk was set to 1280.
There is nothing wrong with the, but this is larger than 1024,
And could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from the other OSs
(e.g., DOS fdisk, OS/2 fdisk)
Warning:invalid flag 0x of partition Table 4 'll be corrected by W (rite)

Command (M for help): P

disk/dev/simp_blkdev:20 MB, 20971520 bytes
1 heads, Sectors/track, cylinders
Units = Cylinders of * 16384 bytes

Device Boot Start End Blocks Id System

Command (M for help): Q

#

-----------------------Page-----------------------

Looks like a good result.

This chapter basically does not mention what is more obscure knowledge, and it seems that through this chapter of learning, we should also rest good

If the reader is now feeling a hundredfold, the purpose of this chapter should be to achieve

< not finished, to be continued >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

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.