Making a kmod
- Reply: Milan Obuch : "Re: Making a kmod"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 18 Oct 2025 21:05:00 UTC
I need to make a kernel mod that connects to a Vantech 2S1P PCIe
serial/par. combo card that has a 74LS02 hooked up to in roughly the
same way that I2C is interfaced to in lpbb(4) is for bit banging on
the LS02. I got /dev/lpt0, etc. on the bhyve host I am used and have
passed it through and the guest sees the 2S1P but thats where I stand
and to farther it appears I neeed a kmod since the guest is seeing the
device but not attaching a driver:
pci0: <simple comms, UART> at device 3.0 (no driver attached)
pci0: <simple comms, UART> at device 5.0 (no driver attached)
pci0: <simple comms, parallel port> at device 6.0 (no driver attached)
none0@pci0:0:3:0: class=0x070002 rev=0x00 hdr=0x00 vendor=0x9710
device=0x9912 subvendor=0xa000 subdevice=0x1000
vendor = 'MosChip Semiconductor Technology Ltd.'
device = 'PCIe 9912 Multi-I/O Controller'
class = simple comms
subclass = UART
none1@pci0:0:5:0: class=0x070002 rev=0x00 hdr=0x00 vendor=0x9710
device=0x9912 subvendor=0xa000 subdevice=0x1000
vendor = 'MosChip Semiconductor Technology Ltd.'
device = 'PCIe 9912 Multi-I/O Controller'
class = simple comms
subclass = UART
none2@pci0:0:6:0: class=0x070103 rev=0x00 hdr=0x00 vendor=0x9710
device=0x9912 subvendor=0xa000 subdevice=0x2000
vendor = 'MosChip Semiconductor Technology Ltd.'
device = 'PCIe 9912 Multi-I/O Controller'
class = simple comms
subclass = parallel port
I also have this simple kmod demo working:
aryeh@sarek2048% more ~root/foo.c
// io_test.c
// Usage: ./io_test <base-port-hex> [value-hex]
// Example: ./io_test 0xe010 0xff
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
static inline void outb(uint16_t port, uint8_t val) {
asm volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
}
static inline uint8_t inb(uint16_t port) {
uint8_t val;
asm volatile ("inb %1, %0" : "=a"(val) : "Nd"(port));
return val;
}
int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "Usage: %s <base-port-hex> [value-hex]\n", argv[0]);
return 1;
}
uint16_t base = (uint16_t)strtoul(argv[1], NULL, 0);
uint8_t val = (argc >= 3) ? (uint8_t)strtoul(argv[2], NULL, 0) : 0x01;
int fd = open("/dev/io", O_RDWR);
if (fd < 0) {
perror("open(/dev/io)");
return 1;
}
printf("Writing 0x%02x to data (port 0x%04x)\n", val, base);
outb(base, val);
usleep(1000); // tiny delay
uint8_t status = inb(base + 1);
uint8_t control = inb(base + 2);
uint8_t data_read = inb(base); // some cards reflect reads
printf("Read: data=0x%02x status=0x%02x control=0x%02x\n",
data_read, status, control);
close(fd);
return 0;
}
--
Aryeh M. Friedman, Lead Developer, http://www.PetiteCloud.org