ใครช่วยอธิบายฉันที
- คืออะไร
IOCTL? - ใช้ทำอะไร?
 - ฉันจะใช้มันได้อย่างไร?
 - ทำไมฉันจึงไม่สามารถกำหนดฟังก์ชั่นใหม่ที่ทำงานเช่นเดียวกับ
IOCTL? 
ใครช่วยอธิบายฉันที
IOCTL?IOCTL?คำตอบ:
An ioctlซึ่งหมายถึง "การควบคุมอินพุต - เอาต์พุต" เป็นการเรียกระบบเฉพาะอุปกรณ์ มีการเรียกระบบเพียงไม่กี่สายใน Linux (300-400) ซึ่งไม่เพียงพอที่จะแสดงฟังก์ชันเฉพาะทั้งหมดที่อุปกรณ์อาจมี ดังนั้นผู้ขับขี่สามารถกำหนด ioctl ซึ่งอนุญาตให้แอปพลิเคชัน userspace ส่งคำสั่งได้ อย่างไรก็ตาม ioctls ไม่ค่อยมีความยืดหยุ่นและมีแนวโน้มที่จะเกะกะเล็กน้อย ("เลขวิเศษ" หลายสิบตัวซึ่งใช้ได้ผล ... หรือไม่) และอาจไม่ปลอดภัยเนื่องจากคุณส่งบัฟเฟอร์เข้าไปในเคอร์เนล - การจัดการที่ไม่ดีอาจแตกได้ สิ่งต่างๆได้อย่างง่ายดาย
อีกทางเลือกหนึ่งคือsysfsอินเทอร์เฟซที่คุณตั้งค่าไฟล์ภายใต้/sys/และอ่าน / เขียนเพื่อรับข้อมูลจากและไปยังไดรเวอร์ ตัวอย่างวิธีการตั้งค่า:
static ssize_t mydrvr_version_show(struct device *dev,
        struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", DRIVER_RELEASE);
}
static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);
และระหว่างการตั้งค่าไดรเวอร์:
device_create_file(dev, &dev_attr_version);
จากนั้นคุณจะมีไฟล์สำหรับอุปกรณ์ของคุณ/sys/ตัวอย่างเช่น/sys/block/myblk/versionสำหรับไดรเวอร์บล็อก
อีกวิธีหนึ่งสำหรับการใช้งานที่หนักกว่าคือ netlink ซึ่งเป็นวิธี IPC (การสื่อสารระหว่างกระบวนการ) เพื่อพูดคุยกับคนขับของคุณผ่านอินเทอร์เฟซซ็อกเก็ต BSD สิ่งนี้ถูกใช้โดยไดรเวอร์ WiFi จากนั้นคุณจะสื่อสารกับมันจาก userspace โดยใช้libnlหรือlibnl3ไลบรารี
ioctlฟังก์ชั่นจะเป็นประโยชน์สำหรับการใช้ไดรเวอร์อุปกรณ์ที่จะตั้งกำหนดค่าบนอุปกรณ์ เช่นเครื่องพิมพ์ที่มีตัวเลือกการกำหนดค่าเพื่อตรวจสอบและตั้งค่าตระกูลฟอนต์ขนาดฟอนต์ ฯลฯioctlสามารถใช้เพื่อรับฟอนต์ปัจจุบันรวมทั้งตั้งฟอนต์เป็นฟอนต์ใหม่ แอปพลิเคชันผู้ใช้ใช้ioctlเพื่อส่งรหัสไปยังเครื่องพิมพ์เพื่อบอกให้ส่งคืนแบบอักษรปัจจุบันหรือตั้งค่าแบบอักษรเป็นแบบใหม่
int ioctl(int fd, int request, ...)
fdคือ file descriptor ซึ่งส่งคืนโดยopen;requestคือรหัสคำขอ เช่นGETFONTจะได้รับแบบอักษรปัจจุบันจากเครื่องพิมพ์SETFONTจะตั้งค่าแบบอักษรบนเครื่องพิมพ์void *อาร์กิวเมนต์ที่สามคือ ขึ้นอยู่กับอาร์กิวเมนต์ที่สองอาร์กิวเมนต์ที่สามอาจมีหรือไม่มีก็ได้เช่นหากอาร์กิวเมนต์ที่สองเป็นอาร์กิวเมนต์SETFONTที่สามอาจเป็นชื่อฟอนต์เช่น"Arial";int requestไม่ใช่แค่มาโคร จำเป็นต้องมีแอปพลิเคชันผู้ใช้เพื่อสร้างรหัสคำขอและโมดูลไดรเวอร์อุปกรณ์เพื่อกำหนดว่าจะต้องเล่นกับการกำหนดค่าใดบนอุปกรณ์ แอปพลิเคชันจะส่งรหัสคำขอโดยใช้ioctlแล้วใช้รหัสคำขอในโมดูลไดรเวอร์อุปกรณ์เพื่อพิจารณาว่าจะดำเนินการใด
รหัสคำขอมี 4 ส่วนหลัก
    1. A Magic number - 8 bits
    2. A sequence number - 8 bits
    3. Argument type (typically 14 bits), if any.
    4. Direction of data transfer (2 bits).  
หากรหัสคำขอคือSETFONTการตั้งค่าแบบอักษรบนเครื่องพิมพ์ทิศทางในการถ่ายโอนข้อมูลจะเป็นจากแอปพลิเคชันผู้ใช้ไปยังโมดูลไดรเวอร์อุปกรณ์ (แอปพลิเคชันผู้ใช้จะส่งชื่อแบบอักษร"Arial"ไปยังเครื่องพิมพ์) หากรหัสคำขอคือGETFONTทิศทางจากเครื่องพิมพ์ไปยังแอปพลิเคชันผู้ใช้
ในการสร้างรหัสคำขอ Linux จะมีมาโครที่เหมือนฟังก์ชันที่กำหนดไว้ล่วงหน้า
1. _IO(MAGIC, SEQ_NO)ทั้งสองคือ 8 บิต 0 ถึง 255 เช่นให้เราบอกว่าเราต้องการหยุดเครื่องพิมพ์ชั่วคราว ไม่จำเป็นต้องมีการถ่ายโอนข้อมูล ดังนั้นเราจะสร้างรหัสคำขอดังต่อไปนี้
#define PRIN_MAGIC 'P'
#define NUM 0
#define PAUSE_PRIN __IO(PRIN_MAGIC, NUM) 
และตอนนี้ใช้ioctlเป็น
ret_val = ioctl(fd, PAUSE_PRIN);
การเรียกระบบที่เกี่ยวข้องในโมดูลไดรเวอร์จะรับรหัสและหยุดเครื่องพิมพ์ชั่วคราว
__IOW(MAGIC, SEQ_NO, TYPE) MAGICและSEQ_NOเป็นเช่นเดียวกับข้างต้นและTYPEทำให้ประเภทของการโต้แย้งต่อไปจำอาร์กิวเมนต์ที่สามของการมีioctl void *W in __IOWแสดงว่ากระแสข้อมูลมาจากแอปพลิเคชันผู้ใช้ไปยังโมดูลไดรเวอร์ "Arial"ตัวอย่างเช่นสมมติว่าเราต้องการที่จะตั้งตัวอักษรเครื่องพิมพ์เพื่อ#define PRIN_MAGIC 'S'
#define SEQ_NO 1
#define SETFONT __IOW(PRIN_MAGIC, SEQ_NO, unsigned long)
เพิ่มเติม
char *font = "Arial";
ret_val = ioctl(fd, SETFONT, font); 
ตอนนี้fontเป็นตัวชี้ซึ่งหมายความว่าเป็นที่อยู่ที่แสดงได้ดีที่สุดunsigned longดังนั้นส่วนที่สามของการ_IOWกล่าวถึงประเภทนี้ นอกจากนี้ที่อยู่ของแบบอักษรนี้จะถูกส่งไปยังการเรียกระบบที่เกี่ยวข้องซึ่งใช้งานในโมดูลไดรเวอร์อุปกรณ์unsigned long  และเราจำเป็นต้องแคสต์เป็นประเภทที่เหมาะสมก่อนที่จะใช้ พื้นที่เคอร์เนลสามารถเข้าถึงพื้นที่ผู้ใช้และด้วยเหตุนี้จึงใช้งานได้ อีกสองฟังก์ชั่นเหมือนมาโครอยู่__IOR(MAGIC, SEQ_NO, TYPE)และ__IORW(MAGIC, SEQ_NO, TYPE)ข้อมูลที่ไหลจะมาจากพื้นที่ไปยังพื้นที่เคอร์เนลของผู้ใช้และวิธีการทั้งสองตามลำดับ
โปรดแจ้งให้เราทราบหากสิ่งนี้ช่วยได้!