เปิดรับสมัครสมาชิก webboard ตามปกติแล้วครับ

ผู้เขียน หัวข้อ: ไดรเวอร์ ปัญหาที่ไม่ใหญ่ แต่อาจทำให้คุณ ตายน้ำตื้นได้!  (อ่าน 4830 ครั้ง)

0 สมาชิก และ 1 บุคคลทั่วไป กำลังดูหัวข้อนี้

athaphol

  • บุคคลทั่วไป
ไดรเวอร์ ปัญหาที่ไม่ใหญ่ แต่อาจทำให้คุณ ตายน้ำตื้นได้!

ที่มา
Computer Today ฉบับที่ 233 ปักษ์แรก มีนาคม 2547
Cover Story ไดรเวอร์ ปัญหาที่ไม่ใหญ่ แต่อาจทำให้คุณ ตายน้ำตื้นได้!
โดย ธวัชวงศ์ ลาวัลย์


"ไดรเวอร์" คำๆ นี้ผมว่าน่าจะเป็นคำที่คุ้นหูสำหรับทุกคนอยู่ไม่น้อย และเดาว่ายังมีหลายคนที่อาจจะยังไม่เข้าใจอย่างถ่องแท้ว่ามันคืออะไร มีหน้าที่อย่างไร และที่สำคัญมันมาเป็นญาติ (ฝ่ายไหน) กับคอมพิวเตอร์ตั้งแต่เมื่อไหร่

ว่ากันว่า หลักการทำงานของคอมพิวเตอร์นั้นจะต้องอาศัยองค์ประกอบหลักๆ 2 ส่วน ด้วยกันคือฮาร์ดแวร์และซอฟต์แวร์ ฮาร์ดแวร์หรืออุปกรณ์ต่างๆ ภายในเครื่องคอมพิวเตอร์จะอาศัยโปรแกรมหรือซอฟต์แวร์ช่วยให้มันทำงานประสานกันได้อย่างลงตัว โดยใช้โปรแกรมระบบปฏิบัติการเป็นตัวกลางอีกที เราเรียกซอฟต์แวร์ประเภทนี้ว่า “ไดรเวอร์” หรือ “ดีไวซ์ไดรเวอร์”

ไดรเวอร์ (Driver) หรือ ดีไวซ์ไดรเวอร์ (Device Driver) ถ้าแปลกันตรงตัวตามพจนานุกรมอังกฤษ-ไทย (แทบทุกฉบับ) จะให้ความหมายเหมือนกัน คือ Device แปลว่าอุปกรณ์, เครื่องประดิษฐ์, เครื่องกลไก ส่วน Driver ก็แปลว่า ผู้ขับขี่, คนขับรถ, เมื่อนำมาแปลรวมกันจึงน่าจะเป็นผู้ขับอุปกรณ์ หรือผู้ควบคุมการทำงานของอุปกรณ์ ดังนั้น อุปกรณ์ต่างๆ ของเครื่องคอมพิวเตอร์ ไม่ว่าจะเป็นการ์ดจอ, แลนการ์ด, ซาวนด์การ์ด, ตลอดจนอุปกรณ์ต่อพ่วงภายนอกอื่นๆ อย่างเช่นพรินเตอร์, แสกนเนอร์, กล้องดิจิตอล ฯลฯ จึงต้องมีดีไวซ์ไดรเวอร์ (ต่อไปจะขอเรียกสั้นๆ ว่า "ไดรเวอร์" นะครับ) เป็นของตนเอง ไม่เช่นนั้นแล้วอุปกรณ์ก็จะไม่สามารถทำงานภายใต้ระบบปฏิบัติการที่ติดตั้งได้ ดังนั้น เราจึงมักพบเห็นเสมอๆ หลังจากที่เราติดตั้งอุปกรณ์ใหม่ๆ เข้าไปในเครื่องคอมพิวเตอร์ เมื่อเปิดเครื่องโปรแกรมระบบปฏิบัติการ (เช่น Windows, Linux, MAC Os ฯลฯ) มักจะมีข้อความแจ้งเตือนให้เราใส่แผ่นที่บรรจุไดรเวอร์สำหรับอุปกรณ์ตัวนั้นเข้าไปในที่อ่านแผ่น ทั้งนี้เพื่อโปรแกรมระบบปฏิบัติการจะได้ทำการติดตั้งโปรแกรมไดรเวอร์สำหรับควบคุม และติดต่อสื่อสารกับอุปกรณ์นั้นอีกที

ประเภทและการทำงานของไดรเวอร์

เรามาทำความเข้าใจถึงขบวนการทำงานของไดรเวอร์กันสักนิด โดยโปรแกรมไดรเวอร์จะถูกโหลดเข้าสู่หน่วยความจำของเครื่องคอมพิวเตอร์ ทันทีที่โปรแกรมระบบปฏิบัติการทำงาน ทั้งนี้เพื่อจูนอุปกรณ์ให้สามารถทำงานกับอุปกรณ์ตัวอื่น ในที่นี้เราสามารถแบ่งโปรแกรมไดรเวอร์ออกเป็นสองประเภทใหญ่ๆ คือ ไดรเวอร์พื้นฐาน และไดรเวอร์พิเศษเฉพาะอุปกรณ์แต่ละตัวไดรเวอร์พื้นฐานที่โปรแกรมระบบปฏิบัติการทุกแพลตฟอร์มเตรียมให้แล้วใน BIOS (Basic Input Output) ซึ่งก็มีไดรเวอร์ของคีย์บอร์ด, เมาส์ (ในดอสไม่มีนะครับ), จอภาพ, พอร์ตอนุกรม, พอร์ตขนาน, เรียลไทม์คล็อก, ดิสก์ไดรฟ์ และในวินโดวส์รุ่นหลังๆ นี้จะมีพอร์ตยูเอสบีเพิ่มเข้ามาอีกด้วย 
 


ส่วนไดรเวอร์พิเศษเฉพาะอุปกรณ์ บริษัทผู้ผลิตอุปกรณ์จะเป็นผู้สร้างขึ้น เช่น ไดรเวอร์เครื่องพิมพ์เลเซอร์สำหรับลีนุกซ์, ไดรเวอร์กล้องดิจิตอลสำหรับวินโดวส์ 98 ที่สำคัญมากคือคุณจะต้องต้องติดตั้งไดรเวอร์ลงไปให้ระบบปฏิบัติการรู้จักก่อน ไม่งั้นจะไม่สามารถใช้อุปกรณ์พิเศษเหล่านั้นได้ ซึ่งในสมัยก่อน ถ้าจะติดตั้งไดรเวอร์สำหรับอุปกรณ์ที่เพิ่มเข้ามาในเครื่องในระบบปฏิบัติการดอส จะต้องใช้คำสั่ง Device หรือ DeviceHigh เพิ่มลงไปในไฟล์ Config.sys ไดรเวอร์ที่เพิ่มเติมเข้ามาอาจจะใช้แทนไดรเวอร์พื้นฐานได้ เช่น ในกรณีใช้เมาส์แบบพิเศษ เราก็สามารถติดตั้งไดรเวอร์ของเมาส์ตัวนั้นลงไปแทนไดรเวอร์มาตรฐานได้ ส่วนในระบบปฏิบัติการตัวอื่นไม่ว่าจะเป็นวินโดวส์, ลีนุกซ์, แม็ก ฯลฯ ต่างก็มีคำสั่งในการโหลดไดรเวอร์โดยเก็บไว้ในไฟล์ที่สำคัญ

ถ้าแบ่งตามลักษณะการรับข้อมูลหรือการรับรู้อุปกรณ์ของระบบปฏิบัติการ เราสามารถแบ่งไดรเวอร์ออกเป็น 2 แบบคือคาแรกเตอร์ดีไวซ์และบล็อกดีไวซ์ (Character and Block Device) โดยคาแรกเตอร์ดีไวซ์หมายถึงอุปกรณ์ที่กระทำกับข้อมูลอินพุตหรือเอาต์พุตครั้งละหนึ่งอักขระในช่วงเวลาหนึ่งตัวอย่างอุปกรณ์เหล่านี้ก็เช่น คีย์บอร์ด จอภาพ พอร์ตอนุกรม และพอร์ตขนาน ส่วนบล็อกดีไวซ์จะกระทำกับกลุ่มข้อมูลอินพุตและเอาต์พุตที่มีลักษณะเป็นโครงสร้างตัวอย่างของบล็อก ดีไวซ์ เช่น ดิสก์ไดรฟ์ทุกชนิด และอุปกรณ์เก็บข้อมูลอื่นๆ ดีไวซ์ไดรเวอร์ตัวหนึ่งจะสนับสนุน คาแรกเตอร์ดีไวซ์ หรือบล็อกดีไวซ์อย่างใดอย่างหนึ่งเท่านั้น แต่จะไม่สนับสนุนสองอย่างพร้อมๆ กัน ชนิดของดีไวซ์ที่ไดรเวอร์นั้นสนับสนุนจะตรวจสอบได้จาก ฟังก์ชันที่ไดรเวอร์เรียกใช้ และข้อมูลที่บอกที่ส่วนเฮดเดอร์ของดีไวซ์ไดรเวอร์

รูปแบบของดีไวซ์ไดรเวอร์ (Device-Driver Format)

ดีไวซ์ไดรเวอร์ทุกตัวไม่ว่าจะสนับสนุนคาแรกเตอร์ดีไวซ์ หรือบล็อกดีไวซ์จะต้องประกอบด้วยส่วนของเฮดเดอร์ (Device-driver header) รูทีนกลวิธี (Strategy Routine) และรูทีนอินเทอร์รัปต์ (Interrupt Routine) ซึ่งส่วนประกอบเหล่านี้จะใช้ในการเตรียมข้อมูลและโค้ด เมื่อระบบปฏิบัติการต้องการเพื่อใช้จัดการอินพุตและเอาต์พุต จากอุปกรณ์ ดีไวซ์ไดรเวอร์ที่ติดตั้งเพิ่มเติมจะอยู่ในรูปไฟล์เลขฐานสอง (Binary image file) ที่มีการระบุตำแหน่งที่จะ โหลด (absolute load images) หรือไม่ก็ อยู่ในรูปของไฟล์EXE (Binary image file) ที่ซึ่งประกอบด้วยดีไวซ์ไดรเวอร์ นั้นส่วนใหญ่แล้วจะเก็บไฟล์ที่มีส่วนขยายเป็น .SYS เพื่อแยกความแตกต่างกับ Binary image file อื่นๆ เช่น ไฟล์โปรแกรม .COM ถึงแม้ว่าไฟล์สำหรับดีไวซ์ไดรเวอร์ส่วนใหญ่จะประกอบด้วยหนึ่งดีไวซ์ไดรเวอร์ แต่ก็มีบางตัวที่มากกว่าหนึ่ง ในกรณีเช่นนี้ไฟล์นั้นจะต้องมีหนึ่งเฮดเดอร์สำหรับแต่ละไดรเวอร์


DEVICEHEADER STRUC 
dhLink dd ?   ; เชื่อมไปยังไดรเวอร์ต่อไป   
dhAttributes dw ?   ; บอกดีไวซ์แอทตริบิวต์ 
dhStrategy dw ?   ; ออฟเซตของรูทีนกลวิธี 
dhInterrupt dw ?   ; ออฟเซตของรูทีนอินเทอร์รัปต์ 
dhInterrupt dw ?   ; ออฟเซตของรูทีนอินเทอร์รัปต์ <
                           ; (กรณีที่เป็นคาแรกเตอร์ดีไวซ์) 
                           ; หรือเป็นตัวเลขบอกยูนิต 
                           ; (กรณีเป็นบล็อกดีไวซ์) 
DEVICEHEADER ENDS 
 


ดีไวซ์ไดรเวอร์เฮดเดอร์ (Device-Driver Header) จะต้องเป็นส่วนเริ่มต้นของดีไวซ์ไดรเวอร์ เป็นส่วนชี้เฉพาะถึงดีไวซ์ไดรเวอร์ที่ใช้ ระบุรูทีนกลวิธีและรูทีนอินเทอร์รัปต์ของดีไวซ์ไดรเวอร์และกำหนดแอตทริบิวต์ของดีไวซ์ที่ไดร์เวอร์นั้นสนับสนุน รูปแบบของดีไวซ์ไดรเวอร์เฮดเดอร์จะสัมพันธ์กับโครงสร้าง DEVICEHEADER ดังตารางข้างบน 
 


ถ้าไม่มีดีไวซ์ไดรเวอร์เฮดเดอร์อื่นอีกในไฟล์นั้น ค่าฟิลด์ dhLink จะต้องเป็น 0FFFFh แต่ถ้ามีไดรเวอร์อื่นอีก ค่า 16 บิตล่างของฟิลด์นี้จะเก็บออฟเซต (นับจากจุดเริ่มต้นของ load image) ที่ชี้ไปยังดีไวซ์เฮดเดอร์ตัวต่อไปและ 16 บิตบนจะเป็นค่าศูนย์ เมื่อมีการโหลดไดรเวอร์ระบบปฏิบัติการจะกำหนดให้ฟิลด์นี้ชี้ไปยังไดรเวอร์ตัวต่อไปใน driver chain ฟิลด์ dhAttributes ใช้ในการระบุชนิดของดีไวซ์และเตรียมข้อมูลเพิ่มเติมซึ่งระบบปฏิบัติการใช้เมื่อมันต้องการ ค่าบิตต่างๆ ในฟิลด์เป็นดังนี้


บิต 0 ใช้สำหรับคาแรกเตอร์ดีไวซ์
ไดรเวอร์ ระบุดีไวซ์ที่ใช้เป็นมาตรฐานบิตนี้จะเซตเป็น 1 ถ้าไดรเวอร์นี้ไปแทนที่ไดรเวอร์พื้นฐาน (Resident Device Driver) ที่ซึ่งสนับสนุนอินพุตมาตรฐานอยู่แล้ว

บิต 1 ใช้สำหรับคาแรกเตอร์ดีไวซ์
ไดรเวอร์ระบุดีไวซ์ไดรเวอร์ที่ใช้เป็นเอาต์พุต มาตรฐานบิตนี้จะถูกเซตเป็น 1 ถ้าไดรเวอร์นี้ไปแทนที่ไดรเวอร์พื้นฐาน ซึ่งสนับสนุนเอาต์พุตมาตรฐานอยู่แล้วสำหรับบล็อกดีไวซ์ไดรเวอร์ บิตนี้จะบอกว่าไดรเวอร์นี้จะสนับสนุนการประมวลผลที่อ้างตำแหน่งแบบ 32 - bit sector address หรือไม่ ถ้าบิตนี้ถูกเซตเป็น 1 แสดงว่าสามารถอ้างอิงตำแหน่งแบบ 32 - bit sector address ได้ ระบบปฏิบัติการจะตรวจสอบบิตนี้เพื่อให้รู้ว่าจะต้องใช้ฟิลด์ rwrHugeSector ของโครงสร้าง READ WRITERQUEST ในการอ้างตำแหน่งสำหรับฟังก์ชัน Read (ดีไวซ์ไดรเวอร์ฟังก์ชัน 04h ) Write (ดีไวซ์ไดรเวอร์ฟังก์ชัน 08h) และ Write with verify (ดีไวซ์ไดรเวอร์ฟังก์ชัน 09h) ถ้าบิตนี้เป็นศูนย์แสดงว่าไดรเวอร์นี้สนับสนุนดีไวซ์ที่อ้างแอดเดรสแบบ 16- bit sector addressing

บิต 2 ใช้สำหรับคาแรกเตอร์ดีไวซ์
ไดรเวอร์ใช้ระบุว่าดีไวซ์ที่ใช้เป็นดีไวซ์สมมติ (NUL device) โดยไดรเวอร์พื้นฐานของอุปกรณ์สมมุติ (resident NUL device driver) จะเป็นไดรเวอร์พื้นฐานที่ไม่สามารถถูกแทนที่โดยไดรเวอร์เพิ่มเติมตัวอื่นได้ ดังนั้น ค่าบิตจะต้องเป็นศูนย์สำหรับดีไวซ์ไดรเวอร์อื่นทั้งหมด

บิต 3 ใช้สำหรับคาแรกเตอร์ดีไวซ์
ไดรเวอร์ใช้ระบุว่าดีไวซ์ที่ใช้เป็น clock device บิตนี้ จะมีค่าเป็น 1ถ้าไดรเวอร์ถูกแทนที่ด้วยไดรเวอร์เพิ่มเติมตัวใหม่ที่สนับสนุน clock device

บิต 4 ใช้สำหรับคาแรกเตอร์ดีไวซ์
ไดรเวอร์ระบุว่าไดรเวอร์นั้นสนับสนุน fast character output ถ้าบิตนี้ถูกเซตแสดงว่าระบบปฏิบัติการเรียกใช้ Fast Console (อินเทอร์รัปต์ 29h) (ด้วยค่าของอักขระที่อยู่ในรีจิสเตอร์ AL) เมื่อโปรแกรมต้องการเขียนไปยังดีไวซ์นั้น เช่น เมื่อใช้ฟังก์ชัน Direct Console I/O (อินเทอร์รัปต์ 21hฟังก์ชัน 29h) ขณะการติดตั้งดีไวซ์ไดรเวอร์ตังนี้จะต้องติดตั้งแฮนเดิล (สำหรับอินเทอร์รัปต์ 29h) เพื่อใช้จัดการ fast output

บิต 6 ใช้บอกว่าไดรเวอร์สนับสนุน
ฟังก์ชัน logic-drive mapping หรือ generic IOCTL หรือทั้งสองฟังก์ชันหรือไม่ถ้าบิตนี้ถูกเซตเป็น 1 แสดงว่าดีไวซ์ไดรเวอร์สามารถใช้ฟังก์ชัน Get Logic Drive และ Set Logic Drive (ดีไวซ์ไดรเวอร์ฟังก์ชัน 13h)

บิต 7 ใช้บอกว่า
ไดรเวอร์สนับสนุนฟังก์ชัน IOCTL Query หรือไม่ ถ้าบิตนี้ถูกเซตเป็น 1 แสดงว่าดีไวซ์ไดรเวอร์สามารถใช้ฟังก์ชัน IOCTL Query (ดีไวซ์ไดรเวอร์ฟังก์ชัน 19h)

บิต 11 ใช้บอกว่าไดรเวอร์สนับสนุน
ฟังก์ชัน Open Device, Close Device และ Removable Media Drive (ดีไวซ์ไดรเวอร์ฟังก์ชัน 0Dh,0Eh และ 0Fh) หรือไม่ ถ้าบิตนี้ถูกเซตเป็น 1 แสดงว่าดีไวซ์ไดรเวอร์สามารถใช้ฟังก์ชันเหล่านี้ได้ เฉพาะบล็อกดีไวซ์ไดรเวอร์เท่านั้นที่สามารถใช้ Removable Media

บิต 13 ใช้สำหรับคาแรกเตอร์ดีไวซ์
ไดรเวอร์ใช้บอกว่าไดรเวอร์สนับสนุนฟังก์ชัน Output Unit Busy (ดีไวซ์ไดรเวอร์ 10h) หรือไม่ถ้าบิตนี้ถูกเซตเป็น 1 แสดงว่าดีไวซ์ไดรเวอร์สามารถใช้ฟังก์ชันเหล่านี้ได้สำหรับบล็อกดีไวซ์ไดรเวอร์ ใช้บอกว่าไดรเวอร์ระบบปฏิบัติการให้ค่าเซกเตอร์แรก FAT ตัวแรกเมื่อต้องการใช้ฟังก์ชัน Build BPB (ดีไวซ์ไดรเวอร์ฟังก์ชัน 02h) บิตนี้จะต้องเป็น 0 ถ้าไดรเวอร์ต้องการ FAT

บิต 14 ใช้บอกว่าไดรเวอร์สนับสนุน
ฟังก์ชัน IOCTL Read และ IOCTL Write (ดีไวซ์ไดรเวอร์ฟังก์ชัน 03h และ 0Ch) หรือไม่ ถ้าบิตนี้ถูกเซตเป็น 1 แสดงว่าดีไวซ์ไดรเวอร์สามารถใช้ฟังก์ชันเหล่านี้

บิต 15 ใช้บอกว่า
ไดรเวอร์สนับสนุนคาแรกเตอร์ดีไวซ์ไดรเวอร์หรือบล็อกดีไวซ์ไดรเวอร์ ถ้าบิตนี้ถูกเซตเป็น 1 แสดงว่าดีไวซ์ไดรเวอร์สนับสนุนคาแรกเตอร์ดีไวซ์บางบิตในฟิลด์ db Attributes ที่ไม่ถูกใช้สำหรับดีไวซ์ที่กำหนดจะถูกเซตให้เป็นศูนย์ 
 


ฟิลด์ dbStrategy และ dbInterrupt ประกอบด้วยออฟเซตขนาด 16 บิตของตำแหน่งเริ่มต้น ของรูทีนกลวิธีและรูทีนอินเทอร์รัปต์ นั้นคือตำแหน่งเริ่มต้น ของรูทีนทั้งสองจะต้องอยู่ใน เซกเมนต์เดียวกับดีไวซ์ไดรเวอร์เฮดเดอร์สำหรับดีไวซ์ไดรเวอร์ที่อยู่ในไฟล์เลขฐานสอง (Binary image file) ออฟเซตจะเป็นไบต์ที่เริ่มจากตำแหน่งเริ่มต้นของไฟล์ สำหรับไดรเวอร์ ที่ไฟล์ .EXE ออฟเซตจะเป็นไบต์ที่เริ่มจากตำแหน่งของ file’s load image ฟิลด์ dbNameOrUnit มีขนาด 8 ไบต์ ที่ประกอบด้วยชื่อของดีไวซ์ (logical-device name) หรือไม่ก็เป็นค่า 1 ไบต์ที่ระบุตัวเลขของยูนิตที่สนับสนุนคาแรกเตอร์ดีไวซ์จะอนุญาตให้ตั้งชื่อของ logical-device name ได้ไม่เกิน 8 ตัวอักษร (ในดอส) และชื่อต้องเริ่มจากตำแหน่งซ้ายโดยไบต์ ที่เหลือจะถูกเติมจนครบด้วยอักขระว่าง (ASCII 20h) และชื่อดีไวซ์จะต้องไม่มีอักขระโค-ลอน (; ) ในชื่อนั้นในกรณีที่บล็อกดีไวซ์ไม่ต้องการใช้ชื่อไดรเวอร์แต่จะแทนค่าฟิลด์ด้วยตัวเลขของยูนิตที่สนับสนุนนอกจากนี้ยังมีทางเลือกอีกทางหนึ่งก็คืออดสจะเติมค่าในฟิลด์นี้ด้วยค่าที่ไดรเวอร์คืนกลับมาเมื่อมีการเรียกใช้ฟังก์ชัน Init (ดีไวซ์ไดรเวอร์ฟังก์ชัน 00h)

รูทีนกลวิธีและรูทีนอินเทอร์รัปต์ (Stategy and InterruptRoutine)

ไดรเวอร์แต่ละตัวจะประกอบด้วยสองรูทีน (รูทีนเสมือนโปรแกรมย่อย) คือรูทีนกลวิธีและรูทีนอินเทอร์รัปต์ เมื่อเรียกใช้งานระบบปฏิบัติการ (โดยเฉพาะดอส) จะเรียกใช้งานสองรูทีน แต่จะมีเพียงรูทีนอินเทอร์รัปต์ เท่านั้นที่ทำการจัดงานต่างๆ ดอสจะเรียกรูทีนกลวิธีของดีไวซ์ไดรเวอร์ด้วย far call โดยการผ่าน (รีจิสเตอร์ ES:BX) แอดเดรส 32 บิตของ request packet รูทีนกลวิธีจะเก็บค่าแอดเดรสนี้ และคืนการทำงานกลับโดยการใช้ far return ต่อจากนั้นดอสจะเรียกรูทีนอินเทอร์รัปต์เพื่อให้ดีไวซ์ไดรเวอร์ได้จัดการตามฟังก์ชันที่ถูกเรียกใช้ (Requested Function) ด้วยการเข้าถึงฮาร์ดแวร์โดยตรงหรือไม่ก็เรียกผ่านรอมไบออส เมื่อทำงานเสร็จเรียบร้อยรูทีนอินเทอร์รัปต์จะต้องกำหนดค่าสภาวะต่างๆ (Status Value) ให้กับ request packet และคืนการทำงานจองไดรเวอร์ที่ถูกเรียกใช้

คำว่ารูทีนอินเทอร์รัปต์เป็นเพียงชื่อที่ใช้เรียกเท่านั้น แท้จริงแล้วรูทีนนี้ไม่ได้ถูกเรียกใช้งาน จากการเกิดอินเทอร์รัปต์ แต่เป็นการเรียกจากดอสโดยตรงเมื่อมีการเรียกใช้รูทีน การอินเทอร์รัปต์ จะต้องมีการตรวจสอบฟิลด์ฟังก์ชัน (Function field) ใน request packet เพื่อหาว่าจะต้องการ ทำงานอะไร ดังนั้น ในช่วงเวลาเดี๋ยวกันดีไวซ์เวอร์จะรับการร้องขอได้เพียงหนึ่งงานเท่านั้นเพราะการร้องขอจะต้องเรียกใช้รูทีนอินเทอร์รัปต์เพื่อจัดการงานนั้นโดยรูทีนนี้จะแสดงสภาวะบอก MS-DOS ให้รู้ว่าดีไวซ์ยังมีงานอยู่หรืออยู่ในสภาวะทำงานผิดพลาด รูทีนกลวิธีและรูทีนอินเทอร์รัปต์จะต้องเก็บรีจิสเตอร์และแฟล็กที่เรียกใช้งานไว้รูทีนสามารถเก็บค่าเหล่านี้ลงในหน่วยความจำที่เรียกว่าสเเต็ก (Stack) และคืนค่าที่เก็บไว้ก่อนคืนการทำงานกลับไป แต่พื้นที่ของสแต็กมีขนาดจำกัด เมื่อรูทีนถูกเรียกใช้จะใช้พื้นที่สแต็ก 40 ถึง 50 ไบต์ ดังนั้น ถ้าไดรเวอร์ ต้องการพื้นที่มากกว่านี้จะต้องมีการกำหนด สแต็กของตัวเองใหม่สำหรับค่าที่มีความสำคัญเป็นพิเศษ ซึ่งจะต้องมีการเก็บไว้ในทุกกรณีคือ แฟล็กทิศทาง (Direction flag) และบิตของการอีนาเบิลอินเทอร์รัปต์ (Interrupt-enable bits)


ฟังก์ชัน  ชื่อฟังก์ชัน                     หมายเหตุ   
00h      lnit   
01h      Media Check 
02h      Build BPB 
03h      IOCTL Read                ต้องการเมื่อบิตที่ 14 ในฟิลด์ dbAttributes ของโครงสร้าง DEVICEHEADER ถูกเซต 
04h      Read 
08h      Write 
09h      Write and Verify 
0Ch      IOCTLN Write             ต้องการเมื่อบิตที่ 14 ของฟิลด์ dbAttributes ถูกเซต 
0Dh      Open Device              ต้องการเมื่อบิตที่ 11ของฟิลด์ dbAttributes ถูกเซต 
0Eh      Close Device               ต้องการเมื่อบิตที่ 11ของฟิลด์ dbAttributes ถูกเซต 
0Fh      Removable Media        ต้องการเมื่อบิตที่ 11ของฟิลด์ dbAttributes ถูกเซต 
13h      Generic IOCTL            ต้องการเมื่อบิตที่ 6 ของฟิลด์ dbAttributes ถูกเซต 
17h      Get LOGICAL Device    ต้องการเมื่อบิตที่ 6 ของฟิลด์ dbAttributes ถูกเซต 
18h      Set Logical Device       ต้องการเมื่อบิตที่ 6 ของฟิลด์ dbAttributes ถูกเซต 
19h      IOCTL Query              ต้องการเมื่อบิตที่ 7 ของฟิลด์ dbAttributes ถูกเซต

บล็อกดีไวซ์ ไดรเวอร์ (Block-Device Driver)

บล็อกดีไวซ์ไดรเวอร์จะจัดการข้อมูลอินพุตและเอาต์พุตของอุปกรณ์เก็บข้อมูล เช่น ดิสก์ไดรฟ์ โดยไดรเวอร์เหล่านี้จะต้องมีฟังก์ชันในการจัดการดังต่อไปนี้

บล็อกดีไวซ์ไดรเวอร์แต่ละตัวสามารถควบคุมการทำงานของดีไวซ์หนึ่งตัวหรือมากกว่าก็ได้ดีไวซ์ที่กล่าวอาจเป็นฟิสิกส์คอลไดรฟ์ เช่น ฟล็อปปีดิสก์ หรือเป็นลอจิคอลไดรฟ์ เช่น พาร์ทิชันไดรฟ์ของฮาร์ดดิสก์ กรณีที่ดีไวซ์เป็นไดรฟ์ดอสจะกำหนดเลขหมายประจำไดรฟ์ (Unique Drive Number) เพื่อให้โปรแกรมใช้เลขนี้ในการเข้าถึงไดรฟ์ไดรเวอร์สามารถตรวจสอบและรายงายว่ามีดีไวซ์ที่สนับสนุนจำนวนเท่าใดได้ด้วยการเรียกใช้ฟังก์ชัน Init (ดีไวซ์ไดรเวอร์ ฟังก์ชัน 00h) MS-DOS จะยอมรับการกำหนดไดรฟ์ได้สูงสุด 26 ไดรฟ์ ต่อหนึ่งระบบถ้าดีไวซ์ไดรเวอร์รายงานจำนวนไดรฟ์ มากกว่า 26 ตัว ดอสจะยุติการทำงานไดรเวอร์ตัวนั้น ดังนั้น เพื่อให้แน่ใจว่าไดรเวอร์จะรายงานไม่เกินขนาดสูงสุดดอสจะใช้วิธีส่งหมายเลขไดรฟ์ต่อไปที่ว่างให้กับไดรเวอร์ขณะทำการติดตั้งไดรเวอร์

วิธีจะทำให้ติดตั้งไดรเวอร์ได้สมบูรณ์โดยจำนวนไดรฟ์และหมายเลขไดรฟ์ จะไม่เกิน 26 ไดรฟ์ เราไม่สามารถติดตั้งบล็อกดีไวซ์ไดรเวอร์เพิ่มเติมแทนที่ไดรเวอร์พื้นฐานได้บล็อกไดรเวอร์ที่ติดตั้งเพิ่มจะสามารถใช้ได้เฉพาะในกรณีที่ไดรเวอร์พื้นฐานไม่สนับสนุนไดรฟ์นั้นโดยตรง สังเกตว่าดอสจะติดตั้งดีไวซ์ไดรเวอร์พื้นฐานให้เสมอ ก่อนไดรเวอร์ที่ติดตั้งเพิ่มและการกำหนดหมายเลขไดรฟ์ที่กำหนดก็จะเรียงลำดับตามการติดตั้ง

คาแรกเตอร์ดีไวซ์ (Character -Device Drivers)

คาแรกเตอร์ดีไวซ์ไดรเวอร์ที่ติดตั้งเพิ่มจะจัดการอินพุตและเอาต์พุตของดีไวซ์ เช่น คีย์บอร์ด จอภาพ หรือพอร์ตอนุกรมโดยคาแรกเตอร์ดีไวซ์ไดรเวอร์จะต้องมีฟังก์ชันดังต่อไปนี้

คาร์แรกเตอร์ดีไวซ์แต่ละตัวจะต้องมีชื่อลอจิกคอลดีไวซ์ (Logical-Device Name) ที่ใช้ในการระบุถึงไดรเวอร์ และชื่อนี้จะถูกใช้โดยโปรแกรม เพื่อใช้ในการเปิดดีไวซ์ชื่อลอจิกคอลดีไวซ์ไม่ได้เป็นชื่อเฉพาะของไดรเวอร์ตัวใดตัวหนึ่ง ชื่อนี้สามารถแทนไดรเวอร์ได้หลายตัวขึ้นอยู่กับว่าไดรเวอร์ตัวใดติดตั้งหลังสุด ดังนั้น เมื่อดอสเปิดดีไวซ์จะมีการค้นหาลูกโซ่ของการเชื่อมต่อไดรเวอร์ที่โหลดจากจุดเริ่มต้น (ติดตั้งหลังสุด) จนกว่าจะพบไดรเวอร์ ที่สุดก็จะถูกพบก่อนเมื่อที่เหมือนกับชื่อลอจิกคอลไดรเวอร์ที่ระบุโดยไดรเวอร์ที่ติดตั้งหลังสุดจะอยู่ใกล้จุดเริ่มต้นมาก ดอสค้นพบจะหยุดการค้นหาด้วยเหตุนี้เองทำให้ไดรเวอร์พื้นฐาน (Resident Device Drivers) สามารถถูกแทนที่ด้วยไดรเวอร์ที่ติดตั้งเพิ่มเติม ทั้งที่ชื่อลอจิกคอลไดรเวอร์เหมือนกัน


ฟังก์ชัน  ชื่อฟังก์ชัน                 หมายเหตุ 
00h      Init 
03h      IOCTL Read             ต้องการเมื่อบิตที่ 14 ในฟิลด์ dhAttributes ของโครงสร้างDEVICEHEADER ถูกเซต 
04h      Read 
05h      Nondestructive Read 
06h      Input Status 
07h      Input Flush 
08h      Write 
09h      Write with Verify 
0Ah      Output Status 
0Bh      Output Flush 
0Ch      IOCTL Write             ต้องการเมื่อบิตที่14 ในฟิลด์ dhAttributes ของโครงสร้างDEVICEHEADER ถูกเซต 
0Dh      Open Device            ต้องการเมื่อบิตที่11ในฟิลด์ dhAttributes ของโครงสร้างDEVICEHEADER ถูกเซต 
0Eh      Close Device             ต้องการเมื่อบิตที่ 11ในฟิลด์ dhAttributes ของโครงสร้าง DEVICEHEADER ถูกเซต 
10h      Output Unit Busy      ต้องการเมื่อบิตที่13ในฟิลด์ dhAttributes ของโครงสร้าง DEVICEHEADER ถูกเซต 
13h      Generic IOCTL          ต้องการเมื่อบิตที่6ในฟิลด์ dhAttributes ของโครงสร้าง DEVICEHEADER ถูกเซต 
19h      IOCTL Query            ต้องการเมื่อบิตที่ 7ในฟิลด์ dhAttributes ของโครง สร้าง DEVICEHEADER ถูกเซต

จบแล้วครับ ขอบคุณครับที่กรุณาอ่านจนจบ แล้วจะหาบทความดี ๆ มาให้อ่านจนตาแฉะอีกนะครับ    สวัสดี   :c_laugh:

ออฟไลน์ softxg

  • µ¹à»ç¹·Õè¾Öè§àËç¹µ¹
  • มหาลัยรัฐบาล
  • ******
  • กระทู้: 313
  • Reputation: 0
  • เพศ: ชาย
  • µ¹à»ç¹·Õè¾Öè§áË觵¹
    • ʹã¨àÅÕ駻ÅÒ µÔ´µèÍ ÃÒªÒ»Åҷͧä´é¤ÃѺ
ขอบคุณที่นำความรู้มาฝากครับท่าน
Signature cleanned by Admin

Tmaster

  • บุคคลทั่วไป
ขอบคุณครับ

Hanger

  • บุคคลทั่วไป
ยอดความรู้เลย ครับ

ออฟไลน์ fannet

  • ปี 1 เทอม 2
  • ***
  • กระทู้: 15
  • Reputation: 0
ขอบคุณหลายๆ ครับ ความรู้ใหม่
Signature cleanned by Admin

olddej

  • บุคคลทั่วไป
จะเป็นกำลังใจให้ครับ

bitong101010

  • บุคคลทั่วไป
 :-* ๛ok:

kookai8

  • บุคคลทั่วไป
ชอบครับหามาอีกครับ

ออฟไลน์ jochin

  • ปี 1 เทอม 2
  • ***
  • กระทู้: 12
  • Reputation: 0
ขอบคุณครับ
Signature cleanned by Admin

karanzio

  • บุคคลทั่วไป
 :-* ขอบคุณคับ :c_laugh:

HKR

  • บุคคลทั่วไป
คนเขียนนี่เป็น อ.ผมเอง

ออฟไลน์ toyting

  • สอบภาคทฤษฎี
  • *
  • กระทู้: 7
  • Reputation: 0
ขอบคุณคับ :clap: :clap: :clap:
Signature cleanned by Admin

ออฟไลน์ deieiman

  • นักเรียนประถม
  • ****
  • กระทู้: 86
  • Reputation: -1
Signature cleanned by Admin