ใครช่วยอธิบายฉันที
- คืออะไร
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)
ข้อมูลที่ไหลจะมาจากพื้นที่ไปยังพื้นที่เคอร์เนลของผู้ใช้และวิธีการทั้งสองตามลำดับ
โปรดแจ้งให้เราทราบหากสิ่งนี้ช่วยได้!