1. Trang chủ
  2. » Luận Văn - Báo Cáo

Báo cáo thực hành học phần hệ Điều hành f

14 0 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Báo cáo thực hành học phần: Hệ điều hành
Tác giả Nguyễn Tiến Hiệp
Người hướng dẫn Đinh Văn Tuân
Trường học University of Information Technology
Chuyên ngành Computer Science
Thể loại báo cáo
Định dạng
Số trang 14
Dung lượng 396,79 KB

Nội dung

Bài 1: Đọc và in thông tin từ BOOT- Khai báo thư viện: #include #include // thực hiện các thao tác nhập xuất #include // nhập xuất trên cửa sổ console #include // gọi các hàm liên quan đ

Trang 1

BÁO CÁO THỰC HÀNH Học phần: Hệ điều hành Giảng viên: Đinh Văn Tuân

Sinh viên: Nguyễn Tiến Hiệp

Mã sinh viên: B21DCCN344

Nhóm học phần: 08

I Chuẩn bị

- Cài đặt máy ảo, đĩa ảo trên thẻ nhớ USB, lập trình các bài tập đọc FAT

- Chuẩn bị USB: Copy lên thẻ nhớ USB các file: Chương trình cài đặt phần mềm VMWare Player, File chứa máy ảo Windows 98 và ổ đĩa FAT 16 Windows 98 Fat16.vmx do giảng viên cung cấp

- 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ách chạ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ạo sẵn bằng việc click vào nút Open a Virtual Machine Browse và chọn file Windows 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 Khởi động Turbo C, mở và chạy file FAT.cpp Tùy chỉnh file FAT.cpp để đọc thêm thông tin và làm bài tập

II Nội dung thực hành

Dựa vào nội dung được học trên lớp viết chương trình C/C++ để thực hiện các nội dung sau:

Trang 2

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

#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 Bootsector với FAT16:

struct BOOT

{ 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 char OEM[8];// Trường này lưu trữ thông tin nhận dạng hoặc nhà sản xuấ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 định bằ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à đĩa cứ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

Trang 3

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, được thự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 bootstrap sector, thường có giá trị là 0x55AA để xác nhận tính đúng đắn của sector

};

- Hàm in Boot: void main(){ int drive = 3;

//A=0, B=1, C=2, D=3 …

//Đọc boot sector từ ổ đĩa D

BOOT boot; //khởi tạo 1 struct

int res = absread(drive, 1, 0, &boot); //Hàm cho phép đọc BOOT if(res != 0){ //bằng 0 đọc được, khác 0 không đọc được

printf(“Cannot read boot sector\n”); return; }

printf(“Reading disk parameters\n”);//thông báo đang đọc các tham

số của ổ đĩa

printf(“ -\n”);

printf(“Sector size: %d\n”, boot.bytes_per_sector);//in thông tin

về kích thước của sector printf(“FAT type:”);

// duyệt qua từng ký tự trong mảng FAT type của cấu trúc BOOT int i;

for(i=0; i<8;i++)

// In ra màn hình mỗi ký tự trong mảng FAT Type Dòng này sẽ được lặp qua 8 lần (đối với FAT16)

printf(“%c”, boot.FAT_type[i]);

}

Bài 2: Đọc, phân tích, hiển thị nội dung boot sector với bảng FAT

int main(){

Trang 4

//Đọc bảng FAT16 từ ổ đĩa

D

unsigned int *fat = (unsigned int *)malloc (boot.FAT_size

* boot.bytes_per_sector); \\Cấp phát bộ nhớ động để lưu trữ bảng FAT16

\\Kiểm tra xem việc cấp phát bộ nhớ có thành công hay không Nếu không đủ bộ nhớ, in ra thông báo lỗi và kết thúc chương trình

if (fat == NULL){ printf(“Not enough

memory\n”); return; }

printf(“\n\n”; printf(“Reading FAT16

parameters\n”);

printf(“ -\n”);

printf(“FAT size: %d \n”, boot.FAT_size);\\ In ra kích thước của mỗi bảng FAT16

printf(“Reserved: %d \n”, boot.reserved); \\In ra số lượng sector được dành trước khi bắt đầu vùng dữ liệu (reserved)

res = absread(drive, boot.FAT_size, boot.reserved, fat); \\Đọc bảng

FAT16

//Kiểm tra xem việc đọc bảng FAT16 có thành công hay không Nếu không, in ra thông báo lỗi và kết thúc chương trình

if(res != 0){ printf(“Cannot read

FAT\n”); return;

}

//in ra màn hình giá trị của 15 ô đầu tiên trong bảng

FAT printf(“Content of first 15 FAT cells:”); for(i=0;

i<15;i++) printf(“%u “, fat[i]);

//Đếm số lượng Clusters không sử dụng trong 100 Clusters đầu tiên int free_count = 0; //khởi tạo biến đếm

//Duyệt qua 98 Clusters đầu tiên (2-99), do Clusters thứ 0 và 1 không được sử dụng

for(i=2; i < 100;i++){ //first 2 clusters are not used

if(fast[i] == 0) free_count++; //kiểm tra

}

Trang 5

printf(“\n”); printf(“Number of free clusters from first

100 clusters:”); printf(“%d\n”, free_count);

tin

}

//in ra màn hình các Cluster của file bắt đầu từ Cluster thứ n

unsigned int n = 5; //khởi tạo n=5

unsigned int cur = n; //khởi tạo biến duyệt qua các Cluster của tập printf(“Clusters of a file from %u:

“,n); while(cur < 0xFFF8){

printf(“->%u”, cur); cur = fat[cur];

}

Giải thích:

+ Cấp phát không gian nhớ cho bảng FAT Không gian nhớ được tính bằng boot.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 15 ô đầu tiên trong bảng FAT và in nội dung của nó

Bài 3: Đọc, phân tích, hiển thị ROOT

- Khai báo 1 struct của ROOT:

struct 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

Trang 6

trắng ở cuối nếu nó lớn hơ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:

int main(){

//Đọc ROOT từ ổ đĩa D

printf(“\n\n”); printf(“Reading ROOT

information:\n”);

printf(“ -\n”);

//tính toán số byte cần để lưu trữ thông tin trong ROOT, giả sử mỗi mục trong phần thư mục chiếm 32byte int num_byte

= boot.ROOT_size *32; //sizeof(ROOT)

//cấp phát bộ nhớ động và kiểm tra cấp phát có thành công hay không

ROOT *root = (ROOT *)malloc(num_byte);

If(root == NULL) return;

//Tính toán số lượng sector cần để lưu trữ thông tin trong phần thư mục gốc (ROOT) int num_sector = num_byte /

boot.bytes_per_sector;

//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ảng BOOT

int root_begin = boot.reverved + boot.FAT_size * boot.FAT_cnt; res = absread(drive, num_sector, root_begin, (void *)root);//hàm đọc ROOT

Trang 7

//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 if(res != 0){ printf(:\n Cannot read

ROOT \n); return;

}

//In ra 3 mục đầu tiên trong ROOT

printf(“3 first items of root:\n”);

for(i=0;i<3;i++){

//Kiểm tra xem tên của mục có bắt đầu bằng dấu cách hay

không Nếu có, bỏ qua mục này và tiếp tục với mục tiếp theo if(root[i].name[0] == ‘ ‘) continue;

//In ra tên của mục đó cho đến khi gặp dấu cách hoặc hết độ dài cho phép

for(int j=0; j<0 && root[i].name[j] != ‘ ‘; j++)

printf(“%c”, root[i].name[j]);

printf(“\t”);

//In ra màn hình số cluster đầu tiên và kích thước của mục printf(“%d \t %ld\n”, root[i].first_cluster, root[i].size); }

}

* Giải thích:

+ Cấp phát động không gian cho ROOT với không gian nhớ được tính bằng công thức: num_byte = boot.ROOT_size(Số khoản mục tối đa trong ROOT) * 32

+ Để đọc ROOT cần tính tổng số sector cần đọc theo công thức: num_sector = num_byte / boot.bytes_per_sector, vị trí sector bắt đầu được tính theo công thức: root_begin = boot.reserved + boot.FAT_size * boot.FAT_cnt(số bảng FAT)

+ Sử dụng hàm absread để đọc ROOT

Trang 8

+ Sau khi đọc xong sử dụng vòng lặp for để đọc 3 khoản mục đầu tiên trong đó có name(tên khoản mục), first_cluster(Cluster của khoản mục), size(kích thước khoản mục)

Bài 4: Duyệt số thứ tự hoặc nội dung các cluster của file cho trước int main(){

//Tìm một tập tin với tên được cung cấp trong biến char filename[ ] printf(“\n”);

//in ra các cluster thuộc về một tập tin cụ thể

printf(“Clusters belong to file readme:”);

int k; char str[9]; int first_cluster = -1;

for(i=0; i< boot.ROOT_size; i++){

//Sao chép root[i].name vào biến str để tạo thành chuỗi ký tự có ký

tự kết thúc null

for(k=0;k<8 && root[i].name[k] != ‘ ‘; k++)

str[k] = root[i].name[k];

str[k] = 0;

//Nhập tên tập tin từ người dùng để tìm kiếm

char filename[8]; printf(“\n Enter a file

name:”); scanf(“%s”, filename);

if(strcmp(str, filename) == 0){

first_cluster = root[i].first_cluster;

break;

}

}

// In ra các cluster thuộc về tập tin if(first_cluster >= 0){ // Kiểm tra xem đã tìm thấy tập tin hay chưa

// Nếu đã tìm thấy tập tin, in ra màn hình các cluster thuộc về tập tin đó bằng cách duyệt qua bảng FAT

cur = first_cluster;

while(cur < 0xFFF8){

Trang 9

printf(“%u “,cur); cur =

fat[cur];

}

}

// Giải phóng bộ nhớ đã cấp phát cho mảng ROOT và fat.getchar()

để đợi một ký t t bàn phím trước khi thoát chự ừ ương trình free(root);

free(rat);

getchar();

}

* 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 cur ban đầ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 giống câu lệnh dir

a Hàm chuyển đổi giá trị của ký tự x thành một mảng nhị phân 8 bit và lưu vào mảng s

void getbit(char x, char s[8]){

for( int i=0;i<8;i++){

//Kiểm tra xem bit thứ i của x có bật hay không ?

//Nếu bit đó bật, kết quả của biểu thức sẽ khác 0 và điều kiện trong toán tử điều kiện ? : sẽ trả về giá trị 1

//Ngược lại, nếu bit đó tắt, kết quả của biểu thức sẽ là 0 và giá trị trả về sẽ là 0

s[i]=(x &(1<<i)) ?1:0;

Trang 10

}

b Hàm chuyển đổi một nhị phân thành 1 số nguyên

//Nhận đầu vào là một con trỏ s trỏ tới một mảng ký tự, và hai số nguyên i

và j, đại diện cho các chỉ số mảng int convert(char *s, int i, int j){

//sum:tổng của các giá trị nhị phân

//pow:giá trị của lũy thừa 2 int

sum=0,pow=1; for( int

k=i;k<=j;k++){

//Giá trị nhị phân được nhân với giá trị lũy thừa pow và cọng vào biến sum sum+=pow * (s[k]-‘0’); //trừ đi ‘0’ để chuyển đổi từ ký tự thành

số pow*=2; //nhân với 2 để tính đến vị trí nhị phân tiếp theo

} return

sum;

}

c In ra nội dung giống lệnh DIR

Hàm Dir được dùng để hiển thị danh sách các tệp và thư mục trong mục hiện tại.Mỗi đối tượng hiển thị tên, kích thước,kiểu,ngày tạo, thể loại printf(" -DIR -\n");

for( i=0;i<6;i++){ //do chỉ có 6 tệp

int j=0;

// In ra tên của tệp tin/ thư mục

for( j=0;j<8;j++)

{ printf("%c",root[i].name[j]

);

}

printf("\t");

//In ra kiểu của tệp tin/ thư mục

for( j=0;j<3;j++)

{ printf("%c",root[i].ext[j]

);

}

printf("\t");

//In ra kích thước của tệp tin/thư mục theo đúng định dạng

char n[20];

//Chuyển đổi kích thức của tệp tin/thư mục từ kiểu long sang

Trang 11

kiểu chuỗi kí tự n.

sprintf(n,"%ld",root[i].size);

//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

if( strlen(n) %3==0){ for( j=0;j<strlen(n);j++){ if( j!=0 && j!=strlen(n)-1 && j%3==2){

printf("%c,",n[j]);

} else{

printf("%c",n[j]);

} }

//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

}else if( strlen(n) %3==1){ for(

j=0;j<strlen(n);j++){ if(

j!=strlen(n)-1 && j%3==0){

printf("%c,",n[j]);

} else { printf("%c",n[j]);

} }

//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

}else { for( j=0;j<strlen(n);j++)

{ if( j!=strlen(n) -1&& j

%3==1) { printf("%c,",n[j]);

} else { printf("%c",n[j]);

} }

}

printf("\t");

//In ra ngày, tháng, năm tạo tệp tin/ thư mục theo đúng định dạng

char s[16],s1[8],s2[8];

//chuyển đổi ngày và tháng tạo file về dạng một mảng nhị

Trang 12

getbit(root[i].date[0],s1);

//chuyển đổi năm tạo file về dạng một mảng nhị phân getbit(root[i].date[1],s2);

//Lưu các giá trị nhị phân của ngày, tháng, năm tạo file vào cùng trong một mảng

for( j=0;j<8;j++){

s[j]=s1[j];

s[j+8]=s2[j];

}

//Sử dụng hàm convert để chuyển đổi mảng nhị phân thành số nguyên

int ngay=convert(s,0,4);//Ngày từ bit 0 đến bit 4

int thang=convert(s,5,8); //Tháng từ bit 5 đến bit 8 int

nam=convert(s,9,15); //Năm từ bit 9 đến bit 15 nam+=1993;

//để hiển thị năm 2023 //In ra theo định dạng dd-mm-yyyy if(

ngay<10){ printf("0%d-",ngay);

}else{

printf("%d-",ngay);

} if( thang < 10){

printf("0%d-",thang);

}else{

printf("%d-",thang);

}

printf("%d\t",nam%100);

//In ra giờ và phút tạo tệp tin/ thư mục theo đúng định dạng

//chuyển đổi giờ tạo file về dạng một mảng nhị phân getbit(root[i].time[0],s1);

//chuyển đổi giờ tạo file về dạng một mảng nhị phân getbit(root[i].time[1],s2);

//Lưu các giá trị nhị phân của giờ, phút tạo file

vào cùng trong một mảng

for( j=0;j<8;j++)

{ s[j]=s1[j];

s[j+8]=s2[j];

Trang 13

//Sử dụng hàm convert để chuyển đổi mảng nhị phân thành số nguyên

int gio=convert(s,11,15);//Giờ từ bit 11 đến 15

int phut=convert(s,5,10);//Phút từ bit 5 đến 10

//In ra theo đúng định dạng: giờ:phút(a hoặc p)

if( gio<12){

printf("%d:",gio);

}else{

printf("%d:",gio-12);

} if( phut <10){

printf("0%d",phut);

}else{

printf("%d",phut);

} if( gio<12) printf("a");else

printf("p");

printf("\n");

}

* Giải thích:

+ 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

+ Duyệt qua 7 thư mục hoặc file có trong root

+ Ban đầu duyệt qua tên thư mục hay file đó với độ dài 8 byte kiểu char

+ Duyệt kích thước file hay thư mục đó và in đúng định dạng có dấu ‘,’ ngăn cách khi kích thước có nhiều hơn 3 chữ số + 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

Ngày đăng: 15/02/2025, 22:17

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN