Tải bản đầy đủ (.pdf) (63 trang)

Tìm hiểu cơ chế viết Driver cho thiết bị chuẩn USB trên Linux. Ứng dụng viết Driver cho máy điện tim 3 đạo trình

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (39.53 MB, 63 trang )

TÓM TẮT NỘI DUNG ĐỒ ÁN TỐT NGHIỆP
Ngày nay chuẩn truyền thông USB luôn là lựa chọn hàng đầu cho giải pháp kết nối tới máy
tính của các nhà phát triển. Tuy nhiên việc viết một Driver lại không hề đơn giản với một kỹ
sư công nghệ thông tin, do việc này đòi hỏi phải có cái nhìn bao quát về hệ thống: từ mức
firmware trên thiết bị tới kiến trúc hệ điều hành trên máy tính.
Trong đề tài này em đã tìm hiểu các kiến thức liên quan và làm tài liệu về các nội dung đã tìm
hiểu được, nhằm đưa ra một quy trình mà theo đó một kỹ sư công nghệ thông tin có thể áp
dụng để viết thành công một USB Device Driver. Các nội dung được trình bày từ mức tổng
quan về hệ thống Linux, chuẩn truyền thông USB tới mức chi tiết về các hàm cần cài đặt khi
viết một USB Device Driver. Đồ án cũng bao gồm việc ứng dụng viết Driver cho máy điện
tim 3 đạo trình và chương trình hiển thị sóng điện tim trên nền tảng Qt, sau đó chuyển toàn bộ
chương trình xuống chạy kiểm thử trên nền tảng Linux nhúng (KIT FriendlyARM).

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

1


ABSTRACT OF THESIS
Nowaday, USB Connection is always the first choice of many hardware developers when
connecting their devices to computers. However, writing successfully a driver is not simple to
an IT engineer because this need the engineer to have knowledge of system architecture,
hardware design and firmware of devices.
In scope of this project, I have researched relative contents and then documentized all those
contents. My destination is giving a process so an engineer can follow that to write
successfully his USB device driver. The contents in this project are represented from general
about Linux architecture, USB protocol standard to detail of defined functions in a USB
device driver. This project also included writing the driver of 3-lead electrocardiogram
machine and a Qt base program to show electrocardiogram signal. The last, I ported the driver
and the Qt base program to an Embeded Linux KIT (FriendlyARM) to testing.


Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

2


MỤC LỤC
TÓM TẮT NỘI DUNG ĐỒ ÁN TỐT NGHIỆP ..................................................................... 1
ABSTRACT OF THESIS ....................................................................................................... 2
MỤC LỤC ............................................................................................................................. 3
DANH MỤC HÌNH ẢNH ...................................................................................................... 5
DANH MỤC CÁC THUẬT NGỮ, TỪ VIẾT TẮT ................................................................ 6
MỞ ĐẦU ............................................................................................................................... 7
PHẦN 1. CÁC KIẾN THỨC TỔNG QUAN .......................................................................... 9
CHƯƠNG 1. KIẾN TRÚC HỆ ĐIỀU HÀNH LINUX.
GIỚI THIỆU VỀ LẬP TRÌNH MÔ-ĐUN NHÂN TRÊN LINUX .......................................... 9
1.1. Tổng quan kiến trúc hệ điều hành Linux ...................................................................... 9
1.2. Hệ thống tệp tin trên hệ điều hành Linux ................................................................... 10
1.3. Cơ chế quản lý thiết bị trên hệ điều hành Linux ......................................................... 11
1.3.1. Khái niệm Device Driver. .................................................................................. 11
1.3.2. Định danh thiết bị trên hệ điều hành Linux......................................................... 12
1.3.3. Device File. Đường dẫn /dev trong hệ thống tệp tin ........................................... 13
1.3.4. Cơ chế tạo ra tệp tin thiết bị tự động sử dụng udev ............................................. 16
1.4. Giới thiệu về lập trình mô-đun nhân trên Linux ......................................................... 18
1.4.1. Khái niệm mô-đun nhân trong Linux ................................................................. 18
1.4.2. Chương trình HelloWorld. ................................................................................. 20
CHƯƠNG 2. HỆ THỐNG USB TRÊN LINUX ................................................................... 24
2.1. Tổng quan về giao thức usb ....................................................................................... 24
2.1.1. Kiến trúc bus ..................................................................................................... 24
2.1.2. Các lớp thiết bị usb ............................................................................................ 24
2.1.3. Các khái niệm Endpoint, Interface, Configuration .............................................. 27

2.2. Hệ thống USB trên hệ điều hành Linux ..................................................................... 29
2.2.1. Mô hình phân lớp hệ thống USB trên Linux ....................................................... 29
2.2.2. Cách thức giao tiếp trong hệ thống USB ............................................................ 30
PHẦN 2. THỰC HIỆN VIẾT USB DEVICE DRIVER TRÊN LINUX ................................ 36
CHƯƠNG 3. TRÌNH TỰ VIẾT USB DEVICE DRIVER TRÊN LINUX ............................. 36
3.1. Tìm hiểu phần cứng .................................................................................................. 36
3.2. Khai báo cấu trúc dữ liệu liên quan tới thiết bị........................................................... 36
3.3. Khai báo danh sách các thiết bị có thể được điều khiển bởi Driver ............................ 37
3.4. Đăng kí và hủy đăng kí USB Device Driver .............................................................. 37
3.5. Hàm thăm dò............................................................................................................. 39
3.5.1. Truy nhập các thông tin về Endpoint .................................................................. 39
3.5.2. Lưu lại các thông tin đã truy nhập và cấp phát ................................................... 40
3.5.3. Đăng kí lớp thiết bị ............................................................................................ 41
3.6. Hàm ngắt kết nối thiết bị ........................................................................................... 42
Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

3


3.7. Các hàm mở / đọc / ghi thiết bị .................................................................................. 43
3.7.1. Hành động mở tệp tin ........................................................................................ 43
3.7.2. Hành động đọc / ghi........................................................................................... 44
CHƯƠNG 4. VIẾT DRIVER CHO MÁY ĐIỆN TIM 3 ĐẠO TRÌNH ................................. 45
4.1. Viết Driver cho máy điện tim 3 đạo trình .................................................................. 45
4.1.1. Tìm hiểu phần cứng ........................................................................................... 45
4.1.2. Khai báo các cấu trúc dữ liệu và các biến toàn cục cần thiết ............................... 45
4.1.3. Khai báo danh sách thiết bị được hỗ trợ bởi Driver ............................................ 46
4.1.4. Đăng kí và gỡ bỏ driver khỏi hệ thống ............................................................... 48
4.1.5. Thăm dò thiết bị................................................................................................. 48
4.1.6. Cài đặt các hành động mở, đọc, ghi thiết bị ........................................................ 50

4.2. Chương trình hiển thị tín hiệu điện tim trên nền tảng Qt ............................................ 54
4.2.1. Xây dựng giao diện ............................................................................................ 54
4.2.2. Sử dụng Driver đã viết để giao tiếp với máy điện tim ......................................... 55
4.3. Chạy kiểm thử trên KIT FriendlyARM ...................................................................... 57
4.3.1. Biên dịch lại Driver ........................................................................................... 57
4.3.2. Chuyển Driver và chương trình hiển thị tín hiệu xuống KIT ............................... 58
4.4. Kết quả chương trình ................................................................................................. 58
KẾT LUẬN.......................................................................................................................... 62
TÀI LIỆU THAM KHẢO .................................................................................................... 63

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

4


DANH MỤC HÌNH ẢNH
Hình 1. Mô hình kiến trúc hệ thống Linux .............................................................................. 9
Hình 2. Hệ thống tệp tin trong Linux .................................................................................... 10
Hình 3. Số hiệu loại thiết bị và số hiệu thiết bị riêng lẻ ......................................................... 12
Hình 4. Các số hiệu loại thiết bị đã được nhân Linux gán cố định ......................................... 13
Hình 5. Các thiết bị được tìm thấy tại đường dẫn /dev .......................................................... 14
Hình 6. Tạo tệp tin thiết bị mới ............................................................................................. 15
Hình 7. Các mô-đun được tải vào nhân ................................................................................. 19
Hình 8. Kết quả biên dịch hello-1.c ...................................................................................... 21
Hình 9. Kiểm tra thông tin mô-đun hello-1.ko ...................................................................... 22
Hình 10. Kiểm tra mô-đun hello-1.ko đã được tải lên ........................................................... 22
Hình 11. Nhật ký hệ thống khi thêm và gỡ bỏ mô-đun hello-1.ko ......................................... 23
Hình 12. Mô hình bus USB .................................................................................................. 24
Hình 13. Mối quan hệ Endpoint, Interface, Configuration ..................................................... 28
Hình 14. Mô hình phân lớp hệ thống USB trên Linux ........................................................... 29

Hình 15. Chu trình của một URB.......................................................................................... 30
Hình 16. Lưu đồ hàm thăm dò và hàm ngắt kết nối thiết bị ................................................... 43
Hình 17. Kết quả chạy lệnh lsusb.......................................................................................... 45
Hình 18. Lệnh lsusb hiển thị thông tin phần cứng ................................................................. 47
Hình 19. Kết nối mạch với máy tính ..................................................................................... 58
Hình 20. Tệp tin thiết bị liên kết với Driver của máy điện tim............................................... 59
Hình 21. Kiểm tra các mô-đun đã được tải vào nhân hệ điều hành ........................................ 59
Hình 22. Chương trình Qt hiển thị tín hiệu điện tim .............................................................. 60
Hình 23. Kết quả khi chạy trên Kit FriendlyARM................................................................. 61

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

5


DANH MỤC CÁC THUẬT NGỮ, TỪ VIẾT TẮT
Thuật ngữ / Từ viết tắt
USB
USB Host
USB Device
USB Core
URB
Driver / Device Driver
Device Number
Major Number
Minor Number
Configuration
Interface
Endpoint
Bulk Endpoint


Từ nguyên gốc
Universal Serial Bus

USB Request Block

Interrupt Endpoint
Isochronous Endpoint
Control Endpoint
HID
Mass Storage Device
Audio Device
Embedded Linux
Kernel
User/Kernel Mode
User/Kernel Space
Linux Kernel Module
Firmware

Human Interface Device

Dịch nghĩa
Bus nối tiếp đa năng
Máy chủ USB
Thiết bị USB
Lõi hệ thống USB
Khối yêu cầu USB
Trình điều khiển thiết bị
Số hiệu xác định thiết bị
Số hiệu loại thiết bị

Số hiệu thiết bị riêng lẻ
Cấu hình
Giao diện
Điểm cuối
Điểm cuối kiểu truyền theo
khối
Điểm cuối kiểu truyền theo
ngắt
Điểm cuối kiểu truyền
đẳng thời
Điểm cuối kiểu truyền điều
khiển
Thiết bị giao tiếp người
dùng
Thiết bị lưu trữ
Thiết bị âm thanh
Linux nhúng
Nhân hệ điều hành
Chế độ người dùng / nhân
Không gian người dùng /
nhân
Mô-đun nhân Linux
Vi chương trình

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

6


MỞ ĐẦU

Ngày nay trong các thiết bị ngoại vi, chuẩn truyền thông USB đã trở nên rất phổ
biến. Sự đa năng và ưu điểm về tốc độ, khoảng cách, khả năng chịu lỗi đã giúp cho kết
nối USB được rất nhiều nhà phát triển phần cứng lựa chọn cho thiết bị của mình. Ta có
thể bắt gặp kết nối USB ở hầu hết các loại điện thoại di động thông thường, điện thoại
thông minh, máy tính bảng, chuột, bàn phím, loa… Các ứng dụng người dùng muốn
giao tiếp với thiết bị phải thông qua các Driver. Các Driver có tác dụng làm ẩn đi sự
phức tạp và đa dạng về kiến trúc phần cứng với ứng dụng người dùng. Trên hệ điều
hành Linux, các Driver cho một số lớp thiết bị USB phổ biến như HID, Mass Storage,
Audio… đã được xây dựng sẵn trong nhân hệ điều hành. Tuy nhiên nếu phát triển một
thiết bị mới chưa được hệ điều hành hỗ trợ thì nhà phát triển phải tự xây dựng Driver
cho thiết bị của mình. Công việc này khá khó khăn với đa số lập trình viên do vừa phải
hiểu được nguyên lý của phần cứng, vừa phải biết lập trình hệ thống trên Linux. Được
sự gợi ý và giúp đỡ của thầy hướng dẫn em đã thực hiện đề tài: “Tìm hiểu cơ chế viết
Driver cho thiết bị chuẩn USB trên Linux. Ứng dụng viết Driver cho máy điện tim
3 đạo trình”.
Thông qua quyển đồ án này em xin gửi lời cảm ơn tới các thầy cô trong trường Đại học
Bách Khoa Hà Nội, các thầy cô trong Viện công nghệ thông tin và truyền thông, các
thầy cô trong bộ môn Kỹ thuật máy tính đã truyền đạt cho em những kiến thức quý báu
trong suốt 5 năm qua. Đặc biệt, em xin bày tỏ sự biết ơn sâu sắc tới thầy Phạm Văn
Thuận, người đã tận tình hướng dẫn và theo sát em trong quá trình em thực hiện đề tài
này. Cuối cùng em xin gửi lời cảm ơn tới các bạn trong lớp Kỹ thuật máy tính K52 đã
có những góp ý chân thành cho đề tài.
Bố cục của báo cáo tốt nghiệp này như sau:
Mở đầu
Trong phần này em giới thiệu chung về đề tài, lý do chọn đề tài, bố cục bản báo
cáo và lời cảm ơn.
Phần 1. Các kiến thức tổng quan
Chương 1. Kiến trúc hệ điều hành Linux. Giới thiệu về lập trình mô-đun
nhân trên Linux
Chương này sẽ giới thiệu về kiến trúc hệ điều hành Linux, trong đó nhấn mạnh

về chức năng quản lý thiết bị và Driver trên hệ thống Linux. Chương này cũng

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

7


giới thiệu về lập trình mô-đun trong không gian nhân hệ điều hành, đây bước
đầu tiên cần nắm được để viết một USB Device Driver.
Chương 2. Hệ thống USB trên Linux
Chương này cung cấp một số kiến thức cơ bản về chuẩn truyền thông USB và
mô hình điều khiển các thiết bị USB trên hệ thống Linux.
Phần 2. Thực hiện viết USB Device Driver trên Linux
Chương 3. Trình tự viết USB Device Driver trên Linux
Trong chương này em giới thiệu một cách chi tiết về các bước để cài đặt một
USB Device Driver.
Chương 4. Viết Driver cho máy điện tim 3 đạo trình
Phần này em sẽ tập trung vào việc cài đặt cụ thể Driver cho máy điện tim 3 đạo
trình và một chương trình hiển thị tín hiệu điện tim trên nền tảng Qt. Sau đó em
thực hiện chuyển toàn bộ chương trình xuống KIT FriendlyARM chạy kiểm thử.
Kết luận
Phần này sẽ đánh giá những kết quả đã đạt được, những điểm chưa đạt được và
hướng phát triển nhằm hoàn thiện hơn chương trình.

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

8


PHẦN 1. CÁC KIẾN THỨC TỔNG QUAN

CHƯƠNG 1. KIẾN TRÚC HỆ ĐIỀU HÀNH LINUX. GIỚI THIỆU VỀ
LẬP TRÌNH MÔ-ĐUN NHÂN TRÊN LINUX
1.1. Tổng quan kiến trúc hệ điều hành Linux
Linux thực thi ở hai chế độ: chế độ người dùng (user mode) và chế độ nhân
(kernel mode), tương ứng với hai chế độ trên là hai không gian nhớ trên bộ nhớ chính:
không gian người dùng (user space) và không gian nhân (kernel space).
Không gian người dùng là vùng không gian trên bộ nhớ mà các tiến trình người dùng
được thực thi. Không gian này được bảo vệ.
 Hệ thống ngăn chặn việc một tiến trình giao tiếp với một tiến trình khác.
 Chỉ các tiến trình nhân mới có thể truy nhập tới một tiến trình người dùng.
Không gian nhân là vùng không gian trong bộ nhớ nơi mà các tiến trình nhân thực thi.
Người dùng chỉ có thể truy nhập tới vùng bộ nhớ này thông qua các lời gọi hệ thống.
Trong không gian nhân, hệ điều hành có các chức năng chính sau:






Quản lý bộ nhớ (Memory Management)
Quản lý tiến trình (Process Management)
Quản lý thiết bị (Device Management)
Quản lý hệ thống tệp tin (File System Management)
Quản lý giao tiếp mạng (Network Interface Management)

Mô hình kiến trúc hệ điều hành Linux như sau:

Hình 1. Mô hình kiến trúc hệ thống Linux
Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính


9


Chế độ nhân được hỗ trợ bởi kiến trúc của CPU (bởi các lệnh máy đặc biệt) và nó ngăn
người dùng truy nhập vào phần cứng một cách trực tiếp. Trong chế độ người dùng các
chương trình hệ thống, các trình ứng dụng sử dụng lại các dịch vụ của hệ điều hành.
Việc sử dụng lại các dịch vụ này được thực hiện thông qua các lời gọi hệ thống
(system calls).
Khi một lời gọi hệ thống được thực thi, các tham số tới lời gọi sẽ được truyền từ không
gian người dùng tới không gian nhân. Các lời gọi hệ thống sẽ chuyển chế độ chạy máy
từ chế độ người dùng sang chế độ nhân, và điều khiển được chuyển cho hệ điều hành.
Sau khi thực hiện xong lời gọi hệ thống, điều khiển trả lại cho chương trình của người
dùng.
1.2. Hệ thống tệp tin trên hệ điều hành Linux
Hệ thống tệp tin (File System) của Linux được đặc tả như sau:







Cấu trúc cấp bậc (cây thư mục)
Cách xử lý nhất quán của tệp (chuỗi các byte – byte stream)
Khả năng tạo và hủy tệp (tạo mới, xóa)
Tính tăng trưởng động của tệp (thêm bớt, cắt dán)
Khả năng bảo vệ dữ liệu của tệp (bởi các kiểu thuộc tính như quyền truy xuất)
Xử lý các thiết bị ngoại vi như xử lý các tệp

Cây thư mục của hệ thống tệp tin trong Linux như sau:


Hình 2. Hệ thống tệp tin trong Linux

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

10


Hệ thống tệp tin được tổ chức như một cây, bắt đầu từ một nút đơn gọi là root, được
biểu diễn là “/”, từ đó có các thư mục khác tạo thành các nhánh của cây, trong các
nhánh có thể có các nhánh con khác. Dưới các nhánh sẽ là tệp tin. Tệp tin có thể là tệp
bình thường (regular file) hoặc cũng có thể là tệp đặc biệt (special file). Tệp được truy
nhập thông qua đường dẫn (path name). Đường dẫn đầy đủ, hay đường dẫn tuyệt đối,
bắt đầu bởi dấu / và nó xác định tệp bằng cách đi từ root qua cấu trúc cây thư mục theo
các nhánh chỉ thị trong đường dẫn. Ví dụ trong hình trên, có: /usr/src/cmds/date.c là
đường dẫn tuyệt đối tới tệp date.c. Đường dẫn tương đối là đường dẫn tính từ thư mục
hiện tại.
Các chương trình trong Linux khi thao tác với tệp không có khái niệm về định dạng
(format) của tệp. Do đó, tên các tệp tin không có phần đuôi mở rộng như trên
Windows. Các tệp tin được lưu trữ như một dòng các byte, tùy theo từng chương trình
xử lý mà sử dụng các byte đó cho các mục đích khác nhau rồi đưa kết quả đầu ra tương
ứng.
Các tệp tin được sắp xếp trong các thư mục, trong mỗi thư mục có thể có các thư mục
con. Thư mục (directory) trong Linux cũng là một loại tệp, hệ thống xử lý thư mục
cũng bằng các dòng byte, nhưng dữ liệu ở đây là tên các tệp trong thư mục đó và có
khuôn dạng định sẵn sao cho hệ điều hành và một số chương trình (ví dụ ls) có thể
nhận ra được các tệp trong thư mục.
Đối với người dùng, Linux xử lý các thiết bị như thể các tệp tin (tệp tin thiết bị - device
file). Các thiết bị được mô tả bởi các tệp tin thiết bị và nằm ở một nhánh của thư mục
(/dev). Các chương trình truy nhập các thiết bị bằng các cú pháp giống như khi truy

xuất tệp tin thông thường (open – read – write – ioctl).
1.3. Cơ chế quản lý thiết bị trên hệ điều hành Linux
1.3.1. Khái niệm Device Driver.
Cũng như hầu hết các hệ thống khác, Linux giao tiếp với các thiết bị phần cứng
thông qua các thành phần phần mềm được mô-đun hóa (modularized) gọi là trình điều
khiển thiết bị (Device Driver). Một Device Driver sẽ ẩn đi các giao thức giao tiếp phần
cứng cụ thể đối với hệ điều hành. Các Driver cho phép hệ điều hành giao tiếp với thiết
bị thông qua một giao diện đã được chuẩn hóa.
Trên Linux, các thiết bị được phân thành hai dạng chính:
 Thiết bị kiểu kí tự (Character Device): là các thiết bị phần cứng mà đọc và ghi
dữ liệu theo một dòng các byte nối tiếp. Ví dụ: các thiết bị usb, cổng COM…
Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

11


 Thiết bị kiểu khối (Block Device): là các thiết bị phần cứng mà đọc và ghi dữ
liệu theo các khối có kích thước cố định. Khác với các thiết bị kiểu kí tự, thiết bị
kiểu khối cung cấp khả năng truy nhật ngẫu nhiên tới dữ liệu được lưu trữ trên
thiết bị. Ví dụ: ổ đĩa cứng…
1.3.2. Định danh thiết bị trên hệ điều hành Linux
Khi thiết bị được kết nối vào hệ thống, nếu có Driver được chỉ định điều khiển
thiết bị thì Linux sẽ định danh cho thiết bị đó. Linux định danh các thiết bị bằng các số
hiệu thiết bị (Device Numbers), gồm: số hiệu loại thiết bị (Major Number) và số hiệu
thiết bị riêng lẻ (Minor Number).
Major Number xác định xem Driver nào sẽ được sử dụng để quản lý thiết bị đó. Sự
tương ứng giữa Major Number với Driver là cố định và là một phần của mã nguồn
nhân Linux. Các thiết bị có cùng Major Number sẽ do cùng một Driver điều khiển.
Một số Major Number đã được gán cố định cho hầu hết các thiết bị phổ biến. (Danh
sách các thiết bị này có thể thấy trong tài liệu hướng dẫn của các bản phát hành nhân

Linux (Documentation/devices.txt) (hình 4)).
Minor Number xác định các thiết bị hoặc các thành phần thiết bị riêng lẻ được điều
khiển bởi một Driver. Ý nghĩa của số hiệu này còn tùy thuộc vào từng Driver cụ thể.
Ví dụ:
Trong Linux, bật terminal, gõ lệnh sau:
ls –l /dev/sda*
Kết quả:

Hình 3. Số hiệu loại thiết bị và số hiệu thiết bị riêng lẻ

Major Number của ổ đĩa cứng chuẩn SCSI là 8, các Minor Number có thể là 0, 1, 2, 5
để xác định từng phân vùng cụ thể trên ổ đĩa này.

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

12


Hình 4. Các số hiệu loại thiết bị đã được nhân Linux gán cố định
1.3.3. Device File. Đường dẫn /dev trong hệ thống tệp tin
A. Device File
Linux cung cấp một cơ chế để các tiến trình giao tiếp với Driver (cũng là giao
tiếp với các thiết bị phần cứng tương ứng) thông qua các tệp tin đặc biệt – các tệp tin
thiết bị (Device File). Các tiến trình có thể thực hiện các thao tác: mở, đọc, ghi trên các
tệp tin thiết bị này giống như với các tệp tin thông thường.
Các tệp tin thiết bị không phải là các tệp tin thông thường, chúng không thể hiện một
vùng dữ liệu trên đĩa. Thay vào đó, các dữ liệu đọc từ, ghi tới một tệp tin thiết bị sẽ
được giao tiếp tới trình điều khiển thiết bị tương ứng, và từ đó giao tiếp tới các thiết bị
phía dưới.


Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

13


B. Đường dẫn /dev
Hệ thống Linux bao gồm một đường dẫn /dev mà tại đó chứa đầy đủ các tệp tin
thiết bị tương ứng với tất cả các thiết bị mà Linux hỗ trợ. Các phần tử trong /dev có tên
được chuẩn hóa tương ứng với Major Number.
Để kiểm tra thông tin các phần tử trong /dev ta sử dụng lệnh:
ls –l /dev
Các thông tin được hiển thị bao gồm:
 Kí tự đầu tiên xác định xem thiết bị là thiết bị kiểu kí tự hay thiết bị kiểu khối,
‘c’ cho thiết bị kiểu kí tự và ‘b’ cho thiết bị kiểu khối.
 Sau đó là các kí tự cho biết quyền đối với tệp tin thiết bị này.
 Theo sau người sở hữu và nhóm người sở hữu là hai số, chính là số hiệu loại
thiết bị và số hiệu thiết bị riêng lẻ.
 Theo sau là thời gian tạo tệp tin thiết bị
 Cuối cùng là tên của tệp tin thiết bị

Hình 5. Các thiết bị được tìm thấy tại đường dẫn /dev

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

14


C. Tạo ra một tệp tin thiết bị mới
Để tạo ra một tệp tin thiết bị mới trong /dev ta sử dụng lệnh mknod. Việc tạo ra
một tệp tin thiết bị mới không có nghĩa là các trình điều khiển thiết bị tương ứng hay

các thiết bị phần cứng có thể sử dụng được ngay. Mỗi tệp tin thiết bị chỉ đóng vai trò
như một cổng thông tin để giao tiếp với các trình điều khiển thiết bị tương ứng. Chỉ các
tiến trình của siêu – người dùng (superuser) mới có quyền để tạo ra các tệp tin này.
Các tham số truyền vào lệnh mknod: tham số đầu tiên là đường dẫn tới tệp tin trong hệ
thống tệp tin, tham số thứ hai là một kí tự xác định kiểu thiết bị (‘c’ cho thiết bị kiểu kí
tự, ‘b’ cho thiết bị kiểu khối), tham số thứ ba và thứ tư chính là số hiệu loại thiết bị và
số hiệu thiết bị riêng lẻ của thiết bị.
Ví dụ:
Bật terminal, đăng nhập với quyền root, sau đó sử dụng lệnh mknod đã nói trên để tạo
ra một tệp tin thiết bị có tên là mydevice, Major Number là 6, Minor Number là 0.

Hình 6. Tạo tệp tin thiết bị mới
D. Thao tác với tệp tin thiết bị
Đối với các thiết bị kiểu kí tự, các hành động thao giao tiếp với thiết bị thực chất
là thao tác tới các tệp tin. Các hành động đơn giản chỉ là: mở, đọc, ghi tới các tệp tin
thiết bị tương ứng.
Ví dụ:
int fd = open(“/dev/mydevice”, O_WRONLY);
read(fd, buffer, buffer_length);
write(fd, buffer, buffer_length);
close(fd);

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

15


1.3.4. Cơ chế tạo ra tệp tin thiết bị tự động sử dụng udev
A. Giới thiệu về udev
Trong hệ thống Linux, đường dẫn /dev chứa các tệp tin thiết bị. Mỗi tệp tin thiết

bị liên kết với một thiết bị của hệ thống, thiết bị này có thể tồn tại hoặc không tồn tại
trong hệ thống. Các tiến trình trong không gian người dùng có thể sử dụng các tệp tin
thiết bị này để giao tiếp với các thiết bị phần cứng. Đường dẫn /dev trong truyền thống
thường chứa mọi tệp tin thiết bị liên kết tới mọi thiết bị có thể xuất hiện trong hệ thống.
Điều này làm cho kích thước của đường dẫn /dev rất lớn.
Udev là một cách để quản lý đường dẫn /dev. Udev giúp tạo ra một tệp tin thiết bị một
cách rất mềm dẻo và mạnh mẽ. Đường dẫn /dev lúc này không cần phải chứa hết tất cả
các tệp tin thiết bị mà Linux hỗ trợ. Khi một thiết bị được kết nối vào hệ thống, udev sẽ
giúp tạo ra một tệp tin thiết bị liên kết với thiết bị đó. Để làm việc này udev dựa trên
những thông tin được cung cấp bởi sysfs (một hệ thống tệp tin ảo được cung cấp trong
phiên bản nhân 2.6, sysfs xuất ra các thông tin về thiết bị và trình điều khiển thiết bị tới
không gian người dùng) và các quy tắc (rules) do người dùng cung cấp.
Một số tính năng của udev:
 Đổi tên một tệp tin thiết bị
 Cung cấp một tên luân phiên / liên tục cho một tệp tin thiết bị bằng cách tạo ra
một liên kết tới tệp tin thiết bị mặc định đó
 Đặt tên một tệp tin thiết bị dựa trên kết quả của một chương trình nào đó
 Thay đổi quyền và sở hữu của một tệp tin thiết bị
 Khởi chạy một đoạn mã (script) khi một tệp tin thiết bị được tạo hoặc được xóa
(khi một thiết được được kết nối hoặc gỡ bỏ ra khỏi hệ thống)
 Đổi tên các giao diện mạng
B. Các quy tắc viết udev
1, Các tệp tin quy tắc
Khi quyết định cách đặt tên cho một thiết bị và các hành động cần thực hiện, udev đọc
một tập các tệp tin quy tắc. Các tệp tin này được lưu giữ trong đường dẫn
/etc/udev/rules.d và chúng có kết thúc với .rules
Trong các tệp tin quy tắc này, những dòng bắt đầu với kí tự # là những dòng chú thích,
udev sẽ bỏ qua những dòng này. Mỗi một dòng không trống là một quy tắc. Mỗi quy
tắc chỉ được viết trên một dòng, không được dàn thành nhiều dòng.
Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính


16


Một thiết bị có thể được móc nối với nhiều hơn một quy tắc. Các quy tắc này thậm chí
có thể được viết ở các tệp tin quy tắc khác nhau thì chúng vẫn được áp dụng. Ví dụ: có
hai quy tắc cùng móc nối tới một thiết bị, trong đó tạo ra hai tệp tin thiết bị khác tên
nhau cho thiết bị này, cả hai tệp tin này đều được tạo ra.
2, Cú pháp của quy tắc
Mỗi quy tắc được cấu trúc từ một tập các cặp khóa – giá trị (key – value), phân tách
bởi dấu phảy (,). Các khóa móc nối (match keys) là các điều kiện để xác định xem quy
tắc sẽ được áp dụng cho thiết bị nào. Khi tất cả các khóa móc nối trong quy tắc tương
ứng với thiết bị đã được đáp ứng, quy tắc đó sẽ được áp dụng và các hành động của các
khóa chỉ định (assignment keys) sẽ được gọi. Mỗi quy tắc sẽ bao gồm ít nhất một khóa
móc nối và một khóa chỉ định.
Ví dụ:
KERNEL==“hda”, NAME=“my_spare_disk”
Ví dụ trên gồm một khóa móc nối là KERNEL, và một khóa chỉ định là NAME. Khóa
móc nối liên quan tới giá trị của nó sử dụng toán tử so sánh (==), khóa chỉ định liên
quan tới giá trị của nó sử dụng toán tử gán (=).
3, Các quy tắc cơ bản
Udev cung cấp vài loại khóa móc nối khác nhau được sử dụng để viết các quy tắc.
 KERNEL: móc nối với những tên thiết bị quy định trong nhân
 SUBSYSTEM: móc nối tới hệ thống con (subsystem) của thiết bị
 DRIVER: móc nối tới tên của trình điều khiển thiết bị dùng cho thiết bị này.
Một số khóa chỉ định:
 NAME: tên sẽ được sử dụng cho tệp tin thiết bị
 SYMLINK: danh sách các liên kết được sử dụng như các tên thay thế cho tệp
tin thiết bị
Quay lại ví dụ trước:

KERNEL==“hda”, NAME=“my_spare_disk”
Quy tắc này có nghĩa là: móc nối tới thiết bị có tên thể hiện trong nhân Linux là hda và
tạo ra tệp tin thiết bị liên kết với nó có tên là my_spare_disk. Như vậy tệp tin thiết bị
được tạo ra có đường dẫn là /dev/my_spare_disk
Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

17


4, Sử dụng udev để khởi chạy một chương trình
Sử dụng khóa chỉ định RUN ta có thể khởi chạy một chương trình.
Ví dụ:
KERNEL==“sda”, RUN+=“/usr/bin/my_program”
Quy tắc trên có tác dụng là: khi một thiết bị có tên mặc định trong nhân là sda được kết
nối tới hệ thống thì khởi chạy chương trình /usr/bin/my_program
Khóa chỉ định này rất hữu dụng, nó sẽ giúp ta tải trình điều khiển thiết bị cần thiết và
thực hiện móc nối thiết bị với trình điều khiển thiết bị đó.
1.4. Giới thiệu về lập trình mô-đun nhân trên Linux
1.4.1. Khái niệm mô-đun nhân trong Linux
Một mô-đun nhân là một đoạn mã có thể được tải lên hoặc gỡ bỏ (load / unload)
khỏi nhân tùy theo yêu cầu. Chúng giúp mở rộng các chức năng của nhân mà không
cần phải khởi động lại hệ thống.
Ví dụ: trình điều khiển thiết bị là một loại mô-đun, chúng cho phép nhân Linux truy
cập tới các thiết bị được kết nối tới hệ thống. Nếu không có các mô-đun, chúng ta sẽ
phải xây dựng nhân nguyên khối chứa sẵn tất cả các chức năng. Việc này sẽ làm tăng
kích thước của nhân, và cần phải khởi động lại hệ thống mỗi khi thêm chức năng mới
vào ảnh nhân (kernel image).
Để kiểm tra các mô-đun đã được tải vào nhân, ta sử dụng lệnh lsmod, lệnh này sẽ đọc
các thông tin trong tệp tin /proc/modules


Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

18


Hình 7. Các mô-đun được tải vào nhân

Vậy một mô-đun được tải vào nhân như thế nào? Khi nhân cần một tính năng không có
sẵn trong ảnh nhân, tiến trình quản lý mô-đun nhân sẽ thực thi lệnh modprobe để tải
mô-đun cần thiết vào. modprobe nhận tham số vào là một xâu, theo một trong hai
dạng:
 Tên mô-đun, ví dụ: datn_driver hoặc soft
 Một định danh chung hơn, ví dụ: char-major-10-30
Nếu modprobe được truyền vào một định danh chung, trước hết nó tìm kiếm
xâu đó trong tệp tin /etc/modprobe.conf, nếu nó tìm thấy một dòng như:
alias char-major-10-30 softdog
Nó sẽ biết rằng định danh chung đó trỏ tới mô-đun softdog.
Tiếp theo, modprobe tìm kiếm trong tệp tin /lib/modules/‘version’/modules.dep để tìm
xem mô-đun cần tải lên có đòi hỏi mô-đun nào khác được tải lên trước hay không.
modprobe sẽ sử dụng lệnh insmod để tải các mô-đun phụ thuộc vào nhân trước, sau đó
sẽ tải mô-đun yêu cầu vào nhân.

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

19


Ví dụ: nhân Linux cần mô-đun msdos.ko, mô-đun này lại đòi hỏi mô-đun fat.ko được
tải lên nhân trước. Để thực hiện việc tải msdos.ko vào nhân, ta có thể thực hiện một
trong hai cách sau:

insmod /lib/modules/2.6.32-40-generic/kernel/fs/fat/fat.ko
insmod /lib/modules/2.6.32-40-generic/kernel/fs/msdos/msdos.ko
hoặc
modprobe msdos

Lệnh insmod yêu cầu truyền vào một tên đầy đủ tới mô-đun, và nó thực hiện theo đúng
thứ tự lệnh.
Các mô-đun nhân trên Linux có tên kết thúc bằng .ko, ví dụ: msdos.ko, usbhid.ko
1.4.2. Chương trình HelloWorld.
A. Mã nguồn chương trình hello-1.c
/*
* hello-1.c - The simplest kernel module.
*/
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
int init_module(void)
{
printk(KERN_INFO "Hello world 1.\n");
/*
* A non 0 return means init_module failed;
module can't be loaded.
*/
return 0;
}
void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.\n");
}

B. Phân tích chương trình

Các mô-đun nhân có ít nhất hai hàm, một hàm khởi tạo là init_module() được
gọi khi mô-đun được tải vào nhân, và một hàm kết thúc là cleanup_module() được gọi
ngay trước khi mô-đun được gỡ bỏ khỏi nhân. Thông thường, init_module() để đăng kí
một thẻ quản (handler) cho một đối tượng nào đó với nhân, hoặc là thay thế chính hàm
này do nhân cung cấp (thường để làm một việc gì đó, sau đó mới gọi tới hàm gốc của
Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

20


nhân). Hàm cleanup_module() làm công việc ngược lại với hàm init_module(). Nó
giúp cho mô-đun được gỡ bỏ khỏi nhân một cách an toàn.
Về các tệp tin tiêu đề, mọi mô-đun nhân đều cần bao gồm linux/module.h. Tệp tiêu đề
linux/kernel.h được bao gồm vào nhằm sử dụng hàm printk().
Hàm printk() không có tác dụng hiển thị thông tin cho người dùng, nó nhằm mục đích
ghi nhật ký hệ thống (system logging). Mỗi một lệnh printk() có một độ ưu tiên. Có 8
mức độ ưu tiên được định nghĩa trong linux/kernel.h. Trong ví dụ hello-1.c độ ưu tiên
là KERN_INFO. Nếu mức độ ưu tiên không được chỉ định, độ ưu tiên mặc định
DEFAULT_MESSAGE_LOGLEVEL sẽ được sử dụng.
C. Biên dịch
Để biên dịch cho các mô-đun nhân chúng ta sẽ tạo ra các Makefile. Trong tài
liệu hướng dẫn của mã nguồn nhân Linux: linux/Documentation/kbuild/modules.txt có
hướng dẫn chi tiết cách viết Makefile. Dưới đây là Makefile của chương trình hello-1.c
obj-m += hello-1.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Trong terminal, di chuyển con trỏ tới đường dẫn chứa thư mục chứa mã nguồn và

Makefile, gõ lệnh make

Hình 8. Kết quả biên dịch hello-1.c
Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

21


Để kiểm tra thông tin của một mô-đun, ta sử dụng lệnh modinfo

Hình 9. Kiểm tra thông tin mô-đun hello-1.ko

D. Thêm mô-đun hello-1.ko vào nhân
Sử dụng lệnh insmod để thêm mô-đun hello-1.ko vào nhân.

Hình 10. Kiểm tra mô-đun hello-1.ko đã được tải lên

Để gỡ bỏ mô-đun, dùng lệnh: rmmod hello_1
Để kiểm tra thông tin ghi nhật ký hệ thống (do lệnh printk()) ta vào: System ->
Administration -> Log File Viewer, ở cột bên trái chọn syslog -> <ngày hiện tại>

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

22


Hình 11. Nhật ký hệ thống khi thêm và gỡ bỏ mô-đun hello-1.ko

Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính


23


CHƯƠNG 2. HỆ THỐNG USB TRÊN LINUX
2.1. Tổng quan về giao thức usb
USB (Universal Serial Bus) là bus nối tiếp đa năng cho phép các thiết bị đầu
cuối giao tiếp với máy tính chủ (Host Computer).
2.1.1. Kiến trúc bus
Về mặt kết nối vật lý USB là một kiến trúc tầng sao. Tại trung tâm của mỗi sao
là một hub, các thiết bị được cắm vào hub. Mỗi hub thường cho 2, 4 hoặc 7 thiết bị
cắm vào đồng thời. Tại một thời điểm chỉ có một thiết bị có thể giao tiếp với trình điều
khiển trên máy chủ (host controller).
Với 7 bit địa chỉ, ngoài máy chủ USB ra nó có thể quản lý tối đa 127 thiết bị ngoại vi.
Hình sau sẽ minh hoạ kiến trúc của USB.

Hình 12. Mô hình bus USB
2.1.2. Các lớp thiết bị usb
A. Các thành phần của một lớp đặc tả thiết bị USB
Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính

24


Một đặc tả lớp thiết bị định nghĩa số lượng và loại các điểm cuối (endpoint) bắt
buộc cũng như tuỳ chọn mà các thiết bị trong lớp đó có thể có. Một đặc tả lớp cũng có
thể định nghĩa hoặc đặt tên các định dạng dữ liệu được truyền trên bus. Một vài đặc tả
lớp định nghĩa các ứng dụng của dữ liệu đang được truyền, điều này cho phép Host
biết cách sử dụng dữ liệu mà nó nhận được. Một vài lớp thiết bị sử dụng USB để
truyền dữ liệu trong một định dạng được định nghĩa bởi một giao diện khác (ví dụ các
lệnh của giao diện SCSI được sử dụng bởi các thiết bị lưu trữ thứ cấp (mass-storage

device)). Một đặc tả lớp cũng có thể định nghĩa các giá trị cho các mục trong các bộ
mô tả chuẩn.
B. Các lớp thiết bị được định nghĩa
Các lớp thiết bị được định nghĩa cho giao tiếp USB:
 Thiết bị âm thanh (Audio): Lớp thiết bị âm thanh chính là lớp các thiết bị gửi và
nhận dữ liệu âm thanh. Dữ liệu âm thanh có thể là tiếng nói được mã hoá, nhạc
hay bất kỳ một loại âm thanh nào khác. Các thiết bị thuộc lớp thiết bị âm thanh
có thể sử dụng kiểu truyền đẳng thời cho luồng âm thanh hoặc kiểu truyền khối
cho dữ liệu đã được mã hoá bằng giao thức MIDI (Musical Instrument Digital
Interface)
 Thiết bị giao diện thẻ thông minh: Thẻ thông minh là các loại thẻ quen thuộc
được sử dụng cho việc gọi điện thoại, thẻ ra vào, trả cước cầu đường, bảo hiểm
y tế, giải mã cho các bộ thu truyền hình vệ tinh và nhiều các ứng dụng khác,
những ứng dụng này yêu cầu một khối lượng thông tin nhỏ hoặc trung bình với
sự truy cập dữ liệu lưu trong thẻ một cách dễ dàng. Mỗi thẻ là một module bao
gồm bộ nhớ và thường thêm một CPU. Nhiều thẻ cho phép cập nhật nội dung
của chúng để thay đổi một số thông tin ví dụ như giá trị tiền trong thẻ tín dụng
hay mã của thẻ. Để truy cập một thẻ thông minh, bạn kết nối nó với thiết bị giao
diện thẻ thông minh (CCID-Chip Card Interface Device) thường bằng cách nhét
thẻ vào khe đọc hoặc soi nó trước các bộ đọc đối với loại thẻ không cần tiếp
xúc. USB định nghĩa lớp thiết bị giao diện thẻ thông minh vì có một số thiết bị
giao diện thẻ thông minh (CCID) sử dụng giao diện USB để giao tiếp với máy
tính.
 Lớp các thiết bị truyền thông: Lớp các thiết bị truyền thông bao gồm hai loại
thiết bị chính là: thiết bị thoại và các thiết bị mạng tốc độ trung bình. Thiết bị
thoại bao gồm điện thoại tương tự, modem tương tự, Các bộ thích nghi đầu cuối
ISDN và điện thoại số. Các thiết bị mạng bao gồm modem ADSL, modem điện
tín, 10BASE-T Ethernet adapter và hub
Sinh viên thực hiện: Mai Đình Đương – SHSV: 20070820 – Khóa K52 – Lớp: Kỹ thuật máy tính


25


×