PCI driver
This commit is contained in:
parent
bd519208fd
commit
e703628187
8
.idea/Linux.iml
Normal file
8
.idea/Linux.iml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module version="4">
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="Python" name="Python facet">
|
||||||
|
<configuration sdkName="Python 3.10 (Linux)" />
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
</module>
|
10
.idea/conventionalCommit.xml
Normal file
10
.idea/conventionalCommit.xml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="general">
|
||||||
|
<commitTypes>
|
||||||
|
<entry providerId="37415b03-9388-4c55-b949-8c4526f6934d" order="2" />
|
||||||
|
<entry providerId="e9ce9acf-f4a6-4b36-b43c-531169556c29" order="2" />
|
||||||
|
<entry providerId="e9d4e8de-79a0-48b8-b1ba-b4161e2572c0" order="1" />
|
||||||
|
</commitTypes>
|
||||||
|
</component>
|
||||||
|
</project>
|
16
.idea/inspectionProfiles/Project_Default.xml
Normal file
16
.idea/inspectionProfiles/Project_Default.xml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredPackages">
|
||||||
|
<value>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="psycopg2" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="TsLint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
31
counter_reader/counter_reader_bash.service
Normal file
31
counter_reader/counter_reader_bash.service
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
[Unit]
|
||||||
|
# A short human readable title of the unit
|
||||||
|
Description=Counter reader in bash?
|
||||||
|
# A list of units whose activations will wait until after this unit has completed.
|
||||||
|
Before=
|
||||||
|
# A list of units whose activations will occur before this unit starts.
|
||||||
|
After=network.target
|
||||||
|
# A list of units to activate when this one is activated, if any unit listed here fails this unit will deactivate.
|
||||||
|
Requires=
|
||||||
|
# A list of units to activate when this one is activated, if a unit listed here fails this unit will continue to run.
|
||||||
|
Wants=
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
# Configures the process start-up type for this service unit, one of:
|
||||||
|
# simple - The process defined in ExecStart= will stay in the foreground while the unit is activated.
|
||||||
|
# forking - The process defined in ExecStart= will fork a background process and exit right away.
|
||||||
|
# oneshot - The process will exit right away, use with RemainAfterExit= to ensure the serice is marked as active.
|
||||||
|
# Consult the documentantion for types (https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type=) other options.
|
||||||
|
Type=simple
|
||||||
|
# Command with arguments to invoke when the unit is activated.
|
||||||
|
ExecStart=
|
||||||
|
# Command with arguments to invoke when the unit is deactivated.
|
||||||
|
ExecStop=
|
||||||
|
# Configures under what conditions the unit will be restarted.
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
# A list of units who when activated will try and activate this unit
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
# A list of units to enable or disable when this unit is enabled or disabled (e.g., with systemctl enable)
|
||||||
|
Also=
|
7
pci/Makefile
Normal file
7
pci/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
obj-m += ethernet.o
|
||||||
|
# make -C $(nix-build -E '(import <nixpkgs> {}).linux.dev' --no-out-link)/lib/modules/*/build M=$(pwd)
|
||||||
|
|
||||||
|
all:
|
||||||
|
make -C /nix/store/f0b11y3qv1y0l3yvwkl88m181fnbmn80-linux-5.15.92-dev/lib/modules/*/build M=/home/inex/dev/Linux/pci modules
|
||||||
|
clean:
|
||||||
|
make -C /nix/store/f0b11y3qv1y0l3yvwkl88m181fnbmn80-linux-5.15.92-dev/lib/modules/*/build M=/home/inex/dev/Linux/pci clean
|
164
pci/ethernet.c
Normal file
164
pci/ethernet.c
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
// A symbol PCI driver that outputs the MAC address of the network card:
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Inex Code");
|
||||||
|
MODULE_DESCRIPTION("A PCI driver");
|
||||||
|
MODULE_VERSION("0.0.1");
|
||||||
|
|
||||||
|
#define VENDOR_ID 0x10ec
|
||||||
|
#define DEVICE_ID 0x8168
|
||||||
|
|
||||||
|
#define DRIVER_NAME "network_card_pci_driver_mac"
|
||||||
|
|
||||||
|
#define CTL_GET_MAC _IOR('mac', 1, char *)
|
||||||
|
|
||||||
|
static struct pci_device_id network_card_pci_driver_mac_id_table[] = {
|
||||||
|
{ PCI_DEVICE(VENDOR_ID, DEVICE_ID) },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(pci, network_card_pci_driver_mac_id_table);
|
||||||
|
|
||||||
|
static int network_card_pci_driver_mac_probe(struct pci_dev *dev, const struct pci_device_id *id);
|
||||||
|
static void network_card_pci_driver_mac_remove(struct pci_dev *dev);
|
||||||
|
|
||||||
|
static struct pci_driver network_card_pci_driver_mac = {
|
||||||
|
.name = DRIVER_NAME,
|
||||||
|
.id_table = network_card_pci_driver_mac_id_table,
|
||||||
|
.probe = network_card_pci_driver_mac_probe,
|
||||||
|
.remove = network_card_pci_driver_mac_remove
|
||||||
|
};
|
||||||
|
|
||||||
|
static int network_card_open(struct inode *inode, struct file *file);
|
||||||
|
static int network_card_release(struct inode *inode, struct file *file);
|
||||||
|
static ssize_t network_card_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||||
|
|
||||||
|
static struct file_operations network_card_fops = {
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.open = network_card_open,
|
||||||
|
.release = network_card_release,
|
||||||
|
.unlocked_ioctl = network_card_ioctl
|
||||||
|
};
|
||||||
|
|
||||||
|
static int Major;
|
||||||
|
static struct class *network_card_class;
|
||||||
|
|
||||||
|
unsigned char mac_addr[6];
|
||||||
|
|
||||||
|
static atomic_t already_open = ATOMIC_INIT(0);
|
||||||
|
|
||||||
|
static int __init network_card_pci_driver_mac_init(void) {
|
||||||
|
int register_result = pci_register_driver(&network_card_pci_driver_mac);
|
||||||
|
if (register_result < 0) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"pci_register_driver failed\n");
|
||||||
|
return register_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Major = register_chrdev(0, DRIVER_NAME, &network_card_fops);
|
||||||
|
if (Major < 0) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"register_chrdev failed\n");
|
||||||
|
return Major;
|
||||||
|
}
|
||||||
|
|
||||||
|
network_card_class = class_create(THIS_MODULE, DRIVER_NAME);
|
||||||
|
if (!network_card_class) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"class_create failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_create(network_card_class, NULL, MKDEV(Major, 0), NULL, DRIVER_NAME);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit network_card_pci_driver_mac_exit(void) {
|
||||||
|
class_destroy(network_card_class);
|
||||||
|
unregister_chrdev(Major, DRIVER_NAME);
|
||||||
|
pci_unregister_driver(&network_card_pci_driver_mac);
|
||||||
|
|
||||||
|
printk(KERN_INFO
|
||||||
|
"Goodbye cruel world.\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int network_card_pci_driver_mac_probe(struct pci_dev *dev, const struct pci_device_id *id) {
|
||||||
|
u8 __iomem *mmio_base;
|
||||||
|
|
||||||
|
int bar = 2;
|
||||||
|
|
||||||
|
if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) {
|
||||||
|
mmio_base = pci_iomap(dev, bar, pci_resource_len(dev, bar));
|
||||||
|
if (!mmio_base) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"pci_iomap failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"Not a memory-mapped resource\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
mac_addr[i] = ioread8(mmio_base + i);
|
||||||
|
printk(KERN_INFO
|
||||||
|
"MAC address byte %d: %02x\n", i, mmio_base[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
iounmap(mmio_base);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void network_card_pci_driver_mac_remove(struct pci_dev *dev) {
|
||||||
|
dev_t devno = MKDEV(Major, 0);
|
||||||
|
device_destroy(network_card_class, devno)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int network_card_open(struct inode *inode, struct file *file) {
|
||||||
|
if (atomic_cmpxchg(&already_open, 0, 1)) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"already_open is true\n");
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
try_module_get(THIS_MODULE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int network_card_release(struct inode *inode, struct file *file) {
|
||||||
|
atomic_set(&already_open, 0);
|
||||||
|
module_put(THIS_MODULE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t network_card_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
|
||||||
|
switch (cmd) {
|
||||||
|
case CTL_GET_MAC:
|
||||||
|
if (copy_to_user((unsigned long __user *) arg, mac_addr, 6) != 0) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"copy_to_user failed\n");
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(KERN_ERR
|
||||||
|
"unknown ioctl\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(network_card_pci_driver_mac_init);
|
||||||
|
module_exit(network_card_pci_driver_mac_exit);
|
16
pci/read.py
Normal file
16
pci/read.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import fcntl
|
||||||
|
|
||||||
|
MAC_ADDRESS_SIZE = 6
|
||||||
|
DEVICE_PATH = "/dev/network_card_pci_driver_mac"
|
||||||
|
MY_IOCTL_GET_MAC_ADDRESS = 0xed696301
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
device_file = open(DEVICE_PATH, "rb")
|
||||||
|
|
||||||
|
mac_address_buffer = bytearray(MAC_ADDRESS_SIZE)
|
||||||
|
|
||||||
|
fcntl.ioctl(device_file, MY_IOCTL_GET_MAC_ADDRESS, mac_address_buffer)
|
||||||
|
|
||||||
|
print(mac_address_buffer.hex())
|
||||||
|
|
||||||
|
device_file.close()
|
Loading…
Reference in a new issue