owned this note
owned this note
Published
Linked with GitHub
Character Drivers 101
=====
###### tags: `Linux Kernel`
# Kernel Module information export on Userspace
- `modinfo fibdrv.ko` information
in code:
```clike
MODULE_LICENSE("Dual MIT/GPL");
MODULE_AUTHOR("National Cheng Kung University, Taiwan");
MODULE_DESCRIPTION("Fibonacci engine driver");
```
- Major number for each kernel module
`cat /proc/devices` Get the Major number 239 fibonacci
in code: `alloc_chrdev_region(&fib_dev, 0, 1, "fibonacci")`
- get Major number `MAJOR(fib_dev)`
- [Multiple minor number](https://www.cnblogs.com/lifexy/p/7827559.html)
- See the exists module on system
`cat /proc/modules` like `lsmod`
name is same as in makefile: `obj-m := fibdrv.o`
:::info
:smile: [Creating proc file and Interfacing with user space](https://devarea.com/linux-kernel-development-creating-a-proc-file-and-interfacing-with-user-space/#.XmJhM3UzY5l)
:::
- Device Class
`ls /sys/class/fibonacci_class/`
`cat /sys/class/fibonacci_class/fibonacci_dev/dev` 239:0
In code: `class_create(THIS_MODULE, "fibonacci_class")`
- Device File
`ls /dev/fibonacci_dev`
In code: `device_create(fib_class, NULL, fib_dev, NULL, "fibonacci_dev"))`
- Driver information
- Version`cat /sys/module/fibdrv/version`
```clike
MODULE_VERSION("0.1");
obj-m := fibdrv.o
```
- Reference count
`cat /sys/module/fibdrv/refcnt`
[A simple char driver code](https://github.com/ldotrg/practical_coding/blob/master/kernel_module/char_devices/simple_char.c)
:::info
- Kernel Symbol table
```shell
sudo cat /proc/kallsyms
```
:::
### insmod, rmmod, modprobe

### `module_init(sample_char_init)`: create and register a character device with file operations
- The name will populate at `cat /proc/devices`
- it will get the Major number
```clike
alloc_chrdev_region(dev_t *dev, unsigned baseminor,
unsigned count, const char *name)
```
- Populate sysfs entries `ls /sys/class`
`class_create()`
- It will create the device file:`ls /dev/`
`device_create()`
### User program can use device name as a file and invoke file operations on the device.

- 當 User space open file的時候, 最終會呼叫到KERNEL `chrdev_open()`
- `chrdev_open` 會利用inode 的資訊(Major number?)找到對應的`cdev`,並填入`inode->i_cdev`
```clike
static int chrdev_open(struct inode *inode, struct file *filp)
{
...
p = inode->i_cdev;
if (!p) {
struct kobject *kobj;
int idx;
spin_unlock(&cdev_lock);
kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
if (!kobj)
return -ENXIO;
new = container_of(kobj, struct cdev, kobj);
...
}
```
### Each object in the filesystem is represented by an inode.
[檔案系統概念及實作手法](https://hackmd.io/s/BypqEyF6N#Linux-%E6%A0%B8%E5%BF%83%E8%A8%AD%E8%A8%88-%E6%AA%94%E6%A1%88%E7%B3%BB%E7%B5%B1%E6%A6%82%E5%BF%B5%E5%8F%8A%E5%AF%A6%E4%BD%9C%E6%89%8B%E6%B3%95)
:::success
inode (DEVICE_NAME /dev/simple_char_dev) => cdev => simple_char_dev (a super-class of cdev containging device related data) => file
:::

### Assigment: [Device Drivers for Shared Message Queues](http://rts.lab.asu.edu/web_438_Fall_2014/CSE_438_598_Fall_2014_assignment_1.pdf)
```clike
struct share_q {
cdev
queue: arrary of pointer
front: position
end:position
semaphore: for enqueue and dequeue make sure only one coule access
q name
}
```
#### Reference
- [ch8-裝置驅動程式的基本知識](https://hackmd.io/NY0zJGwRR8KbCfkYdmTUsg#ch8-%E8%A3%9D%E7%BD%AE%E9%A9%85%E5%8B%95%E7%A8%8B%E5%BC%8F%E7%9A%84%E5%9F%BA%E6%9C%AC%E7%9F%A5%E8%AD%98)
- [linux-kernel-module-cheat: charater device](https://github.com/cirosantilli/linux-kernel-module-cheat/blob/68af3477cce1cd22566edce2651f54cf8c184a91/kernel_module/character_device_create.c)