Download presentation
Presentation is loading. Please wait.
1
מערכות הפעלה תרגול 10 – מבוא למנהלי התקנים ב-Linux Linux Device Drivers, 2 nd Edition Alessandro Rubini & Jonathan Corbet O’Reilly http://www.xml.com/ldd/chapter/book/
2
תרגול 10 – מבוא למנהלי התקנים ב-Linux2 (c) אריק פרידמן 2006 תוכן התרגול מבוא למנהלי התקנים ומודולים ב-Linux כתיבה והרצה של מודולים התקני תווים
3
תרגול 10 – מבוא למנהלי התקנים ב-Linux3 (c) אריק פרידמן 2006 מה זה מנהל התקן? שכבת תוכנה החוצצת בין החומרה לבין האפליקציה מנהל ההתקן מחביא את הפרטים הנוגעים לפעולת החומרה המשתמש מבצע פעולות באמצעות אוסף פונקציות סטנדרטי שאינו תלוי בהתקן מסוים תפקיד מנהל ההתקן למפות את הפונקציות הסטנדרטיות לפעולות המבוצעות על התקן החומרה גישה מודולרית - ניתן לבנות מנהל התקן בנפרד משאר הגרעין, ואז "לחבר" אותו בזמן ריצה, בשעת הצורך
4
תרגול 10 – מבוא למנהלי התקנים ב-Linux4 (c) אריק פרידמן 2006 מודולים ב-Linux ל-Linux יש יכולת להרחיב בזמן ריצה את אוסף הפעולות שמספק הגרעין קטע קוד שניתן להוסיף לגרעין בזמן ריצה נקרא מודול ספריה משותפת הנטענת (מקושרת בזמן ריצה) לגרעין רק משתמשים מורשים יכולים לטעון מודולים ישנה חלוקה של מודולים לפי התפקודיות שהם מספקים: התקני תווים התקני בלוקים ממשקי רשת ועוד (USB, SCSI,...)
5
תרגול 10 – מבוא למנהלי התקנים ב-Linux5 (c) אריק פרידמן 2006 התקני תווים ובלוקים התקן תווים - התקן שניגשים אליו כאל רצף של בתים (כמו קובץ) מסוף, פורט סדרתי בדרך כלל ניתן לגשת להתקן תווים רק באופן סדרתי התקני בלוקים - התקן שניתן לתקשר איתו רק בכפולות של בלוק (למשל KByte) בפועל Linux מאפשרת לקרוא מהתקני בלוקים גם בתים בודדים משמשים, בין השאר, לייצג מערכות קבצים ניתן לגשת להתקנים אלו דרך מערכת הקבצים (/dev)
6
תרגול 10 – מבוא למנהלי התקנים ב-Linux6 (c) אריק פרידמן 2006 ממשקי רשת התקנים המסוגלים להחליף מידע עם מחשבים אחרים באחריותם לשלוח ולקבל חבילות מידע אינם מיוצגים במערכת הקבצים ישנן קריאות מערכת ייחודיות לטיפול בממשקי רשת
7
תרגול 10 – מבוא למנהלי התקנים ב-Linux7 (c) אריק פרידמן 2006 ענייני אבטחה מודול רץ ב-kernel mode גישה למבני הנתונים בגרעין חשוב להימנע מחורי אבטחה במודול למשל buffer overrun בתכנות ב-c הקפדה על אתחול משתנים יש להתייחס לקלט משתמש בחשדנות במידת הצורך, הגבלת השימוש במודול למשתמשים מורשים
8
תרגול 10 – מבוא למנהלי התקנים ב-Linux8 (c) אריק פרידמן 2006 מודול ראשון #include #include /* for using printk */ MODULE_LICENSE(“GPL”); int init_module(void) { printk(“Hello, World\n”); return 0; } void cleanup_module(void) { printk(“Goodbye cruel world\n”); }
9
תרגול 10 – מבוא למנהלי התקנים ב-Linux9 (c) אריק פרידמן 2006 הפעלת המודול קובץ makefile לדוגמה: KERNELDIR = /usr/src/linux-2.4.18-14custom include $(KERNELDIR)/.config CFLAGS = -D__KERNEL__ -DMODULE –I$(KERNELDIR)/include –O -Wall all: hello.o הרצה: > make > insmod./hello.o Hello, world > rmmod hello GoodBye cruel world >
10
תרגול 10 – מבוא למנהלי התקנים ב-Linux10 (c) אריק פרידמן 2006 העברת פרמטרים למודול בעת טעינת המודול, ניתן להעביר אליו פרמטרים הנוגעים לקונפיגורציה של המודול סוגי פרמטרים נתמכים: b – byte, h – short, i – integer, l – long, s – string ניתן להעביר גם מערך של פרמטרים בקוד המודול מגדירים את המשתנים שיקבלו את הפרמטרים באמצעות המאקרו MODULE_PARM המאקרו צריך להופיע מחוץ לפונקציה. בד"כ ממוקם בתחילת המודול פרמטר ראשון – משתנה הפרמטר, פרמטר שני – סוג הפרמטר יש להגדיר לכל פרמטר ערך ברירת מחדל ניתן להשתמש במאקרו MODULE_PARM_DESC כדי להוסיף תיאור לפרמטר כלי ניהול אוטומטיים יכולים לקרוא את התיאור (אפשר גם עם modinfo)
11
תרגול 10 – מבוא למנהלי התקנים ב-Linux11 (c) אריק פרידמן 2006 העברת פרמטרים למודול (2) הגדרת הפרמטרים במודול (params.c, למשל): int iValue=0; char *strValue; int iArray[4]; MODULE_PARM(iValue,”i”); MODULE_PARM(strValue,”s”); MODULE_PARM(iArray,”4i”); העברת פרמטרים בטעינת המודול: > insmod./params.o iValue=3 sValue=“hello” iArray=1,2,3,4
12
תרגול 10 – מבוא למנהלי התקנים ב-Linux12 (c) אריק פרידמן 2006 גישה לנתוני גרעין למודול יש גישה למבני הנתונים של הגרעין ישנם חלקים בגרעין הזמינים רק אחרי הוספת #define __KERNEL__ מופיע ב-makefile צריך להוסיף #include לקבצים המתאימים … #include int init_module(void) { printk(“The process is \”%s\” (pid %i)\n”, current->comm, current->pid); return 0; } …
13
תרגול 10 – מבוא למנהלי התקנים ב-Linux13 (c) אריק פרידמן 2006 התקני תווים - איך זה עובד? המודולגרעין Linux insmod rmmod init_module() cleanup_module() register_chrdev() unregister_chrdev() chrdevs[] fops אוסף פונקציות אחרות בגרעין קריאה לפונקציה פעולת השמה מצביע לפונקציה מצביע לנתונים
14
תרגול 10 – מבוא למנהלי התקנים ב-Linux14 (c) אריק פרידמן 2006 התקני תווים להתקני תווים ניגשים דרך שמות המופיעים במערכת הקבצים בדרך כלל ממוקמים במדריך /dev כאשר מבצעים ls –l, התקני תווים מאופיינים בתו c בעמודה הראשונה התקן תווים מאופיין ע"י שני מספרים: מספר ראשי (major number) - מזהה את מנהל ההתקן המקושר להתקן מספר משני (minor number) – מספר שמשמש את מנהל ההתקן כדי להבחין בין התקנים שונים המחוברים אליו crw-rw-rw- 1 root root 1, 3 Aug 31 2002 null crw------- 1 root root 10, 1 May 12 2003 psaux crw------- 1 root tty 4, 1 May 12 10:33 tty1 crw-rw-rw- 1 root root 1, 5 Aug 31 2002 zero
15
תרגול 10 – מבוא למנהלי התקנים ב-Linux15 (c) אריק פרידמן 2006 הוספת מנהל התקן חדש כדי ליצור מנהל התקן חדש, יש להקצות לו מספר ראשי חדש מבוצע ע"י הפונקציה register_chrdev(), המוגדרת ב- ההקצאה מבוצעת במסגרת אתחול מנהל ההתקן (init_module()) תחביר: int register_chrdev(unsigned int major, const char *name, struct file_operations *fops); פרמטרים: major – המספר הראשי אותו רוצים להקצות למנהל ההתקן name – שם ההתקן, כפי שיופיע ב-/proc/devices fops – מערך של מצביעי פונקציות, המממשים את פעולת ההתקן. נרחיב עליו בהמשך ערך מוחזר: במקרה של הצלחה יוחזר ערך 0 או חיובי, אחרת -1.
16
תרגול 10 – מבוא למנהלי התקנים ב-Linux16 (c) אריק פרידמן 2006 בחירת מספר ראשי גרסה 2.4 של Linux תומכת ב-256 מספרים ראשיים המספרים 0 ו-255 שמורים לשימוש עתידי חלק מהמספרים הראשיים מוקצים באופן סטטי להתקנים נפוצים הקצאה סטטית של מספרים ראשיים עבור כל התקן יכולה להיות בעייתית התנגשות בין מספרים ראשיים של התקנים שונים ניתן לבצע הקצאה דינמית של מספר ראשי ע"י העברת ערך 0 עבור הפרמטר major מערכת ההפעלה בוחרת מספר פנוי ומחזירה אותו כתוצאה של register_chrdev() במקרה של הקצאה סטטית ערך החזרה יהיה 0 ניתן לראות את המספר שהוקצה גם ב-/proc/devices
17
תרגול 10 – מבוא למנהלי התקנים ב-Linux17 (c) אריק פרידמן 2006 הסרת מנהל התקן מהמערכת כאשר מסירים מנהל התקן, יש לשחרר את המספר הראשי שהוקצה לו, באמצעות הפונקציה unregister_chrdev(), המוגדרת ב- תחביר: int unregister_chrdev(unsigned int major, const char *name); פרמטרים: major – המספר הראשי של מנהל ההתקן אותו רוצים להסיר name – שם ההתקן, כפי שמופיע ב-/proc/devices ערך מוחזר: במקרה של הצלחה יוחזר ערך 0 או חיובי, אחרת -1.
18
תרגול 10 – מבוא למנהלי התקנים ב-Linux18 (c) אריק פרידמן 2006 יצירת התקן חדש הקריאה ל-register_chrdev רק מקשרת בין מנהל התקן לבין מספר ראשי כדי לעבוד עם ההתקן, יש ליצור קובץ חדש שייצג אותו, באמצעות הפקודה mknod (דורש הרשאות superuser) תחביר: mknod NAME TYPE MAJOR MINOR פרמטרים: NAME – שם הקובץ החדש (שייצג את ההתקן) TYPE – סוג ההתקן (c – התקן תווים, b – התקן בלוקים) MAJOR– המספר הראשי של ההתקן (למעשה קובע את מנהל ההתקן) MINOR– המספר המשני של ההתקן (מספר בין 0 ל-255) ניתן להסיר התקן באופן דומה למחיקת קובץ (rm)
19
תרגול 10 – מבוא למנהלי התקנים ב-Linux19 (c) אריק פרידמן 2006 זיהוי התקן ע"י מנהל ההתקן קבצים מיוצגים ע"י מבנה נתונים בשם inode (פרטים נוספים בתרגול על מערכות קבצים). בפרט, גם להתקן תווים יש inode המייצג אותו. בכל פעם שמבצעים פעולה על התקן, מנהל ההתקן מקבל כפרמטר את ה-inode המתאים. השדה i_rdev ב-inode מכיל את המספר הראשי והמשני של ההתקן. המאקרו MAJOR(inode->i_rdev) מחזיר את המספר הראשי המאקרו MINOR(inode->i_rdev) מחזיר את המספר המשני
20
תרגול 10 – מבוא למנהלי התקנים ב-Linux20 (c) אריק פרידמן 2006 פעולות על התקן מערכת ההפעלה מגדירה אוסף פעולות שניתן לבצע על קבצים בפרט זהו גם אוסף הפעולות שניתן לבצע על התקן תווים ניתן להפעיל את הפעולות באמצעות קריאות מערכת מבנה הנתונים file_operations הוא מערך של מצביעי הפונקציות המממשות את אותן הפעולות מוגדר ב- משתנה המצביע למבנה הנ"ל מכונה בד"כ fops או f_op מצביע NULL מייצג פונקציה לא ממומשת, או מימוש ברירת מחדל גישה מונחית אובייקטים הקובץ הוא האובייקט המתודות של האובייקט מוגדרות ע"י אוסף הפונקציות ב-fops
21
תרגול 10 – מבוא למנהלי התקנים ב-Linux21 (c) אריק פרידמן 2006 שדות חשובים ב-file operations int (*open) (struct inode *, struct file *); int (*release) (struct inode *, struct file *); int (*flush) (struct file *); ssize_t (*read) (struct file *, char *, size_t, loff_t *); ssize_t (*write) (struct file *, const char *, size_t, loff_t *); loff_t (*llseek) (struct file *, loff_t, int); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); struct module *owner;
22
תרגול 10 – מבוא למנהלי התקנים ב-Linux22 (c) אריק פרידמן 2006 אתחול file operations לצורך תאימות גדולה יותר בין גרסאות שונות, הוגדר תחביר מיוחד לאתחול: אתחול עם תוויות ("tagged” initialization) הרחבה יחודית למהדר של GNU struct file_operations my_fops = {. llseek=my_llseek,. read=my_read,. write=my_write, … }; אתחול שדה owner נעשה ע"י המאקרו הבא ב-init_module: SET_MODULE_OWNER(&fops);
23
תרגול 10 – מבוא למנהלי התקנים ב-Linux23 (c) אריק פרידמן 2006 איפה אנחנו עומדים בינתיים crw-r--r-- 1 root root 254, 0 May 17 2006 /dev/mycdev0 crw-r--r-- 1 root root 254, 1 May 17 2006 /dev/mycdev1 major numberminor number mycdev קבצי התקן: מנהל התקן: open release read write … owner fops
24
תרגול 10 – מבוא למנהלי התקנים ב-Linux24 (c) אריק פרידמן 2006 פתיחת התקן כאשר פותחים התקן (קריאת המערכת open), בין השאר מערכת ההפעלה מבצעת את הפעולות הבאות: מאתחלת מבנה נתונים מסוג struct file מבנה נתונים זה מייצג קובץ/התקן פתוח משתנה המצביע למבנה הנ"ל מכונה בד"כ file או filp כל הקריאות שהמשתמש מבצע על file descriptor מסויים, יועברו למנהל ההתקן עם אותו struct file במידה והפונקציה open אותחלה עבור מנהל ההתקן, מערכת ההפעלה קוראת לה ומעבירה את מבנה הנתונים כפרמטר
25
תרגול 10 – מבוא למנהלי התקנים ב-Linux25 (c) אריק פרידמן 2006 שדות חשובים ב-struct file mode_t f_mode; /* (FMODE_READ, FMODE_WRITE) */ loff_t f_pos; unsigned int f_flags; /* (O_RDONLY, O_NONBLOCK,…, see ) */ struct file_operations *f_op; void *private_data;
26
תרגול 10 – מבוא למנהלי התקנים ב-Linux26 (c) אריק פרידמן 2006 פתיחת התקן (2) הפונקציה open של מנהל ההתקן אחראית ל: הגדלת מונה השימוש של מנהל ההתקן (מתבצע אוטומטית בגרסאות 2.4 ומעלה) לבדוק שההתקן תקין (אין בעיות חומרה) לאתחל את ההתקן, אם זו הפעם הראשונה שפותחים אותו לזהות את המספר המשני, לעדכן את f_op אם צריך לאתחל מבני נתונים ב-filp->private_data
27
תרגול 10 – מבוא למנהלי התקנים ב-Linux27 (c) אריק פרידמן 2006 סגירת התקן הפונקציה release של מנהל ההתקן אחראית ל: הקטנת מונה השימוש של מנהל ההתקן (מתבצע אוטומטית בגרסאות 2.4 ומעלה) שחרור מבני נתונים ב-filp->private_data, אם צריך פעולת סגירה מתבצעת גם אם האפליקציה לא סגרה קבצים פתוחים באופן מפורש כאשר תהליך מבצע exit מערכת ההפעלה תפעיל את קריאת המערכת close עבור כל קובץ פתוח.
28
תרגול 10 – מבוא למנהלי התקנים ב-Linux28 (c) אריק פרידמן 2006 הפונקציות read ו-write תחביר: ssize_t read(struct file *filp, char *buff, size_t count, loff_t *offp); ssize_t write(struct file *filp, const char *buff, size_t count, loff_t *offp); פרמטרים: filp – מבנה הנתונים המייצג את הקובץ (ההתקן) הפתוח buff – חוצץ באזור הזכרון של המשתמש (מקור לקריאה/יעד לכתיבה) count – מספר הבתים שיש לקרוא/לכתוב offp – מצביע המייצג את המיקום שאליו המשתמש ניגש בקובץ ערך מוחזר: במקרה של הצלחה יוחזר מספר הבתים שהועתקו, אחרת ערך שלילי. הפרמטר offp מעודכן כדי לבטא את המיקום החדש בקובץ
29
תרגול 10 – מבוא למנהלי התקנים ב-Linux29 (c) אריק פרידמן 2006 הפונקציות read ו-write (2) ברוב המקרים נדרש להעתיק מידע בין אזור הזכרון של המשתמש ואזור הזכרון של הגרעין. לרוב מתבצע באמצעות: unsigned long copy_to_user(void *to, const void *from, unsigned long count); unsigned long copy_from_user(void *to, const void *from, unsigned long count); מוגדרות ב- הפונקציות מוודאות כי הגישה מתבצעת לאזורים חוקיים בזכרון במידה ולא, לא מתבצעת כל העתקה בכל מקרה, מוחזר מספר הבתים שנותרו להעתקה (0 אם ההעתקה הצליחה) ניתן להקצות ולשחרר זכרון בגרעין באמצעות kmalloc ו-kfree זהות ל-malloc ו-free, למעט פרמטר נוסף של kmalloc (GFP_USER, GFP_KERNEL)
30
תרגול 10 – מבוא למנהלי התקנים ב-Linux30 (c) אריק פרידמן 2006 הפונקציה ioctl מטרתה לאפשר פקודות בקרה ייחודיות להתקן יש להשתמש באפשרות זאת רק אם לא ניתן לספק מענה הולם במסגרת הפונקציות הקיימות תחביר: int (*ioctl)(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); פרמטרים: inode – אובייקט ה-inode המייצג את הקובץ filp – מבנה הנתונים המייצג את הקובץ הפתוח cmd – מספר סידורי של פקודה (על מנת לתמוך במספר פקודות בקרה) בדרך כלל משתמשים בקובץ header כדי להגדיר שמות לפקודות arg – פרמטר כללי אופציונלי (אם המשתמש לא מעביר אותו, יהיה ערך זבל) ערך מוחזר: תלוי בכותב מנהל ההתקן (שגיאה – ערך שלילי) בדרך כלל לפונקציה יהיה מבנה switch, בהתאם לפרמטר cmd
31
תרגול 10 – מבוא למנהלי התקנים ב-Linux31 (c) אריק פרידמן 2006 הפונקציה ioctl (2) בצד המשתמש, לקריאת המערכת ioctl יש מבנה ייחודי תחביר: int ioctl(int fd,int cmd,…); פרמטרים: fd – מתאר קובץ (שהתקבל כתוצאה של open) cmd – מספר סידורי של פקודה (יועבר כמו שהוא לפונקציה המממשת) … – נועד למנוע בדיקה של המהדר על הפרמטר האופציונלי בדרך כלל מתייחסים לפרמטר האופציונלי כ-char *argp ערך מוחזר: תלוי בכותב מנהל ההתקן (שגיאה – ערך -1)
32
תרגול 10 – מבוא למנהלי התקנים ב-Linux32 (c) אריק פרידמן 2006 הפונקציה ioctl (3) עדיף שהתקנים שונים יגדירו קבועים שונים עבור הפרמטר cmd התקנים שונים עושים שימוש באותם מספרים - פתח לתקלות מוסכמה לקביעת המספרים על סמך ארבעה פרמטרים type – מספר "קסם", רצוי ייחודי להתקן (8 ביטים) הנחיות לבחירת המספר: Documentation/ioctl-number.txt number – מספר סידורי (8 ביטים) direction – כיוון העברת המידע (מנקודת המבט של המשתמש) _IOC_NONE, _IOC_READ, _IOC_WRITE, _IOC_READ | _IOC_WRITE size – גודל מידע המשתמש המעורב בהעברה (8-14 ביטים) הקובץ מגדיר פונקציות מאקרו לקביעת המספרים ישנה פקודת מאקרו לכל כיוון (direction) של העברה: _IO(type,nr), _IOR(type,nr,dataitem) _IOW(type,nr,dataitem), _IOWR(type,nr,dataitem)
33
תרגול 10 – מבוא למנהלי התקנים ב-Linux33 (c) אריק פרידמן 2006 הפונקציה ioctl (4) דוגמה: #define MYDEV_IOC_MAGIC ‘o’ #DEFINE MYDEV_IORESET _IO(MYDEV_IOC_MAGIC,0) #DEFINE MYDEV_SETMODE _IOW(MYDEV_IOC_MAGIC,1,char) #DEFINE MYDEV_GETMODE _IOR(MYDEV_IOC_MAGIC,2,char)
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.