Open Anonymous941 opened 4 months ago
If my memory serves me correctly (I haven’t opened this project for 9 years), you can use parportvirt instead of a real port. And regarding the second question - most likely not. Can you give me an example of how you would like to do this?
I appreciate your help on a 9-year-old project :)
I have a program that uses this code to read from an LPT port
#define LPT_PORT 0x378
#define LPT_DATA LPT_PORT + 0
#define LPT_STATUS LPT_PORT + 1
#define LPT_CONTROL LPT_PORT + 2
unsigned char inp {
return inb(port);
}
void outp(unsigned char data, int port)
{
ioperm(port,1,1);
outb(data, port);
}
I'm trying to emulate this in a virtual machine, and use a userland program to read/write from the virtual parallel port, but I can't figure out how to do it. QEMU won't let me add a virtual parallel port and I don't know how to have GDB break on access to IO like this (or if it's even possible). Is this even MMIO or just reading it directly from the CPU?
Unfortunately, recompiling it isn't an option, as only some of the source code is there (long story), and I'm kind of lost on how to approach this. Is a custom driver like this the best option?
As I understand QEMU with "-parallel file:\<filename>" isn't suitable, right?
As I know GDB can't directly break on I/O port access, and custom driver can be a best option in this case (but I didn't test it for a modern linux kernels)
As I understand QEMU with "-parallel file:
" isn't suitable, right?
The problem is that there's no way to send data back, it just logs write operations to a file...
As I know GDB can't directly break on I/O port access, and custom driver can be a best option in this case (but I didn't test it for a modern linux kernels)
I've been trying to do this, but I have no idea how to actually implement it due to the lack of information on the Internet about port-mapped I/O
Also, thanks so much for your help (not sarcastic), I've been struggling with this for weeks
After a lot of digging, I found request_region
which is hopefully what I need to do
I've finally managed to make this driver appear in /proc/ioports
, but any inb
requests in that range still return 0xff
. Which function is called when the range is accessed?
$ cat /proc/ioports
...
0378-037f : parport0
...
diff --git a/parportvirt/parportvirt.c b/parportvirt/parportvirt.c
index 7b712eb..54f01f8 100644
--- a/parportvirt/parportvirt.c
+++ b/parportvirt/parportvirt.c
@@ -183,6 +183,10 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
static struct parport * pp = NULL;
+static struct resource * io = NULL;
+
+#define REGION_START 0x378
+#define REGION_SIZE 0x8
static int __init uss720_init(void){
pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops);
@@ -191,12 +195,22 @@ static int __init uss720_init(void){
pp->private_data = NULL;
pp->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_TRISTATE | PARPORT_MODE_EPP | PARPORT_MODE_ECP | PARPORT_MODE_COMPAT;
parport_announce_port(pp);
+ // https://github.com/0xAX/linux-insides/blob/master/MM/linux-mm-2.md
+ io = request_region(REGION_START, REGION_SIZE, pp->name);
+ if(!io){
+ printk(KERN_ERR "error requesting region\n");
+ return -ENOMEM;
+ }
+ printk("registered resource start=%pa end=%pa flags=%lu\n", &(io->start), &(io->end), io->flags);
printk("uss720_init\n");
return 0;
}
static void __exit uss720_cleanup(void){
printk("uss720_cleanup\n");
+ if(io){
+ release_region(REGION_START, REGION_SIZE);
+ }
if(pp){
parport_remove_port(pp);
parport_put_port(pp);
Would it be possible to use this without a real parallel port, so I can simulate one by writing to
/dev/parportsnif0
? Also, does this work when userland processes use x86 ASMOUT
(viaioctl
andoutb
)?