I have a minor and major numbers of a char device, and I want to turn them into dev_t (which used to hold device numbers), but I don't want to do all the process of building and writing a module, insmod it into the kernel and etc.
What's an easy way and fast to use the MKDEV macro?
#include <linux/kdev_t.h>
#include <linux/types.h>
dev_t device_num = MKDEV(int major, int minor);
Using a standard C program will not work, obviously, because it's kernel-code/kernel-space.
Update: Writing a User-Space program does work but I can't use the dev_t datatype, maybe because it can be used only by the kernel?
#include <linux/kdev_t.h> // MKDEV
#include <linux/types.h> // dev_t
#include <stdio.h> // I/O
int main(void)
{
int device_id = MKDEV(10, 249);
printf("%d\n", device_id); // 2809
return 0;
}
The header linux/kdev_t.h which provides MKDEV macro is accessible for user space programs too.
Definition of dev_t type is not accessible for the user space programs (headers linux/types.h are different for kernel and user), but for result of MKDEV you may use any integer type of 16 bit or more.
#include <linux/kdev_t.h>
<...>
int device_id = MKDEV(10, 249);
Related
I am debugging faulty serial connection on TrueSTM Atollic IDE.
Watch window, Expressions requires me to select a variable and display it as an array. Drawback is that I need to reselect that on each recompile, it gets very slow for +100 values and it doesn't look very clear to me.
So I have created function which simply prints out the bytes held in one of the buffers, those are then displayed to me over to SWV Console.
freertos.c
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
#include "stdbool.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
uint8_t X [4] = {0xFF,0xFF,0xFF,0xFF};
uint8_t * xt = X;
osThreadDef(CAN_Producer, FrameExtractorNEW, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(CAN_Producer), NULL);
void FrameExtractorNEW(void const * argument){
Print_Bytes(xt,4); // fails
printf("Cheese\n") // fails
}
main.c
#include "main.h"
#include "cmsis_os.h"
#include "can.h"
#include "dma.h"
#include "usart.h"
#include "gpio.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_CAN2_Init();
MX_CAN1_Init();
MX_USART3_UART_Init();
MX_FREERTOS_Init();
osKernelStart();
while (1)
{}
}
// accept pointer to first element, and number of consecutive byte values to display
void Print_Bytes(uint8_t * a1, int bytes_to_read){
for (int i = 0; i<bytes_to_read; i++){
printf("0x%02X " , *(a1+i));
}
}
Easy and straight forward stuff so far, or so it seems.
My problem is that if I try to use the function Print_Bytes() in the freertos.c it will work, but only provided that it has been invoked at least once prior in main.c. Printing out anything using printf() in main.c at least once will also make it work elsewhere in other files.
Without that 'enabling' program execution goes to HardFault_Handler() with following faults.
I have necessary includes for printf() and Print_Bytes() for the functions that call them but it doesn't seem to be enough to get it to work as I expect it should work.
I bet that the printf on the first run initializes some internal variables. In the main it uses the main program heap and the stack. If you use for the first time in the task it does it on the task heap and stack and none of the standard allocations may do not work in this context (printf uses the malloc function).
Personally I have written my own freeRTOS safe versions of this family of functions. It is very bad practice to use thread unsafe functions in the multi thread environment.
likely your minimal heap size is not big enough (ld file ide option ...)
default lib (nano etc ..) will call sbrake" to split stack en enlarge heap but it is nto mean to be used in rtos context so it wan't work if the stack pointer is not the main stack :(
So if you do a first print or malloc etc ...inside main before oskernel start it will help (sp is main stack) by enlarging your heap .
If you do it first time in a thread it wan't succeed cos "sp" use by sbrake is freertos task memory not the "main stack" thus printf fail to alloc mem
You may notice that printf rely or std lib malloc that is not re-entrant nor multi thread safe ... a safer formated print can be done via vsnprintf formating string to a task owned buffer.
I am using the Big Nerd Ranch book Objective-C Programming, and it starts out by having us write in C in the first few chapters. In one of my programs it has me create, I use the sleep function. In the book it told me to put #include <stdlib.h> under the #include <stdio.h> part. This is supposed to get rid of the warning that says "Implicit declaration of function 'sleep' is invalid in C99". But for some reason after I put #include <stdlib.h>, the warning does not go away.. This problem does not stop the program from running fine, but I was just curious on which #include I needed to use!
The sleep man page says it is declared in <unistd.h>.
Synopsis:
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
sleep is a non-standard function.
On UNIX, you shall include <unistd.h>.
On MS-Windows, Sleep is rather from <windows.h>.
In every case, check the documentation.
this is what I use for a cross-platform code:
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
int main()
{
pollingDelay = 100
//do stuff
//sleep:
#ifdef _WIN32
Sleep(pollingDelay);
#else
usleep(pollingDelay*1000); /* sleep for 100 milliSeconds */
#endif
//do stuff again
return 0;
}
What is the proper #include for the function 'sleep()'?
sleep() isn't Standard C, but POSIX so it should be:
#include <unistd.h>
sleep(3) is in unistd.h, not stdlib.h. Type man 3 sleep on your command line to confirm for your machine, but I presume you're on a Mac since you're learning Objective-C, and on a Mac, you need unistd.h.
Given that sleep is a non-standard function, I created a sleep function with the standard library time.h
#include <time.h>
void sleep(double s) {
time_t cur_time = time(NULL);
while ((difftime(time(NULL), cur_time)) < s);
}
I'm trying to write a portable function in c that compares the last modified times of 2 files. The files are tiny and written one right after the other, so I need finer granularity than 1 second (milliseconds).
There seems to be a plethora of time/date functions...
You should look to the stat() function. It's available on *nix and on windows.
They will both return you a struct containing a field name st_msize. They are the finest functions I have heard of in order to get this kind of information from an Operating System.
Since you need portability, beware to take care of the various different types available on Windows. On *NIX, it's a classic time_t structure. If you include specific call, you can obtain nano seconds mtime: it was defined in POSIX.1-2008, according to the man page.
You can also take a look at how you can deal with 64/32 bit time_t
The C standard does not have any functions for this, but the Posix specification does. The 2008 edition even provides sub-second timestamps. #define _POSIX_C_SOURCE 200809L
The following code should give you an idea how to use it.
#define _POSIX_C_SOURCE 200809L
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h> // for printf
#include <stdlib.h> // for EXIT_FAILURE
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
struct stat st = {0};
int ret = lstat(argv[i], &st);
if (ret == -1) {
perror("lstat");
return EXIT_FAILURE;
}
printf("%s: mtime sec=%lld nsec=%lld\n", argv[i],
(long long) st.st_mtim.tv_sec,
(long long) st.st_mtim.tv_nsec);
}
return 0;
}
For POSIX UNIX, stat() is portable and gives struct stat st_mtime which is the modification time in epoch seconds. Windows stat returns windows time values, and has creation time rather than st_ctime.
For non-POSIX UNIX implementations, Windows and other OSes there is no portable concept of file modification time. So, depending on your idea of portable, this whole concept may or my not work for you.
I have an application that has both two external kernel modules and a userspace daemon. I want to load the modules from the daemon code, written in C, at startup, and unload them on clean exit. Can I load them in a cleaner way than doing system("modprobe module"); and unload them using the corresponding rmmod?
init_module / remove_module minimal runnable example
Tested on a QEMU + Buildroot VM and Ubuntu 16.04 host with this simple parameter printer module .
We use the init_module / finit_module and remove_module Linux system calls.
The Linux kernel offers two system calls for module insertion:
init_module
finit_module
and:
man init_module
documents that:
The finit_module() system call is like init_module(), but reads the module to be loaded from the file descriptor fd. It is useful when the authenticity of a kernel module can be determined from its location in the filesystem; in cases where that is possible, the overhead of using cryptographically signed modules to determine the authenticity of a module can be avoided. The param_values argument is as for init_module().
finit is newer and was added only in v3.8. More rationale: https://lwn.net/Articles/519010/
glibc does not seem to provide a C wrapper for them, so we just create our own with syscall.
insmod.c
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#define init_module(module_image, len, param_values) syscall(__NR_init_module, module_image, len, param_values)
#define finit_module(fd, param_values, flags) syscall(__NR_finit_module, fd, param_values, flags)
int main(int argc, char **argv) {
const char *params;
int fd, use_finit;
size_t image_size;
struct stat st;
void *image;
/* CLI handling. */
if (argc < 2) {
puts("Usage ./prog mymodule.ko [args="" [use_finit=0]");
return EXIT_FAILURE;
}
if (argc < 3) {
params = "";
} else {
params = argv[2];
}
if (argc < 4) {
use_finit = 0;
} else {
use_finit = (argv[3][0] != '0');
}
/* Action. */
fd = open(argv[1], O_RDONLY);
if (use_finit) {
puts("finit");
if (finit_module(fd, params, 0) != 0) {
perror("finit_module");
return EXIT_FAILURE;
}
close(fd);
} else {
puts("init");
fstat(fd, &st);
image_size = st.st_size;
image = malloc(image_size);
read(fd, image, image_size);
close(fd);
if (init_module(image, image_size, params) != 0) {
perror("init_module");
return EXIT_FAILURE;
}
free(image);
}
return EXIT_SUCCESS;
}
GitHub upstream.
rmmod.c
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#define delete_module(name, flags) syscall(__NR_delete_module, name, flags)
int main(int argc, char **argv) {
if (argc != 2) {
puts("Usage ./prog mymodule");
return EXIT_FAILURE;
}
if (delete_module(argv[1], O_NONBLOCK) != 0) {
perror("delete_module");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
GitHub upstream.
Busybox source interpretation
Busybox provides insmod, and since it is designed for minimalism, we can try to deduce how it is done from there.
On version 1.24.2, the entry point is at modutils/insmod.c function insmod_main.
The IF_FEATURE_2_4_MODULES is optional support for older Linux kernel 2.4 modules, so we can just ignore it for now.
That just forwards to modutils.c function bb_init_module.
bb_init_module attempts two things:
mmap the file to memory through try_to_mmap_module.
This always sets image_size to the size of the .ko file as a side effect.
if that fails, malloc the file to memory with xmalloc_open_zipped_read_close.
This function optionally unzips the file first if it is a zip, and just mallocs it otherwise.
I don't understand why this zipping business is done, since we can't even rely on it because the try_to_mmap_module does not seem to unzip things.
Finally comes the call:
init_module(image, image_size, options);
where image is the executable that was put into memory, and options are just "" if we call insmod file.elf without further arguments.
init_module is provided above by:
#ifdef __UCLIBC__
extern int init_module(void *module, unsigned long len, const char *options);
extern int delete_module(const char *module, unsigned int flags);
#else
# include <sys/syscall.h>
# define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts)
# define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
#endif
ulibc is an embedded libc implementation, and it seems to provide init_module.
If it is not present, I think glibc is assumed, but as man init_module says:
The init_module() system call is not supported by glibc. No declaration is provided in glibc headers, but, through a quirk of history, glibc does export an ABI for
this system call. Therefore, in order to employ this system call, it is sufficient to manually declare the interface in your code; alternatively, you can invoke
the system call using syscall(2).
BusyBox wisely follows that advice and uses syscall, which glibc provides, and which offers a C API for system calls.
insmod/rmmod use the functions init_module and delete_module to do this, which also have a man-page available. They both declare the functions as extern instead of including a header, but the man-page says they should be in <linux/module.h>.
I'd recommend against the use of system() in any daemon code that runs with root permissions as it's relatively easy to exploit from a security standpoint. modprobe and rmmod are, indeed, the right tools for the job. However, it'd be a bit cleaner and much more secure to use an explicit fork() + exec() to invoke them.
I'm not sure there's a cleaner way than system.
But for sure, if you want to load/unload the modules from your userspace daemon, then you force yourself to run the daemon as root*, which may not be considered as secure.
*: or you can add the explicit commands in the sudoers file, but this will be a nightmare to manage when deploying your application.
You can perform the same tasks that modprobe and Co. do, but I doubt that could be characterized as cleaner.
I'm new to C89, and trying to do some socket programming:
void get(char *url) {
struct addrinfo *result;
char *hostname;
int error;
hostname = getHostname(url);
error = getaddrinfo(hostname, NULL, NULL, &result);
}
I am developing on Windows. Visual Studio complains that there is no such file if I use these include statements:
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
What should I do? Does this mean that I won't have portability to Linux?
On Windows, instead of the includes you have mentioned, the following should suffice:
#include <winsock2.h>
#include <windows.h>
You'll also have to link to ws2_32.lib. It's kind of ugly to do it this way, but for VC++ you can do this via: #pragma comment(lib, "ws2_32.lib")
Some other differences between Winsock and POSIX include:
You will have to call WSAStartup() before using any socket functions.
close() is now called closesocket().
Instead of passing sockets as int, there is a typedef SOCKET equal to the size of a pointer. You can still use comparisons with -1 for error, though Microsoft has a macro called INVALID_SOCKET to hide this.
For things like setting non-blocking flags, you'll use ioctlsocket() instead of fcntl().
You'll have to use send() and recv() instead of write() and read().
As for whether or not you will lose portability with Linux code if you start coding for Winsock... If you are not careful, then yes. But you can write code that tries to bridge the gaps using #ifdefs..
For example:
#ifdef _WINDOWS
/* Headers for Windows */
#include <winsock2.h>
#include <windows.h>
#else
/* Headers for POSIX */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
/* Mimic some of the Windows functions and types with the
* POSIX ones. This is just an illustrative example; maybe
* it'd be more elegant to do it some other way, like with
* a proper abstraction for the non-portable parts. */
typedef int SOCKET;
#define INVALID_SOCKET ((SOCKET)-1)
/* OK, "inline" is a C99 feature, not C89, but you get the idea... */
static inline int closesocket(int fd) { return close(fd); }
#endif
Then once you do something like this, you can code against the functions which appear in both OS's, using these wrappers where appropriate.