Confusion over ioctl() and kernel headers - c

As far as I know, ioctl() is used to expose an "extended" system call interface to userspace applications. Rather than adding thousands of system calls that are unique to specific drivers, ioctl() is used to provide extensible driver-specific functions through a single system call.
This seems clear enough. However, I'm trying to compile my first application that uses an ioctl() call, and I'm starting to doubt my understanding.
Specifically, I want to make an ioctl() call to "sanitize" an eMMC device. Taking a look at /usr/include/linux/mmc/ioctl.h (or in kernel source at include/uapi/linux/mmc/ioctl.h), I can see this structure:
struct mmc_ioc_cmd {
// Most fields omitted
int write_flag;
__u32 opcode;
__u32 arg;
};
From userspace, I don't have any issues including this header and passing this structure into my ioctl() calls.
So this is what my final sanitize snippet looks like:
int sanitize(int fd)
{
struct mmc_ioc_cmd command;
memset(&command, 0, sizeof(command));
command.write_flag = 1;
command.opcode = MMC_SWITCH;
command.arg = EXT_CSD_SANITIZE_START << 16;
return ioctl(fd, MMC_IOC_CMD, &command);
}
My problem is that MMC_SWITCH and EXT_CSD_SANITIZE_START are both defined in kernel headers. Specifically, in my kernel source, they're both found at include/linux/mmc/mmc.h.
Everything I've seen on the internet says to not include headers from the kernel source when building userspace projects. If that's the case, how can you reasonably use the MMC ioctl()? The kernel exposes the structure to pass into ioctl(), but it seems like you can only use the structure by filling it in with "hidden" constants hidden in the kernel source.
My current solution is to copy the necessary constants from the kernel headers to my own project, but this feels dirty to me.
Am I misunderstanding the use-case for ioctl()? Is this a design oversight?

The MMC_IOC_CMD ioctl, and the corresponding mmc_ioc_cmd structure, are part of the Linux userspace API, and therefore are defined in the uapi headers that are installed into /usr/include.
The value that you put into the opcode field gets sent directly to the device. The kernel does not really care what it is, and cannot guarantee what opcodes the device supports, or how it behaves for any specific opcode. Therefore, opcodes like MMC_SWITCH are not part of the API.
As far as I can see, you are supposed to get the opcodes from the relevant MMC standards.
(This is not really a good reason to keep these symbols out of the user-space API; copying the kernel header is much easier than manually transcribing the values from the standard. And the kernel actually has a special case for handling EXT_CSD_SANITIZE_START through this ioctl.)

If you can #include it without adding any additional -I include paths on your GCC command line, then you're fine.
Everything I've seen on the internet says to not include headers from the kernel source when building userspace projects.
That advice means don't include headers directly from the kernel source tree. The uapi headers are intended to be consumed from userspace, and are installed into /usr/include.

Related

What does __section( ) mean in linux kernel source

I see the following code in some OS kernel. But I don't understand the way __section is used, and don't know what does this code mean.
#define KEEP_PAGER(sym) \
extern const unsigned long ____keep_pager_##sym; \
const unsigned long ____keep_pager_##sym \
__section("__keep_meta_vars_pager") = (unsigned long)&sym
It's specific linux kernel C macro definition wrapped around a GCC extension, specifying an atttribute to use for an object. It's a shorter way of writing the section attribute definition
Historically the linux kernel has been written specifically for building with the GCC compiler, and makes extensive use of low level extensions to do specific hardware operations and optimisations.
The section attribute specifically is used to determine the storage location of the object tagged with it. ELF binary format arranges the object file into named sections, and using the attribute like this allows the programmer to more precisely specify where the information for the tagged object will be placed in the target object
Over the years, there's been work put in to increasing the compatibility of these compiler extensions between different compilers, as well as making linux compilable with alternative compilers (if you look at the linux header file where the macro is defined you'll see that it is full of conditional directives for various compiler features). Macros like this can be a useful way to have a portable internal API for low level features across different compiler implementations.
Kernel and kernel driver C code is atypically concerned with direct specifics of physical hardware implementation, and needs to be explicit about the compiler binary output in a way that application level C code rarely will.
One example of why the linux kernel uses named sections is in the init handling - functions and data that are only used during bootup are grouped into one section of memory that can be easily released once startup is complete - you may be familiar with the boot message along the lines of 'freeing unused kernel memory:...' towards the end of the linux boot sequence
It is hard to tell what that __section is exactly without its definition, but it might be a variable "section" attribute. It is used to make compiler place variable into a section different from "bss" or "data". See GCC documentation for details.

alsa-lib - Can't locate structure definition. A low level design pattern?

On line 63 of this example header file there is a typedef:
typedef struct _snd_ctl_elem_info snd_ctl_elem_info_t;
There are multiple examples of typedefs like that through the code.
My goal is to get to the actual definition of the structure _snd_ctl_elem_info but I have grepped the source and googled but found no traces of the actual definition. Because of this search failure, I've started to think I might be missing some concepts and it might be something to do with kernel and backwards compatibility?
My motivation for this is to be able to gdb step through alsa and have an overview of the structures.
Is this some form of a low level structure definition pattern?
This structure is also used by alsa-lib to communicate with the kernel, so it just reuses the kernel's definition.
The kernel header would be installed as /usr/include/sound/asound.h, but to avoid a dependence on the kernel headers being installed correctly, alsa-lib has its own copy of this file in alsa-lib/include/sound/asound.h.
Applications are not supposed to access the members of this structure directly, so alsa-lib does not include asound.h from its official headers (and does not even install it; it's used only when compiling alsa-lib).
To get the actual definition, you would need #include <sound/asound.h>.
It sounds like it gets renamed from a typedef:
#define _snd_ctl_elem_info sndrv_ctl_elem_info
So you're looking for sndrv_ctl_elem_info, which is way easier to find.
It is defined in asound.h at line 809.
It's pretty massive so I won't paste it here.
It is defined in API header snd/asound.h. This is what client code is supposed to #include.

What Is Needed To Use fopen() On An Embedded System?

I am quite new to the FILE family of functions that the standard C library provides.
I recently stumbled across fopen() and the similar functions after researching how stdout, stdin and stderr work alongside functions like printf().
I was wondering, what is needed to use fopen() on an embedded system (which doesn't necessarily have operating system support). After reading more about it, is seems like a cool thing to do on more powerful embedded systems to hook into say, a UART/SPI interface, so that calling printf() would print data out of the UART. Simarly, you could read data from a UART buffer by calling scanf().
This would also increase portability! (code written for say, Linux, would be easier to port if printf() was supported). You could also print debug data to a file if it was running in a production environment, and read from it later.
Can you just use fopen() on a bare-bones embedded system? If so who/where/when is the "FILE" then created (as far as I now, fopen() does not malloc() space for the file, nor do you specify how much)? Or do you need a operating system with FAT file support. If so, would something like http://ultra-embedded.com/?fat_filelib work? Would using FreeRTOS help at all?
Check the documentation for your toolchain's C library - it should have something to say about re-targeting the library.
For example if you are using Newlib you must re-implement some or all of the [syscalls stubs][3] to suit your target. The low level open() syscall in this case will allow fopen() to work as necessary. At its simplest, you might implement open() to support higher-level stdio access to serial ports, but if you are expecting standard file-system access, then you will still need an underlying file-system to map it too.
Another example of re-targeting the Keil/ARM standard library can be found here.
Yes, it's often possible to use fopen() and similar routines in code for embedded systems. The way it often works is that the vendor supplies a C compiler and associated libraries
targeted for their system, which implement some supported subset of the language in a way that's appropriate for that system (e.g. an implementation of printf() that outputs via a UART, or fopen() that uses RAM to simulate some sort of filesystem).
On the Keil compiler, the stdio library is designed to allow the user to define the __FILE structure in any desired fashion. A function like fprintf will perform a sequence of calls to fputc, which will receive a copy of the pointer passed to fprintf. One may define something like fopen to "create" a __FILE and populate its members via any desired means (if there will never be more than one file open at a time, one could simply fill in the fields of a static instance and return that). Variables __stdin, __stdout, and __stderror may likewise be defined as desired (stdin is defined to point to __stdin, and likewise with stdout and stderror).
"Can you just use fopen() on a bare-bones embedded system?"
It depends. Depends on the configuration of your embedded system, the types of memories interfaced, on what memory do you want to implement the file system, the file system library code size (ROM & RAM requirements).
FILE manipulation functions can be used independent of any OS. But a proper file system must be used and FAT is not the only file system (JFFS2, YAFS,...some other proprietary file system)
The file system is generally (but not always) implemented on Flash memories (Nand Flash, Nor Flash). USB device is also a flash (Nand flash). The Nand Flash & Nor Flash may have Parallel interface, I2C interface or SPI interface.

Which headers and functions can I use in loadable kernel modules (except external libraries)?

Section 2 of the Linux man pages contains system calls.
http://linux.die.net/man/2/
After finding this link, I say "OK! I use this reference for developing every modules, It is complete".
But it seems I can not use some functions of this section (like bind(2)). After including required headers (like <sys/socket.h>) the module compilation failed.
Some functions/macros like printk does not listed in the section 2. Many people used Linux Apis that I could not find any official reference for it (just like printk). I don't know how they found these functions? (May be by reading whole source code of kernel instead of reading any reference)
Some functions like memset describes in section 3 (user space libraries) but kernel module developer can use it without any error!
Where I can found a COMPLETE reference of available headers and functions when developing a loadable kernel modules? (Something like MSDN and WINDDK references)
#include <linux/init.h>
#include <linux/module.h>
/* A complete list of availabe headers and functions is missing! */
static int my_init(void)
{
return 0;
}
static void my_exit(void)
{
return;
}
module_init(my_init);
module_exit(my_exit);
As you know, the Kernel is quite a big, big and independent beast. This means that you cannot include anything which is not found under your kernel source tree.
When you're implementing your module, that means the only things you can link to is what you got in :
The kernel source tree itself
Another module you've made (I would recommend to avoid this scenario though whenever possible ... )
Note that you will be able to use the functions only if they are exported. You can check this using the nm utility on the compiled .ko file of a module. If you want to export some symbols of your module, you have to use the macro EXPORT_SYMBOL.
Be careful not to confuse user-space includes, usually found under /usr/include with the kernel module headers (which you are likely wanting to link against).
In the example you gave, the sys/socket.h is the location of the header after a make headers_install. At this location, it is meant to be used by userspace applications. This is NOT what you want when you are programming a module.
I think you have to look deeper in the use of sockets in the kernel. By googling up a little, I found -> this <- on LWN and checked the include/linux/net.h header of my 3.8 kernel source tree. The patch described in the link is integrated in the kernel and is likely to be what you are looking for.
The memset example is also an illustration of what I explained this far : if you want to use it in a common application, you'll have to include the string.h header, which is simply located at /usr/include/string.h. Its kernel equivalent is found under ...
/your-kernel-source-tree-dir/include/linux/string.h
Et voila ! You can use memset and friends inside any piece of kernel code, as long as you include the right header !
Thus, when you feel some frustration, thinking Man, I was able to use this by simply including this header in my apps ... Take a deep look at the kernel source tree (or have grep do it for you ;) ). You are very likely to find what you are looking for !
As per my knowledge there is no such complete reference for kernel module programming. I suggest you study the LDD3 basic sections and http://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN978 for a beginner.

Efficient way to browse header definitions

As an example: on my system (Ubuntu 10.04), the sockaddr structure is defined in /bits/sockaddr.h as
struct sockaddr{
_SOCKADDR_COMMON (sa_); /*...*/
char sa_data[14]; /*...*/
};
and similarly for sockaddr_in, with first field name sin_.
However, all the examples I see access the field sin_
structure_name.sin_family
I meant to track down the typedef (?) for completeness, followed included headers and such, but failed (I got to sa_family_t and similar).
As a more general question: is there, say, a searchable online source where you can simply search for where a macro or typedef is in the header files - either for a particular Ubuntu distribution, or more generically for 'typical' Linux installations? Or, obviously, a clever way from within Ubuntu's shell; or some description of how to be more efficient doing this any other idea.
This is the link:
LXR / The Linux Cross Reference
done...i'll get you the reference for the Linux Kernel API Browser later (used to be able to find it online somewhere). There's the Linux Kernel Archives for the actual source code, which you probably could generate documentation from anyways.
Sorry, but I've not come across something as beautiful as say, the
jQuery API Browser. Hopefully the 'Ubuntu Manpage' #
manpages.ubuntu.com/manpages/lucid/man7/netdevice.7.html, for example,
might suffice. Also for stuff like the struct sockaddr{, you might
like to check out the Linux Kernel API Browser (or something similar)
as that belongs to standard Linux networking protocol headers.
You could try: http://www.google.com/codesearch perhaps?

Resources