Suppose I want to create, in the spirit of /dev/zero, a file /dev/seven that produces the character '7' whenever it is read from. How should I go about doing something like this? Would I need to modify the kernel?
Yes, you'd need to create a driver for that special character device.
For linux, I'd suggest you read Linux Device Drivers by Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman. (Chapter 3 talks about char drivers, but do read at least the first two chapters also.)
A device driver is not necessary, a fifo special file plus a user program generating the stream of 7 is perfectly able to provide this behavior.
You'll need about a five line shell script, all told.
There's a short example of creating a device driver for Linux here, which might help to get you started:
http://www.freesoftwaremagazine.com/articles/drivers_linux
Related
Is there a way with pyusb to unbind a USB device?
I know using the following bash the USB is unbound.
DEVICE=$(grep 064f /sys/bus/usb/devices/*/idVendor | tr '/' ' ' | awk '{ print $5 }')
/bin/bash -c "echo $DEVICE >/sys/bus/usb/drivers/usb/unbind"
But for various reasons I like to move away from bash and switch to Python, and ideally avoid maintaining my custom, complicated logic. So using a existing library makes sense to me.
Selected answer in stackoverflow.com#q54863367 suggests detach_kernel_driver to work for this purpose, but I don't see that happening on my environment; It does unmount the volume in the designated USB device (confirmed by watching the disk space on the USB disappears in lsblk's output) but I still see that OS detects the USB device.
$ ipython
In [7]: import usb
...: dev = usb.core.find(idVendor=0x064f, idProduct=0x03f3)
In [8]: dev.detach_kernel_driver(0)
$ watch lsusb
:
Bus 002 Device 043: ID 064f:03f3 WIBU-Systems AG CmStick/M (article no. 1011)
Environment
Linux (At the time of writing, Ubuntu 16.04 (I know EoLed) or 18.04. But environment shouldn't be a limiting factor. Open for available solutions regardless the version.
UPDATE: My usecase requires mimicing removal of USB device. We've been happy with the operation typically called as un/bind, and also happy with the bash solution to realize un/bind.
A quick search of the PyUSB code makes it seem like there is no feature for binding or unbinding. So PyUSB is not the answer.
However, you don't need to use Bash to unbind a device. Python has a standard library that lets you get directory listings, read files, and write to files, so you can just use Python's standard library instead of Bash.
Thought I'd close OP but coudln't choose an appripriate reason so answer by myself instead.
As I concluded myself with a help from the maintainer in pyusb#399 I found I was misunderstood. Using detach_kernel_driver as suggested in stackoverflow.com#q54863367 worked for my purpose as well.
Using uClinux we have one of two flash devices installed, a 1GB flash or a 2GB flash.
The only way I can think of solving this is to somehow get the device ID - which is down the in the device driver code, for me that is in:
drivers/mtd/devices/m25p80.c
I have been using the command mtdinfo (which comes from mtdutils binaries, derived from mtdinfo.c/h). There is various information stored in here about the flash partitions including flash type 'nor' eraseblock size '65536', etc. But nothing that I can identify the chip with.
Its not very clear to me how I can get information from "driver-land" into "user-land". I am looking at trying to extend the mtdinfo command to print more information but there are many layers...
What is the best way to achieve this?
At the moment, I have found no easy way to do this without code changes. However I have found an easy code change (probably a bit of a hack) that allows me to get the information I need:
In the relevant file (in my case drivers/mtd/devices/m25p80.c) you can call one of the following:
dev_err("...");
dev_alert("...");
dev_warn("...");
dev_notice("...");
_dev_info("...");
Which are defined in include/Linux/device.h, so they are part of the Linux driver interface so you can use them from any driver.
I found that the dev_err() and devalert() both get printed out "on screen" during run time. However all of these device messages can be found in /var/log/messages. Since I added messages in the format: dev_notice("JEDEC id %06x\n", jedecid);, I could find the device ID with the following command:
cat /var/log/messages | grep -i jedec
Obviously using dev_err() ordev_alert() is not quite right! - but dev_notice() or even _dev_info() seem more appropriate.
Not yet marking this as the answer since it requires code changes - still hoping for a better solution if anyone knows of one...
Update
Although the above "solution" works, its a bit crappy - certainly will do the job and good enough for mucking around. But I decided that if I am making code changes I may as well do it properly. So I have now implemented changes to add an interface in sysfs such that you can get the flash id with the following command:
cat /sys/class/m25p80/m25p80_dev0/device_id
The main function calls required for this are (in this order):
alloc_chrdev_region(...)
class_create(...)
device_create(...)
sysfs_create_group(...)
This should give enough of a hint for anyone wanting to do the same, though I can expand on that answer if anyone wants it.
i am a newbie to assembly and program in c (use GCC in Linux)
can anyone here tell me how to compile c code into assembly and boot from it using pen drive
i use the command (in linux terminal) :
gcc -S bootcode.c
the code gives me a bootcode.S file
what do i do with that ???
i just wanna compile the following code and run it directly from a USB stick
#include<stdio.h>
void main()
{
printf ("hi");
}
any help here ???
First of all,
You Should be aware that when you are writing bootloader codes , you should know that you are CREATING YOUR OWN ENVIRONMENT of CODE, that means, there is nothing such ready made C Library available to you or anything similar , ONLY and ONLY BIOS SERVICES (or INTERRUPT ROUTINES).
Now, if you got this, you will probably figure out that the above code won't boot since, you don't have the "stdio.h" header, this means that the CPU when executing your compiled code won't find this header and thereby won't understand what is "printf" (since printf is a method of the stdio.h header).
So if you want to print any string you need to write this function by YOUR OWN either in a separate file as a header and link its object file at compilation time when creating the final binary file or in the same file. it is up to you. There could be other ways, I'm not well familiar with them, just do some researches.
Another thing you should know, it is the BIOS who is responsible for loading this boot code (your above code in your case) into memory location 0x07C00 (0x0000h:0x7C00 in segment:offset representation), so you HAVE to mention in your code that you are writing this code on this memory location, either by
1-using the ORG instruction
2-Or by loading the appropriate registers for that (cs,ds,es)
Also, you should get yourself familiar with the segment:offset memory representation scheme, just google it or read intel manuals.
Finally, for the BIOS to load your code into the 0x07C00, the boot code must not exceed 512byte (ONLY ON FIRST SECTOR OF THE BOOTABLE MEDIA, since a sectore is 512byte) and he must find at the last two byte of this first sector (byte 510 & byte 511) of your code the boot signature 0x55AA, otherwise the BIOS won't consider this code AS BOOTABLE.
Usually this is coded as :
ORG 0x7C00
...
your boot code and to load more codes since 512byte won't be sufficient.
...
times 510 - ($ - $$) db 0x00 ; Zerofill up to 510 bytes
dw 0xAA55 ;Boot Sector signature,written in reverse order since it
will be stored as little endian notation
Just to let you know, I'm not covering everything here, because if so, I'll be writing pages about it, you need to look for more resources on the net, and here is a link to start with(coding in assembly):
http://www.brokenthorn.com/Resources/OSDevIndex.html
That's all, hopefully this was helpful to you...^_^
Khilo - ALGERIA
Booting a computer is not that easy. A bootloader needs to be written. The bootloader must obey certain rules and correspond with hardware such as ROM. You also need to disable interrupts, reserve some memory etc. Look up MikeOS, it's a great project that can better help you understand the process.
Cheers
I'm working on an audio recognition project.
For testing, I'd like to be able to have a program:
load audio data from a file
provide it to the Linux kernel, as if it were coming from a microphone
have any user-space program sampling the microphone be obtaining data sourced
from my file.
Is that possible in Linux without having to write a new kernel module?
EDIT: i guess that solution won't work .. but see my comment below.
this shoud be simple under linux.
here are the steps:
make a named pipe with mkfifo (mkfifo ~/audio_out.pipe)
cat the audiofile into this pipe (cat test.wav > ~/audio_out.pipe)
get the program you want to listen, to get input from this pipe. maybe you have to make a symlink for programs not flexible enough to read from any device.
I hope I got your question right.
I'm debugging communications with a serial device, and I need to see all the data flowing both directions.
It seems like this should be easy on Linux, where the serial port is represented by a file. Is there some way that I can do a sort of "bi-directional tee", where I tell my program to connect to a pipe that copies the data to a file and also shuffles it to/from the actual serial port device?
I think I might even know how to write such a beast, but it seems non-trivial, especially to get all of the ioctls passed through for port configuration, etc.
Has anyone already built such a thing? It seems too useful (for people debugging serial device drivers) not to exist already.
strace is very useful for this. You have a visualisation of all ioctl calls, with the corresponding structure decoded. The following options seems particularly useful in your case:
-e read=set
Perform a full hexadecimal and ASCII dump of all the data read from
file descriptors listed in the
specified set. For example, to see all
input activity on file descriptors 3
and 5 use -e read=3,5. Note that this
is independent from the normal tracing
of the read(2) system call which is
controlled by the option -e
trace=read.
-e write=set
Perform a full hexadecimal and ASCII
dump of all the data written to file
descriptors listed in the specified
set. For example, to see all output
activity on file descriptors 3 and 5
use -e write=3,5. Note that this is
independent from the normal tracing of
the write(2) system call which is
controlled by the option -e
trace=write.
I have found pyserial to be quite usable, so if you're into Python it shouldn't be too hard to write such a thing.
A simple method would be to write an application which opened
the master side of a pty and the tty under test. You would then
pass your tty application the slave side of the pty as the 'tty device'.
You would have to monitor the pty attributes with tcgetattr() on the pty
master and call tcsetattr() on the real tty, if the attributes changed.
The rest would be a simple select() on both fd's copying data bi-directionally and copying it to a log.
I looked at a lot of serial sniffers. All of them are based on the idea of making a virtual serial port and sniff data from that port. However, any baud/parity/flow changes will break connection.
So, I wrote my own sniffer :). Most of the serial ports now are just USB-to-serial converters. My sniffer collects data from USB through debugfs, parse it and output to the console. Also any baudrate changes, flow control, line events, and serial errors are also recorded. The project is in the early stage of development and for now, only FTDI is supported.
http://code.google.com/p/uscmon/
Much like #MBR, I was looking into serial sniffers, but the ptys broke the parity check. However, his sniffer was not helping me, as I'm using a CP2102, and not a FT232. So I wrote my own sniffer, by following this, and now I have one that can record file I/O on arbitrary files: I called it tracie.