Without making .ko, I know that it is possible to run user process in kernel mode. But I don't know how to make.
I will put the question otherway, is it possible to set the supervisor bit in user process?
Because as we know when sys call is triggered it will generate int80 which puts exec mode to kernel and while returning back from sys-call post wrapper disables it back to user mode. Instead is it possible that in post call we still maintain the mode of supervisor?
what problem do you want to solve by doing this? you seem to have a solution in mind and want linux to behave like some other system where this solution is the right one. maybe you have to adapt your solution to how unix works and get it cleaner, more crash proof and more portable on the way.
what do you mean with 'I know that it is possible to run user process in kernel mode', which example do you have in mind? I don't want to have to guess your thoughts, just tell us. there is no simple supervisor bit that lets you just do more, at least not on i386, and not every syscall goes through int80.
user space processes don't work in kernel mode, the programming model is totally different. code using the in kernel programming model is called modules. what you can do from user space is mmap()ing your device's i/o area and get interrupts via the UIO interface (cf. http://lwn.net/Articles/232575/) which only requires a very minimal kernel module just for receiving and transmitting the interrupts.
I have a set of code which was earlier running on some other OS where everything runs in supervisor mode.
Now I am porting it to linux. In the code there are hardcoded address which touches the PCI device mem. I don't want to modify the code.
I want this process to be run in kernel mode so that it can access the PCI mem.
pci device memory by definition has no hardcodeable address. it may have worked by chance (because hardware and setup code never changed) but this simplistic approach is not supported in linux. you can get a base address from the kernel and add your constant offsets, of course, this way you only have to split your absolute addresses into base address and offset. this book http://lwn.net/Kernel/LDD3/ may be what you need, or have a real look at the UIO interface.
You can solve this specific problem by using mmap() on file /dev/mem to map the desired portion of PCI memory space into your process's address space at the hard-coded address. To discovery the true addresses, read the BAR registers from the device's config space by using the lspci command or by looking at the config file in the device's directory under /sys/bus/pci/devices.
Mmap is working fine for me. But the problem is mapped address is not to the one I have (i.e hardcoded address).
The first param to mmap tells where I want the mapping addr to be. But it is neglecting and mapping to some low address.
To adjust to this I need to change all the hardcoded address which consumes my huge time.
Without changing my hardcoded address if I get any alternative soln I will be very happy.
32 bit processes on a 64 bit kernel apparently have a full 4G address space, the kernel sits at the end of the (inaccessible for 32 bit processes) 64 bit address space. as you can see here:
cat uses the full 4G space to map libraries, heap, stack.
these days it's nearly impossible to buy a pc without 64 bit capability and if in doubt you can use a normal 32 bit userspace on a 64 bit kernel.
btw, why did the original developer choose to hardcode the addresses in the code? it is much more readable to at lease use constants for that, eg. BASE=0xd000000, COMMAND=BASE+0x123, etc. someone decided to write unmaintainable code, here, and now you have to clean up the mess.
Under current Linux kernels, the various PCI BARs exist as mmap-able files in /sys/bus/pci; for example, /sys/bus/pci/devices/0000:02:09.1/resource0 is BAR 0 of device 0000:02:09.1 on this machine. You could mmap() the BARs at the address you want and access the device directly.
you can't
You can't.
Unless you make it a kernel module - for which you'll need program sources and some degree of kernel programming.
Or, define what you understand by "running process in kernel mode".
Without making .ko, I know
Without making .ko, I know that it is possible to run user process in kernel mode. But I don't know how to make.
I will put the question otherway, is it possible to set the supervisor bit in user process?
Because as we know when sys call is triggered it will generate int80 which puts exec mode to kernel and while returning back from sys-call post wrapper disables it back to user mode. Instead is it possible that in post call we still maintain the mode of supervisor?
what do you want to solve
what problem do you want to solve by doing this? you seem to have a solution in mind and want linux to behave like some other system where this solution is the right one. maybe you have to adapt your solution to how unix works and get it cleaner, more crash proof and more portable on the way.
what do you mean with 'I know that it is possible to run user process in kernel mode', which example do you have in mind? I don't want to have to guess your thoughts, just tell us. there is no simple supervisor bit that lets you just do more, at least not on i386, and not every syscall goes through int80.
user space processes don't work in kernel mode, the programming model is totally different. code using the in kernel programming model is called modules. what you can do from user space is mmap()ing your device's i/o area and get interrupts via the UIO interface (cf. http://lwn.net/Articles/232575/) which only requires a very minimal kernel module just for receiving and transmitting the interrupts.
I have a set of code which
I have a set of code which was earlier running on some other OS where everything runs in supervisor mode.
Now I am porting it to linux. In the code there are hardcoded address which touches the PCI device mem. I don't want to modify the code.
I want this process to be run in kernel mode so that it can access the PCI mem.
pci mem
pci device memory by definition has no hardcodeable address. it may have worked by chance (because hardware and setup code never changed) but this simplistic approach is not supported in linux. you can get a base address from the kernel and add your constant offsets, of course, this way you only have to split your absolute addresses into base address and offset. this book http://lwn.net/Kernel/LDD3/ may be what you need, or have a real look at the UIO interface.
One solution
You can solve this specific problem by using mmap() on file /dev/mem to map the desired portion of PCI memory space into your process's address space at the hard-coded address. To discovery the true addresses, read the BAR registers from the device's config space by using the lspci command or by looking at the config file in the device's directory under /sys/bus/pci/devices.
Mmap is working fine for me.
Mmap is working fine for me. But the problem is mapped address is not to the one I have (i.e hardcoded address).
The first param to mmap tells where I want the mapping addr to be. But it is neglecting and mapping to some low address.
To adjust to this I need to change all the hardcoded address which consumes my huge time.
Without changing my hardcoded address if I get any alternative soln I will be very happy.
What is your hard-coded
What is your hard-coded address? Most kernels on 32-bit machines won't let a process use an address that is >= 0xc0000000.
My hardcoded address is
My hardcoded address is 0xd0000000.
Thats why I wanted to run this process in kernel mode.
64 bit kernel
32 bit processes on a 64 bit kernel apparently have a full 4G address space, the kernel sits at the end of the (inaccessible for 32 bit processes) 64 bit address space. as you can see here:
cat uses the full 4G space to map libraries, heap, stack.
these days it's nearly impossible to buy a pc without 64 bit capability and if in doubt you can use a normal 32 bit userspace on a 64 bit kernel.
btw, why did the original developer choose to hardcode the addresses in the code? it is much more readable to at lease use constants for that, eg. BASE=0xd000000, COMMAND=BASE+0x123, etc. someone decided to write unmaintainable code, here, and now you have to clean up the mess.
mmap() the BARs
Under current Linux kernels, the various PCI BARs exist as mmap-able files in /sys/bus/pci; for example, /sys/bus/pci/devices/0000:02:09.1/resource0 is BAR 0 of device 0000:02:09.1 on this machine. You could mmap() the BARs at the address you want and access the device directly.
____call_usermodehelper().
____call_usermodehelper().