Thursday, October 30, 2014

Compare I2C and SPI protocols.


  • SPI protocol requires more hardware(I²C needs 2 lines and that’s it, while SPI formally defines at least 4  Signals).
  • SPI procol is faster than I2C, it works in full duplex mode, can transmit upto 10Mbps whereas I2C is limited to 1Mbps in normal mode and 3.4Mbps in fast mode.
  • SPI can have only one master whereas I2C supports more than one masters.
  • In SPI there is no limitation to the number of bits transmitted in one frame(I2c 8bits).
  • SPI is non standard whereas I2C is standard protocol.

Read these two posts for better understanding 

SPI Protocol

SPI(Serial Peripheral Interface) is a single master multiple slave serial transmission protocol that works in full duplex mode.



  • There can be only one master but there can be multiple slaves.
  • MOSI- Master out Slave In
  • MISO- Master In Slave Out
  • SCLK- Clock Signal
  • SS or CS- Slave Select or Chip Selecthe 
  • The data is transmitted using shift register.
  • With the number of clocks equal to the word size(generally 8) the master and slave would have exchanged the value in their shift register.
  • They can now process the data they have received or/and can load new data in the shift register.



Lets Talk Business and Discuss The actual Protocol

  • To start off , the the master configures the clock rate of transmission(frequency should be less than the maximum supportable frequency).
  • The master then sends a chip select signal 0 on the chip select line which it wants to choose.
  • Since the lines are active high so by default they are high(initially).
  • Sometimes a waiting time is involved, so the master must wait for that duration before it starts the clock cycle.
  • During each SPI clock cycle a full transmission happens with this operation-
  1. The master sends one bit on MOSI line and the slave reads on the same line.
  2. The slave sends one bit on the MISO line and the master reads on the same line.
  • We may not need all these transmission for our purpose but as per the protocol this has to happen.

I2C Protocol

I²C (Inter-Integrated Circuitis a multi-master, multi-slavesingle-ended(data flow in only one direction at a time)serial computer bus invented by Philips Semiconductor, known today as NXP Semiconductors, used for attaching low-speed peripherals to computer's motherboards and embedded systems.


The Physical I2C Bus


  • Physically I2C consits of just 2 buses.
  • One bus is SDA for data transfer and the other one is SCL for the clock.
  • All the devices on the I2C bus are connected on these two lines.






  • Both these lines are open drain lines, i.e the chip can drive these lines low but can't drive it high.
  • To make it high we need to connect a pull up register to both the lines connected to 5V supply.
  • We don't need separate pull up register for each device.



Masters and Slaves

  • The devices on I2C bus are either master or slave.
  • Characteristics of a master-

  1. Master is the one who drives the clock.
  2. Master is the one who initiates the transfer.
  3. Though both master and slave send data over the bus bus but the transferred is controlled by master.

I2C Device Addressing

  • I2C device addresses are either 7 bit or 10 bit.
  • Considering 7 bit addressing we can connect upto 128 devices to the I2C bus.


  • While sending we send the address as a 8 bit sequence with 8th bit telling the slave if master is reading(1) or writing(0) from /to the device.


The I2C Protocol

  • SDA is allowed to change only when SCL is low , but it is not followed in 2 cases.
1. Start Sequence

2. Stop Sequence


  • The start and stop sequence is sent by master and it marks the beginning and end of the transfer with the slave device.
  • Steps for writing to the slave-
1. Send a start sequence(all the I2C devices start to listen)
2. Send the I2C address of the slave with the R/W bit low (even address/writing)(all the slaves listen to it and matches it with their own address).
The slave sends the acknowledgement bit in return if the address matches.
3. Send the internal register number you want to write to
4. Send the data byte
5. [Optionally, send any further data bytes]
6. Send the stop sequence.

  • Steps for reading from the slave-
1. Send a start sequence( all the I2C devices on the bus start to listen)
2. Send I2C address of the slave with the R/W bit low (even address/write)(all the slaves listen to it and matches it with their own address).
The slave sends the acknowledgement bit in return if the address matches.
3. Send Internal address of the register to which we need to write.
4. Send a start sequence again (repeated start)
5. Send I2C address of the slave with the R/W bit high (odd address)(slave knows it has to be read from)
6. Read data byte from slave
7. Send the stop sequence.

The peculiar thing in this operation is that even in read operation we do one write operation to know the register from which we need to read from.

Saturday, October 25, 2014

The Virtual Filesystem



Virtual file system (VFS) or Virtual filesystem switch is an abstraction layer on top of a more concrete file system. The purpose of a VFS is to allow for client applications to access different types of concrete file systems in a uniform way.

VFS is a kernel software layer that handles all system calls related to file systems. Its main strength is providing a common interface to several kinds of file systems. It also helps different types of filesystems to interoperate.







Architectural View of VFS







The central idea for VFS operation-

VFS substitutes the generic system call like read and write with the native function for that particular filesystem, eg. NTFS. Each specific filesystem implementation must translate its physical organization into VFS’s common file model.










What are the file systems supported by linux VFS?




–Disk-based filesystems


• Ext2, ext3, ReiserFS


• Sysv, UFS, MINIX, VxFS


• VFAT, NTFS


• ISO9660 CD-ROM, UDF DVD


• HPFS, HFS, AFFS, ADFS,


–Network filesystems


• NFS, Coda, AFS, CIFS, NCP


–Special filesystems


•E.g. /proc




What are the system calls supported by VFS?
• Filesystem

–Mount(), umount(), umount2()

–Sysfs()

–Statfs(), fstatfs(), statfs64(), fstatfs64(), ustat()


•Directories

–Chroot(), pivot_root()

–Chdir(), fchdir(), getcwd()

–Mkdir(), rmdir()

–Getdents(), getdents64(), readdir(), link(), unlink(), rename(), lookup_dcookie()


•Links


–Readlink(), symlink()


•Files

–Chown(), fchown(), lchown(), chown16(), fchown16(), lchown16()

–Chmod(), fchmod(), utime()

–Stat(), fstat(), lstat(), acess(), oldstat(), oldfstat(), oldlstat(), stat64(), lstat64(), fstat64()

–Open(), close(), creat(), umask()

–Dup(), dup2(), fcntl(), fcntl64()

–Select(), poll()

–Truncate(), ftruncate(), truncate64(), ftruncate64()

–Lseek(). _llseek()

–Read(), write(), readv(), writev(), sendfile(), sendfile64(), readahead()


UNIX Filesystems
What is a filesystem?

  • A filesystem means a hierarchical storage of data following a particular structure. 
  • Filesystem contains files, directories and associated control information. 
  • Basic filesystem related operations are 1. creation 2. deletion 3. mounting. 
  • Filesystems are mounted at a specific mount point in a global hierarchy known as namespace. 
  • Mounting at a global namespace allows file systems to appear as entries in a single tree. 


UNIX has provided 4 file system related abstractions

1. Mount points

2. Directory entries

3. Files

4. Inodes


A file is an ordered string of bytes. 
File operations are read, write, create, delete. 

Files are organized in directories.A directory is analogous to a folder and usually contains related files. Directories can also contain other directories, called subdirectories 
A file's metadata is stored in a separate data structure known as inode. 
inode+FS' control information = super block/FS metadata .
VFS is object oriented.
VFS introduces a common file model to represent all supported filesystems.
The objects here refer to structures—not explicit class types, such as those in C++ or Java. 





The four main object types of the VFS are-

  • File object, it is an open file associated with a process.It is really just a block of logically related arbitrary data. 
  • Inode object, it represents metadata about a file.An inode contains essentially information about ownership (user, group), access mode (read, write, execute permissions) and file type. Surprisingly the inodes don't contain the file names as we might think it to contain. 
  • Dentry object ,it is the glue that holds inodes and files together by relating inode numbers to file names. Dentries also play a role in directory caching which, ideally, keeps the most frequently used files on-hand for faster access. File system traversal is another aspect of the dentry as it maintains a relationship between directories and their files. 
  • Superblock object,it is basically the file system metadata and defines the file system type, size, status, and information about other metadata structures (metadata of metadata). The superblock is very critical to the file system and therefore is stored in multiple redundant copies for each file system. The superblock is a very "high level" metadata structure for the file system. For example, if the superblock of a partition, /var, becomes corrupt then the file system in question (/var) cannot be mounted by the operating system. Commonly in this event fsck is run and will automatically select an alternate, backup copy of the superblock and attempt to recover the file system. The backup copies themselves are stored in block groups spread through the file system with the first stored at a 1 block offset from the start of the partition. This is important in the event that a manual recovery is necessary. 

The common file model is specifically geared toward Unix filesystems, all other filesystems must map their own concepts into the common file model

– For example, FAT filesystems do not have inodes

NB:Since VFS treats directory as a normal file that's why there is no separate directory object.






An operations object is contained within each of these primary objects.These objects describe the methods that the kernel invokes against the primary objects:


1.The super_operations object, which contains the methods that the kernel can invoke on a specific filesystem, such as write_inode() and sync_fs()


2. The inode_operations object, which contains the methods that the kernel can invoke on a specific file, such as create() and link()


3. The dentry_operations object, which contains the methods that the kernel can invoke on a specific directory entry, such as d_compare() and d_delete()


4 The file_operations object, which contains the methods that a process can invoke on an open file, such as read() and write()

Each registered filesystem is represented by a file_system_type structure.This object describes the filesystem and its capabilities.
Furthermore, each mount point is represented by the vfsmount structure.This structure contains information about the mount point, such as its location and mount flags.
There are two per-process structures also that describe the filesystem and files associated with a process.They are, respectively, the fs_struct structure and the file structure.


The Superblock Object

  • The superblock object is implemented by each filesystem . 
  • It is used to store information describing the specific filesystem. 
  • The filesystem object corresponding to the superblock is filesystem superblock or filesystem control block. 
  • This object is stored in a special sector of the disk. 
  • For filesystems like sysfs which do not reside on the disk, the superblock is generated on the fly and is stored in memory. 
superblock object is represented by struct super_block and defined in <linux/fs.h>.

The code for creating, managing, and destroying superblock objects lives in fs/super.c.
A superblock object is created and initialized via the alloc_super() function.

When mounted, a filesystem invokes this function, reads its superblock off of the disk, and fills in its superblock object.





The most important item in the superblock object is s_op, which is a pointer to the superblock operations table.The superblock operations table is represented by struct super_operations and is defined in <linux/fs.h>. It looks like this:




struct super_operations {

struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);
void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, int);
void (*drop_inode) (struct inode *);
void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait);
int (*freeze_fs) (struct super_block *);
int (*unfreeze_fs) (struct super_block *);
int (*statfs) (struct dentry *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *);
void (*umount_begin) (struct super_block *);
int (*show_options)(struct seq_file *, struct vfsmount *);
int (*show_stats)(struct seq_file *, struct vfsmount *);
ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
};



Each item in this structure is a pointer to a function that operates on a superblock object.The superblock operations perform low-level operations on the filesystem and its inodes.
When a filesystem needs to perform an operation on its superblock, it follows the pointers from its superblock object to the desired method. For example, if a filesystem wanted to write to its superblock, it would invoke sb->s_op->write_super(sb);
In this call, sb is a pointer to the filesystem’s superblock. Following that pointer into s_op yields the superblock operations table and ultimately the desired write_super() function, which is then invoked. Note how the write_super() call must be passed a superblock, despite the method being associated with one.This is because of the lack of object-oriented support in C. In C++, a call such as the following would suffice: sb.write_super();





Let’s take a look at some of the superblock operations that are specified by

1. struct inode * alloc_inode(struct super_block *sb)
Creates and initializes a new inode object under the given superblock.
2. void destroy_inode(struct inode *inode)
Deallocates the given inode.
3. void dirty_inode(struct inode *inode)
Invoked by the VFS when an inode is dirtied (modified). Journaling filesystems such as ext3 and ext4 use this function to perform journal updates.
4. void write_inode(struct inode *inode, int wait)
Writes the given inode to disk.The wait parameter specifies whether the operation should be synchronous.
5. void drop_inode(struct inode *inode)
Called by the VFS when the last reference to an inode is dropped. Normal Unix filesystems do not define this function, in which case the VFS simply deletes the inode.
6.void delete_inode(struct inode *inode)
Deletes the given inode from the disk.
7. void put_super(struct super_block *sb)
Called by the VFS on unmount to release the given superblock object.The caller must hold the s_lock lock.
8. void write_super(struct super_block *sb)
Updates the on-disk superblock with the specified superblock.The VFS uses this function to synchronize a modified in-memory superblock with the disk.The caller must hold the s_lock lock.
9. int sync_fs(struct super_block *sb, int wait)
Synchronizes filesystem metadata with the on-disk filesystem.The wait parameter specifies whether the operation is synchronous.
10. void write_super_lockfs(struct super_block *sb)
Prevents changes to the filesystem, and then updates the on-disk superblock with the specified superblock. It is currently used by LVM (the LogicalVolume Manager).
11. void unlockfs(struct super_block *sb)
Unlocks the filesystem against changes as done by write_super_lockfs().
12. int statfs(struct super_block *sb, struct statfs *statfs)
Called by the VFS to obtain filesystem statistics.The statistics related to the given filesystem are placed in statfs.
13. int remount_fs(struct super_block *sb, int *flags, char *data)
Called by the VFS when the filesystem is remounted with new mount options.The caller must hold the s_lock lock.
14. void clear_inode(struct inode *inode)
Called by the VFS to release the inode and clear any pages containing related data.
15. void umount_begin(struct super_block *sb)
Called by the VFS to interrupt a mount operation. It is used by network filesystems, such as NFS.

All these functions are invoked by the VFS, in process context.All except
dirty_inode() may all block if needed.


The Inode Object


The inode object represents all the information needed by the kernel to manipulate a file
Filesystems without inodes generally store file-specific information as part of the file; unlike Unix-style filesystems, they do not separate file data from its control information. Some modern filesystems do neither and store file metadata as part of an on-disk database.Whatever the case, the inode object is constructed in memory in whatever manner is applicable to the filesystem.
The inode object is represented by struct inode and is defined in <linux/fs.h>.






An inode represents each file on a filesystem, but the inode object is constructed in memory only as files are accessed.This includes special files, such as device files or pipes.
Consequently, some of the entries in struct inode are related to these special files. For example, the i_pipe entry points to a named pipe data structure, i_bdev points to a block device structure, and i_cdev points to a character device structure.These three pointers are stored in a union because a given inode can represent only one of these (or none of them) at a time.







The Dentry Object


  • VFS employs the concept of a directory entry (dentry).A dentry is a specific component in a path. /, bin, and vi are all dentry objects for the file /bin/vi.The first two are directories and the last is a regular file.
  • Dentry objects are all components in a path, including files. Resolving a path and walking its components is a nontrivial exercise, time-consuming and heavy on string operations, which are expensive to execute and cumbersome to code.The dentry object makes the whole process easier.
  • Dentries might also include mount points. In the path /mnt/cdrom/foo, the components /, mnt, cdrom, and foo are all dentry objects.
  • The VFS constructs dentry objects on the- fly, as needed, when performing directory operations.
  • Dentry objects are represented by struct dentry and defined in <linux/dcache.h>.












Dentry State


  • A valid dentry object can be in one of three states: used, unused, or negative.
  • A used dentry corresponds to a valid inode (d_inode points to an associated inode) and indicates that there are one or more users of the object (d_count is positive).A used dentry is in use by the VFS and points to valid data and, thus, cannot be discarded.
  • An unused dentry corresponds to a valid inode (d_inode points to an inode), but the VFS is not currently using the dentry object (d_count is zero). Because the dentry object still points to a valid object, the dentry is kept around—cached—in case it is needed again.
  • A negative dentry is not associated with a valid inode (d_inode is NULL) because either the inode was deleted or the path name was never correct to begin with.The dentry is kept around, however, so that future lookups are resolved quickly.


The Dentry Cache


The kernel caches dentry objects in the dentry cache or, simply, the dcache.
The dentry cache consists of three parts:

1. Lists of “used” dentries linked off their associated inode via the i_dentry field of
the inode object. Because a given inode can have multiple links, there might be
multiple dentry objects; consequently, a list is used.

2. A doubly linked “least recently used” list of unused and negative dentry objects.The
list is inserted at the head, such that entries toward the head of the list are newer
than entries toward the tail.When the kernel must remove entries to reclaim memory,
the entries are removed from the tail; those are the oldest and presumably have
the least chance of being used in the near future.

3. A hash table and hashing function used to quickly resolve a given path into the
associated dentry object.


The File Object


  • The final primary VFS object that we shall look at is the file object.The file object is used to represent a file opened by a process.
  • When we think of the VFS from the perspective of user-space, the file object is what readily comes to mind. Processes deal directly with files, not superblocks, inodes, or dentries. It is not surprising that the information in the file object is the most familiar (data such as access mode and current offset) or that the file operations are familiar system calls such as read() and write().
  • The file object is the in-memory representation of an open file.
  • The object (but not the physical file) is created in response to the open() system call and destroyed in response to the close() system call. All these file-related calls are actually methods defined in the file operations table.
  • Because multiple processes can open and manipulate a file at the same time, there can be multiple file objects in existence for the same file.
  • The file object merely represents a process’s view of an open file.The object points back to the dentry (which in turn points back to the inode) that actually represents the open file.
  • The inode and dentry objects, of course, are unique.
  • The file object is represented by struct file and is defined in <linux/fs.h>.








High View Diagram of the layers in VFS

V4L2

Video for Linux or V4L is a set of APIs and driver framework for video capture applications and for O/P devices. It supports many USB webcams, TV tuners and other O/P devices.It is integrated into the Linux Kernel code. V4L2 is the second version of V4L.


BASICS


Operations performed on a V4L2 device-


Opening the device

• Changing device properties, selecting a video and audio input, video standard, picture brightness e.t.c
• Negotiating a data format
• Negotiating an input/output method
• The actual input/output loop

• Closing the device


1. Opening and Closing the device



  • V4L2 drivers are implemented as kernel modules.
  • They are loaded automatically when the device is first opened.(can be loaded manually too).
  • The driver plugs into videodev kernel module.
  • This module provides helper function and a common application interface to all the drivers attached.
  • All V4L2 devices registers their device nodes with same major number 81 and different minor numbers.

What if the same driver supports multiple related function?

In this case the driver registers different minor numbers for the different operations.

Imagine a driver supporting video capturing, video overlay, raw VBI capturing, and FM radio

reception. It registers three devices with minor number 0, 64 and 224 (this numbering scheme is inherited from the V4L API). Regardless if /dev/video (81, 0) or /dev/vbi (81, 224) is opened the application can select any one of the video capturing, overlay or VBI capturing functions. Without programming (e. g. reading from the device with dd or cat) /dev/video captures video images, while /dev/vbi captures raw VBI data. /dev/radio (81, 64) is invariable a radio device, unrelated to the video functions. Being unrelated does not imply the devices can be used at the same time, however. The open() function may very well return an EBUSY error code.



Can a V4L2 device be opened more than once?

Yes, this feature can be implemented in the V4L2 driver. But data exchange is not permitted.
When the driver supports stream sharing anyway it must be implemented
transparently. The V4L2 API does not specify how conflicts are solved.


2.Querying Capabilities

All V4L2 drivers must support VIDIOC_QUERYCAP ioctl. Applications should always call this ioctl after opening the device.This ioctl is available to query the functions, capabilities and I/O methods supported by the device.

Other features can be queried by calling the respective ioctl, for example  VIDIOC_ENUMINPUT to learn about the number, types and names of video connectors on the device.


Application Priority


All applications are provided a default medium priority when opened. It is possible that we want to use two different applications with different priorities , for eg. we would want one application to run in low priority in background and one application is foreground(high priority). V4L2 defines the VIDIOC_G_PRIORITY and VIDIOC_S_PRIORITY ioctls to request and query the access priority associate with a file descriptor.After using query capability ioctl the application can use VIDIOC_S_PRIORITY to set a different priority.

3. Video Inputs and Outputs

The VIDIOC_G_INPUT and VIDIOC_G_OUTPUT ioctl return the index of the current video input or output. To select a different input or output applications call the VIDIOC_S_INPUT and VIDIOC_S_OUTPUT ioctl. To learn about the number and attributes of the available inputs and outputs applications can enumerate them with the VIDIOC_ENUMINPUT and VIDIOC_ENUMOUTPUT ioctl, respectively.

4. Audio Inputs and Outputs

Audio and video inputs and outputs are associated. Selecting a video source also selects an audio source.
To learn about the number and attributes of the available inputs and outputs applications can enumerate them with the VIDIOC_ENUMAUDIO and VIDIOC_ENUMAUDOUT ioctl, respectively.The VIDIOC_G_AUDIO and VIDIOC_G_AUDOUT ioctl report the current audio input and output, respectively. Note that, unlike VIDIOC_G_INPUT and VIDIOC_G_OUTPUT these ioctls return a structure as VIDIOC_ENUMAUDIO and VIDIOC_ENUMAUDOUT do, not just an index.
To select an audio input and change its properties applications call the VIDIOC_S_AUDIO ioctl. To select an audio output (which presently has no changeable properties) applications call the VIDIOC_S_AUDOUT ioctl.
Drivers must implement all input ioctls when the device has one or more inputs, all output ioctls when the device has one or more outputs. When the device has any audio inputs or outputs the driver must set the V4L2_CAP_AUDIO flag in the struct v4l2_capability returned by the VIDIOC_QUERYCAP ioctl.

5. Video Standards

Video devices typically support one or more different video standards or variations of standards.Each video input and output may support another set of standards. This set is reported by the std field of struct v4l2_input and struct v4l2_output returned by the VIDIOC_ENUMINPUT and VIDIOC_ENUMOUTPUT ioctl, respectively.
V4L2 defines one bit for each analog video standard currently in use worldwide, and sets aside bits for driver defined standards, e. g. hybrid standards to watch NTSC video tapes on PAL TVs and vice versa.To enumerate and query the attributes of the supported standards applications use the VIDIOC_ENUMSTD ioctl.
To query and select the standard used by the current video input or output applications call the VIDIOC_G_STD and VIDIOC_S_STD ioctl, respectively.The received standard can be sensed with the VIDIOC_QUERYSTD ioctl.

When we deal with USB camera, the notion of video standards make little sense.
Any capture device, output devices accordingly, which is
• incapable of capturing fields or frames at the nominal rate of the video standard, or
• where timestamps refer to the instant the field or frame was received by the driver, not the capture time, or where sequence numbers refer to the frames received by the driver, not the captured frames.
Here the driver shall set the std field of struct v4l2_input and struct v4l2_output to zero, the
VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_QUERYSTD and VIDIOC_ENUMSTD ioctls shall return the EINVAL error code.



6. V4L2 Controls

Devices have different set of controls like brightness, contrast, saturation which is generally presented to the user in form of user interface.As devices vary the controls associated with that device varies too.
All controls are accessed using an ID value. V4L2 defines several IDs for specific purposes. Drivers can also implement their own custom controls using V4L2_CID_PRIVATE_BASE and higher values.The pre-defined control IDs have the prefix V4L2_CID_, and are listed below 







































































Applications can enumerate the available controls with the VIDIOC_QUERYCTRL and
VIDIOC_QUERYMENU ioctls, 
They can get and set a control value with the VIDIOC_G_CTRL and VIDIOC_S_CTRL ioctls. Drivers must implement VIDIOC_QUERYCTRL, VIDIOC_G_CTRL and VIDIOC_S_CTRL when the device has one or more controls, VIDIOC_QUERYMENU when it has one or more menu type controls.


7. Data Formats

The application asks for a particular format and the driver selects and reports the best the hardware can do to satisfy the request. Of course applications can also just query the current selection.
A single mechanism exists to negotiate all data formats using the aggregate struct v4l2_format and the VIDIOC_G_FMT and VIDIOC_S_FMT ioctls. Additionally the VIDIOC_TRY_FMT ioctl can be used to examine what the hardware could do, without actually selecting a new data format.
The first VIDIOC_S_FMT assigns a logical stream (video data, VBI data etc.) exclusively to one file descriptor.
Exclusive means no other application, more precisely no other file descriptor, can grab this stream or change device properties inconsistent with the negotiated parameters. A video standard change for example, when the new standard uses a different number of scan lines, can invalidate the selected image format. Therefore only the file descriptor owning the stream can make invalidating changes.
Apart of the generic format negotiation functions a special ioctl to enumerate all image formats supported by video capture, overlay or output devices is available.
The VIDIOC_ENUM_FMT ioctl must be supported by all drivers exchanging image data with

applications.



Tuesday, October 21, 2014

What is ioremap() ?

ioremap() function is used to map the physical addres of an I/O device to the kernel virtual address.Kernel creates a page table i.e mapping of virtual address to the physical address requested.When we do iounmap() this mapping is destroyed.

void *ioremap(unsigned long phys_addr, unsigned long size);

void iounmap(void * addr);




Explain DMA.

DMA or direct memory access is a feature of cumputerised systems that allows certain Hardware Subsystems to access the system main memory RAM, without much involvement of the CPU.
When CPU is using a normal programmed input/output it becomes fully busy during the entire duration of read or write operation. When using DMA, the CPU just initiates the transfer, resumes the work that it is currently doing and it just inimated by DMA controller when the transfer is done using interrupt.

What is the difference Memory Mapped I/O and I/O mapped I/O?

In memory mapped I/O , the devices share the memory space with our RAM whereas in I/O mapped I/O the devices have separate address space than the memory.So, in I/O mapped I/O we can increase the address capacity of the system.
I/O mapped I/O uses special instructions to access the devices(IN, OUT).Since the external devices are not as fast as the processor so, I/O mapped I/O helps reduce the timing difference between the CPU and memory.The main advantage of memory mapped I/O is that it is easier to program it and it is suported by all the instructions and addressing mode(behave as if it is normal memory access).

Monday, October 20, 2014

mmap() and munmap()


  • In computingmmap(2) is a POSIX-compliant Unix system call that maps files or devices into memory. 
  • It is a method of memory-mapped file I/O.
  •  It naturally implements demand paging, because initially file contents are not entirely read from disk and do not use physical RAM at all.
  •  The actual reads from disk are performed in a "lazy" manner, after a specific location is accessed. After the memory is no longer needed it is important to munmap(2) the pointers to it.
  • memory-mapped file is a segment of virtual memory which has been assigned a direct byte-for-byte correlation with some portion of a file or file-like resource. 
  • This resource is typically a file that is physically present on-disk, but can also be a device, shared memory object, or other resource that the operating system can reference through a file descriptor
  • Once present, this correlation between the file and the memory space permits applications to treat the mapped portion as if it were primary memory.
  • Memory mapping is the only way to transfer data between user and kernel spaces that does not involve explicit copying, and is the fastest way to handle large amounts of data.
  • There is a major difference between the conventional read(2) and write(2) functions and mmap. 
  • While data is transfered with mmap no "control" messages are exchanged. 
  • This means that a user space process can put data into the memory, but that the kernel does not know that new data is available. The same holds for the opposite scenario: The kernel puts its data into the shared memory, but the user space process does not get a notification of this event. 
  • This characteristic implies that memory mapping has to be used with some other communication means that transfers control messages, or that the shared memory needs to be checked in regular intervals for new content. 
  • Similar to the read and write function calls mmap can be used with different file systems and with sockets.
From Linux Man page-


#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);

  • mmap() creates a new mapping in the virtual address space of the
calling process. The starting address for the new mapping is
specified in addr. The length argument specifies the length of the
mapping.
  • If addr is NULL, then the kernel chooses the address at which to
create the mapping; this is the most portable method of creating a
new mapping. If addr is not NULL, then the kernel takes it as a hint
about where to place the mapping; on Linux, the mapping will be
created at a nearby page boundary. The address of the new mapping is
returned as the result of the call.
  • The contents of a file mapping are initialized using length bytes starting
at offset offset in the file (or other object) referred to by the
file descriptor fd. offset must be a multiple of the page size as
returned by sysconf(_SC_PAGE_SIZE).
  • The prot argument describes the desired memory protection of the
mapping (and must not conflict with the open mode of the file). It
is either PROT_NONE or the bitwise OR of one or more of the following
flags:
PROT_EXEC Pages may be executed.
PROT_READ Pages may be read.
PROT_WRITE Pages may be written.
PROT_NONE Pages may not be accessed.
  • The flags argument determines whether updates to the mapping are
visible to other processes mapping the same region, and whether
updates are carried through to the underlying file. This behavior is
determined by including exactly one of the following values in flags:


MAP_SHARED Share this mapping. Updates to the mapping are visible to
other processes that map this file, and are carried
through to the underlying file. The file may not actually
be updated until msync(2) or munmap() is called.


MAP_PRIVATE
Create a private copy-on-write mapping. Updates to the

mapping are not visible to other processes mapping the

same file, and are not carried through to the underlying

file. It is unspecified whether changes made to the file

after the mmap() call are visible in the mapped region.

  • In addition, zero or more of the following values can be ORed in
flags:


MAP_32BIT (since Linux 2.4.20, 2.6)
Put the mapping into the first 2 Gigabytes of the process
address space. This flag is supported only on x86-64, for
64-bit programs.
MAP_ANON



Synonym for MAP_ANONYMOUS. Deprecated.
MAP_ANONYMOUS



The mapping is not backed by any file; its contents are

initialized to zero. The fd and offset arguments are ignored;


MAP_DENYWRITE
This flag is ignored.
MAP_EXECUTABLE
This flag is ignored.


MAP_FILE
Compatibility flag. Ignored.


MAP_FIXED
Because requiring a
fixed address for a mapping is less portable, the use of this

option is discouraged.

MAP_GROWSDOWN
Used for stacks. Indicates to the kernel virtual memory
system that the mapping should extend downward in memory.


MAP_HUGETLB (since Linux 2.6.32)
Allocate the mapping using "huge pages." See the Linux kernel
source file Documentation/vm/hugetlbpage.txt for further
information.


MAP_LOCKED (since Linux 2.5.37)
Lock the pages of the mapped region into memory in the manner
of mlock(2). This flag is ignored in older kernels.


MAP_NONBLOCK (since Linux 2.5.46)
Only meaningful in conjunction with MAP_POPULATE. Don't
perform read-ahead: create page tables entries only for pages

that are already present in RAM.

MAP_NORESERVE
Do not reserve swap space for this mapping. When swap space

is reserved, one has the guarantee that it is possible to

modify the mapping. When swap space is not reserved one might
get SIGSEGV upon a write if no physical memory is available.


MAP_POPULATE (since Linux 2.5.46)
Populate (prefault) page tables for a mapping. For a file
mapping, this causes read-ahead on the file. Later accesses

to the mapping will not be blocked by page faults.

MAP_POPULATE is supported for private mappings only since

Linux 2.6.23.

MAP_STACK (since Linux 2.6.27)
Allocate the mapping at an address suitable for a process or
thread stack. This flag is currently a no-op, but is used in

the glibc threading implementation so that if some

architectures require special treatment for stack allocations,

support can later be transparently implemented for glibc.

MAP_UNINITIALIZED (since Linux 2.6.33)
Don't clear anonymous pages. This flag is intended to improve

performance on embedded devices. This flag is honored only if

CONFIG_MMAP_ALLOW_UNINITIALIZED option. Because of the

the kernel was configured with the


security implications, that option is normally enabled only on

of the contents of user memory).

embedded devices (i.e., devices where one has complete control

Of the above flags, only MAP_FIXED is specified in POSIX.1-2001.
However, most systems also support MAP_ANONYMOUS (or its synonym
MAP_ANON).


Some systems document the additional flags MAP_AUTOGROW,
MAP_AUTORESRV, MAP_COPY, and MAP_LOCAL.
  • A file is mapped in multiples of the page size. For a file that is
    not a multiple of the page size, the remaining memory is zeroed when
    mapped, and writes to that region are not written out to the file.
    on the pages that correspond to added or removed regions of the file
    The effect of changing the size of the underlying file of a mapping
    is unspecified.
munmap()
The munmap() system call deletes the mappings for the specified
address range, and causes further references to addresses within the
range to generate invalid memory references. The region is also
hand, closing the file descriptor does not unmap the region.
automatically unmapped when the process is terminated. On the other
The address addr must be a multiple of the page size. All pages
containing a part of the indicated range are unmapped, and subsequent
references to these pages will generate SIGSEGV. It is not an error
if the indicated range does not contain any mapped pages.