2.3 Questions
Alright, close the books — the theory is over. Now it's time to get our hands dirty.
We've covered a lot of ground in this chapter: from procfs to sysfs, then debugfs, netlink sockets, and finally ioctl. If you don't write the code yourself, these mechanisms will remain dry concepts on a page. To truly cement this knowledge, you need to apply it to real problems.
The exercises below aren't fill-in-the-blank questions — they're genuine engineering tasks. If you can complete them independently, even if it takes some time to look things up, you've officially crossed the threshold into this field.
Don't worry — reference code for some exercises is available in this book's GitHub repository, but I strongly recommend trying to write them yourself first. As Donald Knuth said, "The best test is when you have to explain it." Here, the best test is when you have to implement it.
Exercise 2.1 — sysfs_on_misc ⭐⭐
Task: Go back to the simple misc device driver we wrote in Chapter 1. Dig it up — we're going to extend it.
Requirements:
- Extend this driver by creating two attribute files under sysfs.
- You need to implement the corresponding
showandstorecallback functions. - Read from and write to these files from userspace (via shell or a C program) to verify the interface works correctly.
Tip: Remember the
DEVICE_ATTRmacro? It will save you a lot of work. Don't forget to attach it during initialization withdevice_create_fileand detach it during cleanup withdevice_remove_file.
Exercise 2.2 — sysfs_addrxlate ⭐⭐⭐
This is an advanced exercise that touches on deep memory management mechanisms.
Task: Write a simple platform driver that leverages Linux kernel memory management knowledge to implement an "address translation" feature.
Requirements:
- Create two sysfs files:
addrxlate_kva2paandaddrxlate_pa2kva. - addrxlate_kva2pa:
- The user writes a kernel virtual address to the file.
- The driver converts it to the corresponding physical address.
- When the user reads the file, it displays the translated physical address.
- addrxlate_pa2kva:
- The reverse operation: write a physical address, and read back the kernel virtual address.
Tip: You'll need to consult the kernel documentation to understand how to work with macros like
virt_to_physand related page table operations. This exercise will help you understand the mapping relationship between kernel space and physical memory.
Exercise 2.3 — dbgfs_disp_pgoff ⭐⭐
Task: Write a kernel module that exposes kernel configuration parameters through debugfs.
Requirements:
- Create a file named
dbgfs_disp_pgoffunder the debugfs mount point. - When the user reads this file, the driver returns the value of the current kernel's
PAGE_OFFSETmacro.
Tip:
PAGE_OFFSETis a key marker for the kernel space starting address. This exercise will familiarize you with debugfs APIs (such asdebugfs_create_file) and how to handle simple read requests.
Exercise 2.4 — dbgfs_showall_threads ⭐⭐⭐
Task: Write a kernel module that uses debugfs to provide a real-time view of system processes.
Requirements:
- Create a file
dbgfs_showall_threadsunder debugfs (note: you may need to create a subdirectory). - When the user reads this file, the driver iterates through all tasks in the system (
task_struct) and outputs key information for each thread in CSV format.
Suggested output fields: TGID,PID,current,stack-start,name,#threads
- Pay attention to the
[name]format for kernel threads. #threadsshould only display a positive integer for multi-threaded processes; do not output it for single-threaded processes.
Tip: This requires using the
for_each_processmacro or a similar iteration mechanism. Also, be mindful of concurrency issues — don't let the scheduler block you while reading. This exercise will give you a feel for debugfs's flexibility compared to procfs — there are far fewer formatting constraints.
Exercise 2.5 — ioctl assignment #1 ⭐⭐
Task: Based on the provided ch2/ioctl_intf/ template code, implement the classic userspace-to-kernel interaction via ioctl.
Requirements:
- Write a userspace C program and a kernel character device driver.
- Implement the
unlocked_ioctlmethod in the driver. - Add a new ioctl command:
IOCTL_LLKD_IOCQPGOFF. - When the userspace program queries via this command, the kernel returns the value of
PAGE_OFFSETto userspace.
Tip: Don't forget the definition of the
_IORmacro — it's essential for defining ioctl command numbers.
Exercise 2.6 — ioctl_undoc ⭐⭐⭐
Task: Let's do something "dangerous" — implement an undocumented ioctl command to retrieve the driver's internal state.
Requirements:
- Again, based on the
ch2/ioctl_intf/template. - Define a "driver context data structure" in the driver (the
structwe used in earlier examples), containing a few fields such as statistics and status flags. Allocate and initialize it during module initialization. - Add a fourth ioctl command:
IOCTL_LLKD_IOCQDRVSTAT. - Key point: This command is "undocumented," meaning it bypasses the常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规常规