Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use without real parallel port? #1

Open
Anonymous941 opened this issue Jul 2, 2024 · 6 comments
Open

Use without real parallel port? #1

Anonymous941 opened this issue Jul 2, 2024 · 6 comments

Comments

@Anonymous941
Copy link

Anonymous941 commented Jul 2, 2024

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 ASM OUT (via ioctl and outb)?

@strezh
Copy link
Owner

strezh commented Jul 3, 2024

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?

@Anonymous941
Copy link
Author

Anonymous941 commented Jul 3, 2024

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?

@strezh
Copy link
Owner

strezh commented Jul 8, 2024

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)

@Anonymous941
Copy link
Author

Anonymous941 commented Jul 9, 2024

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

@Anonymous941
Copy link
Author

After a lot of digging, I found request_region which is hopefully what I need to do

@Anonymous941
Copy link
Author

Anonymous941 commented Jul 9, 2024

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);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants