I'm currently learning kernel driver programmation using Linux Device Drivers - 3rd.
To define a block device, I have to declare a gendisk
structure and to initialize it with relevant informations.
In chapter 16 its written:
sector_t capacity;
The capacity of this drive, in 512-byte sectors. The sector_t type can be 64 bits wide. Drivers should not set this field directly; instead, pass the number of sectors to set_capacity.
Usualy I set the capacity using a call like:
set_capacity(gendisk, sector_number*(hard_sector_size/KERNEL_SECTOR_SIZE));
Imagine that I have a device with a memory zone that is not a multiple of 512 bytes.
Let's take 2000 bytes so there is three 512 bytes zones plus a 464 bytes zone
[-512b-] [-512b-] [-512b-] [-464b-]
0 511 512 1023 1024 1535 1536 1999
- What should I pass to
set_capacity
?
Furthermore on some devices, memory is splitted into several areas. Imagine that I have a device containing multiple memory areas, each with different size and that I want to abstract this splitted memory into a single memory zone.
area1 => 32000 bytes
area2 => 512 bytes
area3 => 50 bytes
area4 => 45 bytes
area5 => 1024 bytes
In this case the hard sector size is not a constant within the device.
- How should I fill the
gendisk
structure ?
UPDATE after @KamilCuk answer:
To continue with this example let's take the full device memory (33631 bytes) which is 65 sectors of 512 bytes + 1 sector of 351 bytes.
So the solutions are to present it either as:
- 33270 bytes memory zone ==> 65 sectors
or
- 33631 bytes memory zone ==> 66 sectors with 161 bytes discarded at the end of last sector
Are those the best solutions or there is another way to handle this specific case ?
- Basically the question could be resumed to how to initialize a block device when it's not a multiple of KERNEL_SECTOR_SIZE?