I have written a Loadable Kernel Module (LKM) which wraps the audio-driver under /dev/snd/pcmC0D0p .
Therefore I moved pcmC0D0p to pcmC0D0p_bak, renamed my driver to pcmC0D0p and passthru every command like MMAP, IOCTL etc. (but doing other things before forwarding the MMAPed-data).
This is bad, I know (but it's my first step in linux-programing) but it worked.
Today, I read in an article about Userspace device drivers.
Now I'm wondering: should this really be possible? Write a "driver" with userspace-code, implemented methods like MMAP & IOCTL and put it in place of a normal kernel-device (/dev/snd/pcmC0D0p)?
It isn't, isn't it?
IF it's possible, has anyone a simple example, a reference? Anything is really welcome!
It is possible to write userspace device drivers, but not quite in the way you're thinking.
An example is the uio_pci_generic module, this can be programmed (via /proc) with the ID of a PCI device and will make the device's memory available to you via mmap. You can receive interrupts by blocking on a read call.
Note how this does not allow you to pretend to be a driver, only to perform driver-like actions (communicating directly with a hardware device, receiving interrupts, etc). No userspace program can ever service a call to ioctl, or expose itself as a character device, without the help of some kernel module.
Related
I'm new to RISC-V and operating system developing, and I'm now trying to make a simple hypervisor-like interface in RISC-V. What stops me right now is that I have no idea about how to trigger a machine call (like RISC-SBI) which stands in firmware level and machine-mode for a user-mode applications? Since recently user-level applications communicate with kernel by system calls. However I may have to make the call skip the kernel and directly to the firmware. How to achieve this for a high-levl application?
I' really in a difficult time. So much thanks for your replies.
To make a system call, load register a0 with which call you want to make (and possibly arguments to the syscall in other registers), then execute an ecall instruction with 01 in func3, which specifies Supervisor mode. To return to user mode after executing the system call code, the OS kernel executes an sret instruction, which returns to User mode from Supervisor mode. This is documented in the Privileged Architecture specification, but I'll admit it requires a bit of knowledge ahead of time to figure out where to look.
My question is quite simple.
I encountered this sys_vm86old syscall (when reverse engineering) and I am trying to understand what it does.
I found two sources that could give me something but I'm still not sure that I fully understand; these sources are
The Source Code and this page which gives me this paragraph (but it's more readable directly on the link):
config GRKERNSEC_VM86
bool "Restrict VM86 mode"
depends on X86_32
help:
If you say Y here, only processes with CAP_SYS_RAWIO will be able to
make use of a special execution mode on 32bit x86 processors called
Virtual 8086 (VM86) mode. XFree86 may need vm86 mode for certain
video cards and will still work with this option enabled. The purpose
of the option is to prevent exploitation of emulation errors in
virtualization of vm86 mode like the one discovered in VMWare in 2009.
Nearly all users should be able to enable this option.
From what I understood, it would ensure that the calling process has cap_sys_rawio enabled. But this doesn't help me a lot...
Can anybody tell me ?
Thank you
The syscall is used to execute code in VM86 mode. This mode allows you to run old "real mode" 32bit code (like present in some BIOS) inside a protected mode OS.
See for example the Wikipedia article on it: https://en.wikipedia.org/wiki/Virtual_8086_mode
The setting you found means you need CAP_SYS_RAWIO to invoke the syscall.
I think X11 especially is using it to call BIOS methods for switching the video mode. There are two syscalls, the one with old suffix offers less operations but is retained for binary (ABI) compatibility.
Normally in Linux PCI drivers may expose a control interface to user-land
via a character device, e.g. /dev/drv_ctl, and a user application can
read/write I/O control commands with ioctl() on the open file descriptor.
In Linux we create this with register_chrdev() kernel API.
I would like to have the same or similar mechanism and behaviour on Solaris, but seems that on Solaris it works slightly different; DDI routine ddi_create_minor_node() requires a node type indicating audio, block, net etc. device, this looks quite vague to me, for example what type a crypto PCI device belongs to?
Also, it seems that ddi_create_minor_node() creates a node under /devices/* and not under /dev/*
I would appreciate if someone could clarify my doubts and point out at the right directions.
Thanks.
Typically you create a symlink under /dev yourself, using a name which is useful to you. That would point to your actual /devices path which was created by calling ddi_create_minor_node(). You'll find the list of ddi node types in <sys/sunddi.h>; for a crypto device (what even is that?) you'd probably want DDI_PSEUDO.
possibly a really dumb question, but could someone explain why one could not write assembly code to trigger system functions or control hardware? For example, would it not be possible to write code to switch screen off/on or even the device's phone?
I am not talking about jailbreaking the device, nor making an app for the app store. Normal app with assembly to call system functions.
If indeed possible, anyone have a good reference or starting point of achieve such tasks?
Thanks
iPhones use a memory-protected operating system in which each user process is contained in its own virtual memory address space. The address space is protected by the memory management unit (MMU) hardware and trying to access memory outside of regions given to the process by the OS will result in an exception. The OS reserves hardware memory ranges to itself and does not make it available to user processes. As such, it is not possible to directly interface to the hardware from a user process.
It is certainly possible to call system functions from assembly code. And what do you think a C or C++ application does? It does exactly that. C/C++ and assembly code all ultimately convert (at compile time) into machine code that the CPU executes.
I'm not sure where the guide would be for doing things like this, but you can certainly run a C program in a debugger and see how it calls various system functions or you can disassemble this program and read the disassembly without running the program in the debugger.
In any event, you will not get more control over the device from a program written in assembly than from a program written in C. The OS should restrict direct access to certain I/O devices and memory areas at the CPU level, where there's no distinction between assembly and C, it's all the same to the CPU, just a bunch of instructions in machine code.
I wanted to know is there any reason to minimize use of system call in code and what is the alternate of not using system call ,one would say use API but api in turns use system call
Is it True??
Because most system calls have an inherent overhead. A system call is a means of tapping into the kernel, a controlled gateway towards obtaining some service.
When performing a system call, some actions are taken (warning, it's a simplification):
You invoke a library (wrapper) function
The function puts the arguments where they are expected. Also the function puts the number of the system call in eax
The function calls a trap (int 0x80 or whatever)
The processor is switched to kernel mode
The kernel invokes some system_call routine
The registers are saved onto the kernel stack
The arguments are checked to be valid
The action is performed
The registers are restored from the kernel stack
The processor is returned to user mode
The function (finally...) returns
And I probably forgot some of the steps. Doesn't this sound like a lot of work ? All you wanted is the bold part. The rest is overhead.
A system call requires that the system switches from User mode to Kernel mode. This makes system calls expensive.
An article to understand this better:
Understanding User and Kernel Mode - Jeff Atwood
First, if you use framework or APIs (e.g. by using wxWidgets instead of rendering the windows manually, or the GNU C library) your code is portable between different operating systems.
Second, you if you're using APIs you won't have problems if the manufacturer changes how the operating system works under the hood, as the APIs (should) be the same as before.
The only reason that cames to my mind right now is portability issues. If you use system calls, your code will only run on that Operating System. And if you need to compile the same source to another OS, you will be in trouble, the API may be completely different.