In Linux, what kinds of files are memory mapped? - linux

What are the different types of Linux files that can be created entirely in memory?
For example, a pipe file may be created, but does the location of where a file is created (or the filesystem type of the file's path) make a difference to whether a disk access is involved? If I create a pipe file in an ext3 file system, could a physical disk access result?

Off the top of my head, and without looking at any books :D, I think it breaks down like this:
mmap-able:
files (of course)
soft-links (final target if it's a file, block device or kernel device)
hard-links (final target if it's a file, block device or kernel device)
block devices (/dev/ram1, /dev/sda1, etc..)
character devices (You can mmap character devices, but in some cases it won't make sense (or work right). For instance an easy way to develop a driver in userland is to have a kernel module handle a basic mmap to your hardware and then expose the hardware via a mmapable character device so that a non-privileged user can access it. (USB, audio, flash cards) use this. A lot of embedded stuff does too.
unix domain sockets? Does zerocopy/sendfile count?
mmap-able but not a file?
shared memory
un-memmappable?
directories
fifos (one reader, one writer) ?

Related

Does a file system include executing code or just data structures

Let's take an SD card for example. I wish to partition this card into different partitions with different file systems on each partition, for example FAT, EXT3, HFS etc.
I understand the SD card will have a memory controller. In order for these file systems to work for each partition, will extra code be added to the card, or is it just data structures which get updated?
If we mount this card onto a Linux system for example, is it Linux which has the special code to deal with each file system, or is this embedded into the card, or is there even any extra code involved here for a file system? This concept I haven't fully grasped yet.

API to read the device tree from userspace

Is there an API to read the Open-Firmware device tree from userspace?
For example, reading /sys/firmware/fdt (flattened device tree)?
If not, is the file format published so a userspace application can read entries from the fdt?
This is easier than I first thought. On devices that support Open-Firmware, the linux kernel mounts it as a virtual filesystem at /proc/device-tree/.
In my case, on the systems I happened to be checking, this was a symbolic link to /sys/firmware/devicetree/base. But either way, walking through the files and directories in /proc/device-tree/ is relatively easy to do, regardless of the language.

How to use linux device model and /sys filesystem?

I'm new in developing Linux driver.
Traditionally, If i want to create char device, I just need to implement read write and ioctl functions, and register it by register_chrdev_region with corresponding Major device ID. And then use mknod to create a device file of that Major device ID. Then call read write open in user space will then call the corresponding functions by kernel.
But now i'm studying Linux device model and sys filesystem, which is added in kernel 2.6. I'm told if possible, Don't use /dev filesystem, as linux now has a good device model to handle device and driver.This confused me, so I'll summarize my confusion into some questions:
How do I create a char device in /sys? To be more specific, how do I create a null device just like /dev/null?
How do I call my char device driver function from userspace?
I heard that udev is based on sys filesystem to create device file in /dev. Why? Since I'm told "If possible, Don't use /dev filesystem", why does udev use /sys to create file in /dev?
Does a file in sys have any conceptions like char device file or block device?
In /dev, open write from user space will finally map to functions in file operation structure defined by me, then what functions will be called when I open or write to files in /ssy?
Without context your statement about /dev is not clear. Anyway:
You cannot create char devices on sysfs. The main purpose of sysfs is to export information and allow the user to adjust single values (just navigate under /sys/ for some examples). Char devices usually does much complicated things.
If you mean how you call your driver's open,read,write,ioctl, ... well, by doing open(2), read(2), write(2), ioctl(2) (look at man pages of these commands)
when a device appear, the kernel create a directory under /sys. For example take a look at ls /sys/bus/usb/devices/. All that directories are created when an USB device appear. You can try by plug/unplug USB devices. udev put an eye on sysfs to detect new devices and according to the information from sysfs it create the device under /dev. This happens when the driver, somehow, calls device_add(). Often this functions is invoked by other register functions like: device_create, device_register, or other from other sub-systems.
the idea of sysfs is to provide information about the devices and drivers loaded. So you can change device, bus and driver options. Or manually attach a device to a module
Actually, behind the sysfs attributes there is a set of file_operation, where open, read and write are managed by the kernel and not by your driver. In order to create a sysfs attribute you have to provide the pair of function show and store to read/write something from/to the driver. Then the kernel will route the requests to your correct attribute

Linux: mmap() for non-regular files

I understand that mmap() allows an application to map a file into memory, so that there's a one-on-one correspondence between a memory address and a word in the file.
But my question is what if the file is a non-regular file created by a device driver? As I know, some non-regular files are mmap-able, some are not. What does that mean from programming's perspective? What should I do if I want my non-regular file to be mmap-able?
I have worked on a Linux-kernel-module in which I implemented mmap function pointer(struct file_operations). This module would create a device entry in /dev/ directory. Now my user-space application would open this entry using "open" and would make a mmap system call. Eventually inside the Linux-Kernel-module I insmoded the mmap function will be called and will do the implemented processing and will return back to the user-space.
This was just an example to represent the service requested by the user-space to the OS(Kernel).
When ever user wants to access hardware or wants to request service from the kernel(like mapping physical memory to user-virtual-address-space), it can do it using the entry created by the driver in the /dev/ or /sys/ or /proc/ etc. These files can be termed as "virtual interface" to the kernel.

Port Window Api---GetVolumeInformation to Linux

win Api
WINAPI GetVolumeInformation(
_In_opt_ LPCTSTR lpRootPathName,
_Out_opt_ LPTSTR lpVolumeNameBuffer,
_In_ DWORD nVolumeNameSize,
_Out_opt_ LPDWORD lpVolumeSerialNumber,
_Out_opt_ LPDWORD lpMaximumComponentLength,
_Out_opt_ LPDWORD lpFileSystemFlags,
_Out_opt_ LPTSTR lpFileSystemNameBuffer,
_In_ DWORD nFileSystemNameSize
);
Hello: I want to port windows api GetVolumeInformation to Linux.
Q1:Does Linux have the same function.
Q2:if not.
Q2.1 what is lpVolumeNameBuffer in linux(is /dev/sda1)? how can i get it in linux?
Q2.2 what is lpVolumeSerialNumber in linux(is )? i use ioctl get it.
struct hd_driveid id;ioctl(fd, HDIO_GET_IDENTITY, &id);
Q2.3 what is lpMaximumComponentLength in linux? how can i get it in linux?
Q2.4 what is lpFileSystemFlags in linux? how can i get it in linux?
Q2.5 what is lpFileSystemNameBuffer? how can i get it in linux?
If you have any good ideas I would really appreciate it.
Thanks!
Conceptually, linux doesn't have volumes in the same way that Windows does - linux has mount points, Windows has 'drive letters', for lack of a better term.
lpVolumeName is the friendly name of a mounted volume - for instance, my C: drive is labeled 'main_disk'. The point of this label is only to give a friendly name to the drive, and the label can change whenever the user decides to change it, and it does not affect the structure of the ultimate file system layout.
In linux, volumes are mounted as mount points, eg, the device referred to as /dev/sda2 might be mounted at the /var mount point. Here, /var is part of the file system, and thus, mount points determine the structure of the ultimate file system layout. This is not simply a friendly name for the user to give to their disk so that they can know what it is.
Linux and others do support something called disk labeling, but that's used to be able to refer to the disk using a stable name, instead of its device name, which could change if the hard drives are moved around in the computer. For instance, in FreeBSD, I could label my main hard drive root; when that hard drive is detected during boot up, i can instead refer to it as /dev/label/root and specify the mount point for it using that name. However, this is still being used to determine the ultimate structure of the file system - it's a functional dependency - and so the user can't change it willy-nilly without breaking something or having to change the fstab file that describes device-to-mount-point mappings.
lpVolumeSerialNumber has to do with the filesystem on the volume; that is, this field is specific to what filesystem is being used on the volume, and isn't something that all volumes will have.
In Windows, typically two filesystems are supported - Fat32 and NTFS - both of which can give a serial number to a file system. In Linux, FreeBSD, etc, there are many, many file systems - UFS/UFS2, EXT/EXT2/EXT3/EXT4, ReiserFS/Reiser4, BTRFS, ZFS, FFS, etc. Whether or not a volume has a serial number depends on what file system the volume is using, and not all filesystems support serial numbers. Each filesystem will have its own utility commands to query this sort of data - for instance, dumpfs on FreeBSD for UFS2 file systems.
The list goes on. Unfortunately, there are no direct analogs between Windows and Linux for the parts you're asking about, but as I've shown, sometimes it doesn't matter and when it does, you can usually find something to replace it with.
POSIX systems have statvfs()/fstatvfs() subroutines (which might be a library function or system call, depending on the OS). Perhaps they are what most closely resemble what the Windows' function you named does, but they have a very different interface.
I don't know if it matters to you, but a related problem is to enumerate mounted filesystems. To enumerate currently mounted filesystems on Linux, you can read the contents of /proc/mounts. Some other UNIX flavors (namely BSD-derived systems) have getvfsstat()/getfsstat() calls for the same purpose. Solaris has (or used to have) neither, and you best choice was to read /etc/mnttab. AIX has none of these, and your (only?) reliable (?) option to enumerate current mounts is to parse the output of the mount command, run without any argument.

Resources