HỌC VIỆN CÔNG NGHỆ BƯU CHÍNH VIỄN THÔNGKHOA CÔNG NGHỆ THÔNG TIN 1 BỘ MÔN HỆ ĐIỀU HÀNH Bài thực hành số 3: Đọc và phân tích hệ thống file FAT sử dụng hàm đọc đĩa mức thấpGiảng viên hướng
Trang 1HỌC VIỆN CÔNG NGHỆ BƯU CHÍNH VIỄN THÔNG
KHOA CÔNG NGHỆ THÔNG TIN 1
BỘ MÔN HỆ ĐIỀU HÀNH
Bài thực hành số 3:
Đọc và phân tích hệ thống file FAT sử dụng hàm đọc đĩa mức thấpGiảng viên hướng dẫn: Đinh Trường Duy
Họ và tên sinh viên: Trần Văn Thanh
Mã sinh viên: B22DCCN787
Lớp: D22CQCN07-B
Nhóm: 05
Hà Nội – 2024
Trang 2I Chuẩn bị
- Cài đặt máy ảo
+ Bước 1: Cài đặt chương trình chạy máy ảo VMWare Player bằng cáchchạy file VMware-player-full-16.2.4.exe
+ Bước 2: Chạy chương trình máy ảo vừa cài xong Mở máy ảo đã tạosẵn bằng việc click vào nút Open a Virtual Machine Browse và chọn fileWindows 98 Fat16.vmx trong thư mục Virtual
+ Bước 3: Khởi động máy ảo, hệ điều hành sẽ hiện lên , đổi tên máy ảothành tên MSV+ Họ tên
Trang 3+ Bước 4: Download Turbo C++, giải nén , đưa vào thư mục TC trong ổ đĩa C
+ Bước 5: Khởi động Turbo C bằng lệnh C:\> TC
Trang 4+ Bước 6: Mở và chạy file FAT.CPP
Ấn F10 -> File -> Open
File FAT.CPP
Trang 5Thực hiện chạy File FAT.CPP : F10-> Run ( Alt+F9)
Trang 6II Nội dung thực hành
Bài 1: Đọc và in thông tin từ BOOT
- Khai báo thư viện
#include<iostream.h>
#include<stdio.h> // thực hiện các thao tác nhập xuất
Trang 7#include<conio.h> // nhập xuất trên cửa sổ console
#include<dos.h> // gọi các hàm liên quan đến hệ điều hành
#include<string.h> // hàm xử lý xâu
- Khai báo cấu trúc BOOT với FAT16
+ char jump[3] : lệnh JUMP chỉ thị cho CPU bỏ qua phần thông tin và nhảy tới thực hiện mã mồi của hệ điều hành, nếu đây là đĩa mồi của hệ điều hành
Trang 8+ char OEM[8] : Trường này lưu trữ thông tin nhận dạng hoặc nhà sảnxuất OEM (Original Equipment Manufacturer) của thiết bị gốc Thường
có độ dài là 8 bytes
+ int bytes_per_sector : Lưu trữ số byte trong mỗi sector Sector là đơn vị
cơ bản của việc lưu trữ trên đĩa cứng
+ char sectors_per_cluster : Số sector trong mỗi cluster, là đơn vị lưu trữ
cơ bản trong hệ thống tập tin FAT
+ int reserved : Dùng để lưu trữ số lượng sector được dành trước khi bắtđầu vùng dữ liệu
+ char FAT_cnt : Số lượng bảng FAT trên đĩa Đối với FAT16, thường là2
+ int ROOT_size : Kích thước của phần thư mục gốc được xác địnhbằng số lượng entry trong thư mục gốc
+ int total_sectors : Tổng số sector trong đĩa
+ char media : Xác định loại phương tiện lưu trữ (ví dụ: 0xF8 là đĩacứng)
+ int FAT_size : Kích thước của mỗi bảng FAT
+ int sectors_per_track : Số sector trên mỗi track của đĩa
+ int head_cnt : Số lượng đầu đọc/ghi trên đĩa
+ long hidden_sectors : Số lượng sector ẩn trước khi đĩa bắt đầu+ long total_sectors_long : Tổng số sector trên đĩa, sử dụng kiểu dữ liệu+ long char unknown[3] : Các trường không xác định
+ char serial : Số Serial của đĩa
+ char volume[11] : Tên của phân vùng
+ char FAT_type[8] : Loại hệ thống tập tin (ví dụ: FAT16)
+ char loader[448] : Mã mồi (bootstrap code) có độ dài 448 byte, đượcthực thi khi hệ điều hành được khởi động từ đĩa
+ char mark[2] : Dấu hiệu cuối cùng của 512-byte bootstrapsector, thường có giá trị là 0x55AA để xác nhận tính đúng đắn củasector
- Hàm in Boot
Trang 10- Kết quả trên Window98
Trang 11Bài 2: Đọc, phân tích, hiển thị nội dung bảng FAT
Trang 12- Giải thích
+Cấp phát không gian nhớ cho bảng FAT Không gian nhớđượctính bằngboot.FAT_size(kích thước FAT tính bằng sector – đối với FAT 12/16) * boot.bytes_per_sector(kích thước sector tính bằng bytes)
+ Hiển thị một số nội dung của bảng FAT: boot.FAT_size,boot.reserved(Số sector dành cho vùng đầu đĩa đến trước FAT)
+ Để đọc bảng FAT cũng sử dụng hàm đọc đĩa absread
+ Sau khi đọc bảng FAT thành công, sử dụng vòng lặp để duyệt tất cả ôtrong bảng FAT và in nội dung của nó
- Kết quả chạy trên Window98
Trang 13Bài 3: Đọc , phân tích , hiển thị ROOT
- Khai báo 1 Struct của ROOT
+ char name[8] : Lưu trữ tên của ROOT hay lưu trữ tên của mục trong thư mục gốc
+ char ext[3] : Lưu trữ phần mở rộng của tên file, thêm dấu trắng ở cuối nếu nó lớnhơn 3 bytes
+ char attr : Lưu trữ thuộc tính của mục, chẳng hạn như chỉ đọc, ẩn, hệ thống, thưmục,
+ char reserved[10] : Các trường dự trữ không xác định
+ char time[2] : thời gian tạo (giờ, phút, giây)
+ char date[2] : ngày tạo (ngày, tháng, năm)
+ int first_cluster : cluster đầu tiên của mục
+ long size : kích thước của ROOT
- Đọc , phân tích và hiển thị ROOT
- Đọc ROOT từ ổ đĩa D
Trang 14+ int num_byte= boot.ROOT_size *32 : Tính toán số byte cần để lưu trữ thông tintrong ROOT, giả sử mỗi mục trong phần thư mục chiếm 32byte
+ ROOT *root = (ROOT *)malloc(num_byte) : Cấp phát bộ nhớ động và kiểm tracấp phát có thành công hay không
+ If(root == NULL) return;
+ int num_sector = num_byte / boot.bytes_per_sector : Tính toán số lượng sectorcần để lưu trữ thông tin trong phần
Trang 15+ int root_begin = boot.reverved + boot.FAT_size * boot.FAT_cnt : Tính toán vịtrí bắt đầu của phần thư mục gốc (ROOT) trên đĩa dựa trên thông tin trong bảngBOOT.
+ res = absread(drive, num_sector, root_begin, (void *)root) : hàm đọc
ROOT
+ if(res != 0) : Kiểm tra xem việc đọc thông tin từ phần thư mục gốc có thành công hay không Nếu không, in ra thông báo lỗi và thoát khỏi hàm
- In thông tin 5 mục đầu tiên trong ROOT
- Kết quả hiển thị trên Window98
Trang 16Bài 4: Duyệt số thứ tự hoặc nội dung của các cluster của file cho trước
- Giải thích
+ Để duyệt các cluster của 1 file cho trước ta phải kiểm tra file đó
có tồn tại trong root Sử dụng hàm strcmp(str, filename) để kiểm tra+ Nếu file đó tồn tại đặt first_cluster = root[i].cluster
+ Sử dụng vòng lặp while để duyệt với điều kiện cur < 0xFFF8 với curban đầu bằng first_cluster Qua từng vòng lặp cur sẽ bằng giá trị của cluster tiếp theo
Bài 5: Viết đoạn chương trình in ra nội dung giống như câu lệnh dir
- Viết 2 hàm getBit() và hàm convert() Hàm getBit có chức năng chuyển 1
kí tự kiểu char sang 1 dãy bit nhị phân Hàm convert có chức năng biến đổi 1 dãy nhị phân sang một số kiểu int
Trang 17- Trong hàm Main()
+ In tên của tệp tin , thư mục
- In ra kiểu của tệp tin, thư mục
Trang 18- In ra kích thước của tệp tin/thư mục theo đúng định dạng
+ Chuyển đổi kích thức của tệp tin/thư mục từ kiểu long sang kiểu chuỗi
kí tự n
+ Nếu chiều dài của n chia hết cho 3 thì in ra dấu ‘,’ sau các vị trí chia dưcho 3 bằng 2, ngoại trừ 2 vị trí đầu và cuối
+ Nếu chiều dài của n chia cho 3 dư 1 thì in ra dấu ‘,’ sau các vị trí chia
dư cho 3 bằng 0, ngoại trừ 2 vị trí đầu và cuối
+ Nếu chiều dài của n chia cho 3 dư 2 thì in ra dấu ‘,’ sau các vị trí chia
dư cho 3 bằng 1, ngoại trừ 2 vị trí đầu và cuối
Trang 19- In ra ngày, tháng, năm tạo tệp tin/ thư mục theo đúng định dạng
- Sử dụng 3 dãy kí tự char s[16], s1[8], s2[8] và hàm getBit() để chuyển đổi kí tự sang dãy bit
- Dãy kí tự s1 sẽ lưu dãy bit sau khi chuyển đối từ kí tự củaroot[i].date[0], s2 sẽ lưu dãy bit sau khi chuyển đổi từ kí từcủa root[i].date[1], s sẽ lưu dãy bit được nối từ s1 và s2
- Sau khi chuyển đổi, sử dụng hàm convert để tính ngày,tháng, năm Bit 0-4: ngày(1-31),Bit 5-8: tháng (1-12), Bit9-15: năm + 1994
- In ra giờ và phút tạo tệp tin/ thư mục theo đúng định dạng
Trang 20- Chuyển đổi root[i].time[0] và root[i].time[1] sang dãy bit Sau đó tính giờ, phút, giây Bit 0-4: giây/2, Bit 5-10: phút, Bit 11-15: giờ
- Kết quả trên TC
Trang 21Phần 1.1:
- Hàm chuyển một số kiểu unsigned int sang biểu diễn nhị phân
- In nội dung của 150 ô FAT đầu tiên của ổ đĩa D ra màn hình từ đó in ra bảng bit của 150 khối nhớ của ổ D
Trang 22- Kết quả trên Window98
Phần 1.2:
Trang 23- Đọc FAT vào bộ nhớ tại địa chỉ << int fat >>
- In các cluster thuộc file đó và in ra tên của File đó trong ROOT
- Kết quả trên Window98
Trang 24Phần 1.3:
- Đọc thư mục gốc của hệ thống file FAT16 sử dụng tên file độ dài tối đa 8
ký tự được đọc vào bộ nhớ tại địa chỉ << void root >>∗
- In tên và độ dài các file trong thư mục gốc
Trang 25- Kết quả trên Window98
Trang 26- Tìm một file có tên cho trước trong thư mục gốc và cho biết file đó cóbao nhiêu khối nhớ ( File “README”)
Kết quả trên Window98