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

Báo cáo đồ án môn học hệ điều hành lab02 system calls

23 7 0

Đ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

Theo định nghĩa của Silberschatz "Hệ điều hành là chương trình quản lý phần cứng máy tính." Tuy nhiên, quan điểm về một hệ điều hành còn tùy thuộc nhiều vào nhu cầu và góc nhìn của người

Trang 1

TRƯỜNG ĐẠI HỌC KHOA HỌC TỰ NHIÊN KHOA CÔNG NGHỆ THÔNG TIN

BÁO CÁO ĐỒ ÁN MÔN HỌC HỆ ĐIỀU HÀNH

Lab02 : System calls Giảng viên lý thuyết : Thầy Trần Trung Dũng

Lớp: 21CNTN

THÀNH PHỐ HỒ CHÍ MINH, NGÀY 1 THÁNG 11 NĂM 2023

Trang 2

Lời nói đầu

Hệ điều hành là một bài toán mở và không có một định nghĩa thật chuẩn xác Theo định nghĩa của Silberschatz "Hệ điều hành là chương trình quản lý phần cứng máy tính." Tuy nhiên, quan điểm về một hệ điều hành còn tùy thuộc nhiều vào nhu cầu và góc nhìn của người dùng và hệ thống Quan điểm thứ nhất cho rằng hệ điều hành là một bộ điều phối tài nguyên Ở quan điểm này, hệ điều hành nắm giữ các tài nguyên, nó có nhiệm vụ cấp phát và thu hồi các tài nguyên này cho người dùng luân phiên nhau.

Hình 1: Một số hệ điều hành hiện nay

Trong quan điểm thứ hai, hệ điều hành là một máy ảo Nghĩa là hệ điều hành cung cấp cho mỗi người dùng một máy ảo Máy ảo này có thể giống với máy tính vật lý thật, có thể là một máy tính hoàn toàn khác, có thể là một máy tính mạnh hơn Điều quan trọng là máy ảo tạo cho người dùng tin rằng họ sỡ hữu riêng tài các tài nguyên phần cứng cần thiết cho nhu cầu của mình Một góc nhìn khác nữa là xem hệ điều hành như một bộ giúp chia sẻ tài nguyên chung Hệ điều hành chịu trách nhiệm phân chia, phòng chống xâm phạm tài nguyên giữa các người dùng Đồng thời quản lý sự cộng tác của người dùng trong việc sử dụng chung nguồn tài nguyên hạn hẹp Đây cũng là góc nhìn kinh tế, vì chúng ta không thể mua sắm hết tất cả các tài nguyên cần thiết.

Với đồ án này, nhóm em tiến hành thực hiện trên Hệ điều hànhUbuntu Bài tập đã được hoàn thiện đầy đủ và báo cáo chi tiết ở các phần sau.

Trang 3

Mục lục

2.1 Cài đặt môi trường 5

2.2 Kiểm tra cài đặt 5

3 Thực hiện đồ án 6 3.1 Using gdb 6

3.1.1 Thực hiện cài đặt theo yêu cầu 6

3.1.2 Trả lời các câu hỏi của đề bài 6

3.2 System call tracing 11

3.3.4 Test toàn bộ bài tập 21

4 Phân công công việc của các thành viên 22 5 Tài liệu tham khảo 22 Danh sách hình vẽ 1 Một số hệ điều hành hiện nay 1

2 Xv6 4

3 Cài đặt Xv6 - labs - 2023 trên Ubuntu 5

4 Kiểm tra cài đặt trên Ubuntu 5

5 Các bước thực hiện yêu cầu bài tập 6

6 Kết quả trả về sau khi thực hiện 7

7 Number syscall lưu trữ trong thanh ghi a7 8

8 Kết quả kiểm thử bài tập Lab02 21

Danh sách bảng 1 Bảng phân công thành viên 22

Trang 4

Thông tin chung về đồ án học tập Môi trường phát triển: Hệ điều hành Ubuntu Thông tin chi tiết:

•Project được giao trong link •Báo cáo về đồ án.

Lời cảm ơn

Những kiến thức về môn họcHệ Điều Hànhđược ứng dụng trong đồ án của chúng em được thầyTrần Trung Dũng, Lê Giang Thanh, Nguyễn Thanh Quân giảng dạy rất nhiệt tình, tâm huyết Chúng em xin cảm ơn các thầy vì đồ án này nói riêng và vì những kiến thức mà các thầy đã cung cấp nói chung.

Ngoài ra, nhóm cũng đã tham khảo từ nhiều trang web như GitHub và trang web chính thứcXv6 Những thuật toán, những ý kiến giải đáp trên các diễn đàn trên đã góp phần giúp nhóm thực hiện đồ án này.

Thành phố Hồ Chí Minh, ngày 14 tháng 10 năm 2023

Trang 5

1 Giới thiệu về Xv6

Xv6 là một khóa học hệ điều hành phát triển vào mùa hè năm 2006 Xv6 là một hệ điều hành thí nghiệm mã nguồn mở dựa trên Unix, được phát triển tại Đại học MIT Nó được thiết kế nhằm mục đích giáo dục và nghiên cứu về hệ điều hành, giúp sinh viên và nhà nghiên cứu hiểu rõ hơn về cấu trúc và hoạt động của một hệ điều hành.

Xv6 được xây dựng dựa trên hệ điều hành Unix V6 của Bell Labs, một trong những phiên bản Unix ban đầu Nó được viết bằng ngôn ngữ C và mã nguồn của nó có thể được tìm thấy trên GitHub để mọi người có thể tìm hiểu và đóng góp vào dự án.

Mục tiêu chính của Xv6 là cung cấp một hệ điều hành đơn giản, nhẹ và dễ hiểu Nó bao gồm một số tính năng cơ bản của hệ điều hành như quản lý tiến trình, bộ nhớ, tệp tin và giao tiếp qua hệ thống Xv6 cung cấp một giao diện dòng lệnh đơn giản cho người dùng và hỗ trợ một số lệnh cơ bản như ls, cat, rm và cp.

Xv6 đã được sử dụng rộng rãi trong các khóa học về hệ điều hành và nghiên cứu tại nhiều trường đại học trên thế giới Việc nắm vững và tìm hiểu về Xv6 có thể giúp sinh viên và nhà nghiên cứu hiểu sâu hơn về cách hoạt động của hệ điều hành và phát triển kỹ năng lập trình hệ thống Chi tiết có thể tìm thấy trong link sau : Xv6.

Hình 2: Xv6

Trang 6

2 Mô tả cụ thể

2.1 Cài đặt môi trường.

Trước khi vào bài tập, chúng ta cần phải cài đặt môi trường và các thư viện cần thiết cho đồ án Phần cài đặt này có thể tìm thấy trong phần Tools Used, tùy vào hệ điều hành đang sử dụng mà có các cài đặt khác nhau Ở đây nhóm chúng em sử dụng hệ điều hànhUbuntu.

Hình 3: Cài đặt Xv6 - labs - 2023 trên Ubuntu

2.2 Kiểm tra cài đặt

Sau khi tiến hành, cài đặt thành công môi trường, các phiên bản củaQEMU, GNU, Sau đó, chúng em tiến hành kiểm thử và và bắt đầu thực hiện đồ án.

Hình 4: Kiểm tra cài đặt trên Ubuntu

Trang 7

3 Thực hiện đồ án

3.1 Using gdb

Bài tập này giúp tìm hiểu cách hoạt động và cách sử dụng gdb Giống vớiLab1, thầy Lê Giang Thanh đã giới thiệu.

3.1.1 Thực hiện cài đặt theo yêu cầu

Hình 5: Các bước thực hiện yêu cầu bài tập.

Kết quả sau khi thực hiện đầy đủ các lệnh trên được mô tả trong hình 6: 3.1.2 Trả lời các câu hỏi của đề bài

Câu trả lời được lưu trữ trong file answers-syscall.txt.

Question : Looking at the backtrace output, which function called syscall? Trả lời : Kết quả cho biết syscall được gọi bởiusertrap, nó được chỉ ra trong output củabacktrace.

Trang 8

Hình 6: Kết quả trả về sau khi thực hiện.

Trang 9

Question : What is the value of p->trapframe->a7 and what does that value represent? (Hint: look user/initcode.S, the first user program xv6 starts.)?

Chúng em đã thực hiện gõ n 2 lần để giúp chostruct proc *p = myproc()có thể thực thi Sau đó gỡ lệnhp /x *pvà xem kết quả.

Thực hiện kiểm tra giá trịp->trapframe->a7 Kết quả đầu ra như sau : (gdb) p p->trapframe->a7

$2 = 7

Dựa vào đoạn code tronguser/initcode.S, ta có thể thấy rằng number syscall được chạy lưu trữ trong thanh ghia7.

Hình 7: Number syscall lưu trữ trong thanh ghi a7.

Trang 10

Trong bài này, number syscall là 15, dựa vào filekernel/syscall.h thì number syscall này đại diện choSYS_exec.

// System call numbers

#define SYS_fork 1 #define SYS_dup 10 #define SYS_exit 2 #define SYS_dup 10 #define SYS_wait 3 #define SYS_sbrk 12 #define SYS_pipe 4 #define SYS_sleep 13 #define SYS_read 5 #define SYS_uptime 14 #define SYS_kill 6 #define SYS_open 15 #define SYS_exec 7 #define SYS_write 16 #define SYS_fstat 8 #define SYS_mknod 17 #define SYS_chdir 9 #define SYS_unlink 18 #define SYS_link 19 #define SYS_mkdir 20

Theo hướng dẫn đặc quyền RISC-V, bit SPP cho biết mức đặc quyền mà privilege level đang thực thi trước khi vào chế độ giám sát Khi trap được đặt, SPP được đặt thành 0 nếu trap bắt nguồn từ user mode hoặc 1 nếu ngược lại Khi một lệnh SRET (xem Phần 3.3.2) được thực thi để trả về từ bộ xử lý trap, mức đặc quyền được đặt thành user mode nếu bit SPP là 0 hoặc chế độ giám sát nếu bit SPP là 1; SPP sau đó được đặt thành 0.

Như chúng ta có thể thấy, giá trị của bit SPP là 0, cho biết mức đặc quyền trước khi vào kernel cho lệnh gọi hệ thống là user mode.

Khi thực hiện sửa câu lệnhnum = p->trapframe->a7; thành câu lệnh khác là num = *(int *)0;.

Question : Write down the assembly instruction the kernel is panicing at Which register corresponds to the varialable num?

Thực hiện câu lệnhmake qemu cho kết quả như sau:

Trang 11

sepc cho biết địa chỉ của mã nơi mà kernel gặp sự cố Chúng ta có thể tìm kiếm mã này trongkernel/ kernel.asm.

num = * (int *) 0;

8000204e: 00002683 lw a3, (zero) #0 0 <_entry-0x80000000> if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {

8000206c: c789 beqz a5,80002076 <syscall+0x3c> // Use num to lookup the system call function for num, call it, // and store its return value in p->trapframe->a0

Dựa vào đoạn code trên ta có thể thấy, chính sự thay thế câu lệnh đã gây ra lỗi cho kernel và tương ứng cho lệnh lỗi này trong assembly làlw a3,0(zero).

Question : Why does the kernel crash? Hint: look at figure 3-3 in the text; is address 0 mapped in the kernel address space? Is that confirmed by the value in scause above? (See description of scause in RISC-V privileged

Thread 2 hit Breakpoint 1, syscall () at kernel/syscall.c:126

Nếu chúng ta nhập vào n thì panic sẽ diễn ra một lần nữa Do đó, chúng ta có thể chấm dứt quá trình và kiểm tra giá trị của thanh ghi scause bằng cách:

p $scause $4 = 13

Theo hướng dẫn của RISC-V, giá trị 13 ở đây biểu thị lỗi trang tải Đặc biệt, đã xảy ra lỗi khi tải dữ liệu từ địa chỉ bộ nhớ 0 vào s2 Như chúng ta có thể thấy trong sách giáo trình, địa chỉ 0 không ánh xạ tới không gian kernel; đúng hơn, nó bắt đầu ở địa chỉ ảo 0x80000000.

Question : What is the name of the binary that was running when the kernel paniced? What is its process id (pid)?

Trang 12

Có thể thấy rằng chương trình người dùng này là initcode, đây là quy trình đầu tiên trong xv6 Việc in cấu trúc proc sẽ cho phép người ta kiểm tra thông tin bổ sung về quy trình này:

(gdb) p *p

$2 = {lock = {locked = 1, name = 0x800081b8 "proc", cpu = 0x80008a50 <cpus+256>}, state = RUNNING, chan = 0x0, killed = 0, xstate = 0, pid = 1, parent = 0x0, kstack = 274877894656, sz = 4096, pagetable = 0x87f73000, trapframe = 0x87f74000, context = {ra = 2147488960, sp = 274877898352, s0 = 274877898400, s1 = 2147519824, s2 = 2147518752, s3 = 1, s4 = 274877898448, s5 = 2147544024, s6 = 3, s7 = 2147588592, s8 = 1, s9 = 2147588888, s10 = 4, s11 = 0}, ofile = {0x0 <repeats 16 times>}, cwd = 0x80016e60 <itable+24>, name = "initcode\000\000\000\000\000\000\000"} Khi đó chúng ta có thể thấy rằng pid của initcode là 1.

3.2 System call tracing

Đề bài: Trong bài tập này, chúng sẽ thêm tính năng theo dõi cuộc gọi hệ thống có thể giúp bạn khi gỡ lỗi trong các labs sau này Bạn sẽ tạo lệnh gọi trace system mới để kiểm soát việc tracing Nó phải lấy một đối số, một number mask, có các bit chỉ định lệnh gọi system call nào để trace Ví dụ: để trace system call fork, một chương trình gọi trace(1 « SYS_fork), trong đó SYS_fork là số hệ thống từ kernel/syscall.h Bạn phải sửa đổi trong kernel xv6 để in ra một dòng khi mỗi systemcall sắp quay trở lại, nếu system call’number được đặt trong mask Dòng này phải chứa process id, tên của system call và giá trị trả về; bạn không cần in các đối số của system call Lệnh trace system call sẽ cho phép theo dõi tiến trình gọi nó và bất kỳ tiến trình con nào mà nó phân nhánh sau đó, nhưng không ảnh hưởng đến các tiến trình khác.

3.2.1 Thực hiện cài đặt

Dựa vào các gợi ý của đề bài, nhóm chúng em thực hiện theo các bước sau:

•Thêm prototype cho system call vào fileuser/user.h Thêm một stub vào file user/usys.pl và một syscall number vào file kernel/syscall.h.

Trang 13

Sau đó khai báo$U/_ trace vào phầnUPROGS trong Makefile // user/user.h

// system calls

int sleep( );int int uptime(void);

int trace( );int

•Thêm hàmsys_trace trong kernel/sysproc.c để thực hiện lệnh gọi hệ thống mới bằng cách ghi nhớ đối số của nó trong một biến mới trong cấu trúcProctrong kernel/proc.h.

// kernel/proc.h

struct file *ofile[NOFILE]; // Open files

struct inode *cwd; // Current directory

char name[16]; // Process name (debugging) uint64 syscall_trace;

Mặc dùsys_tracecó thể được định vị trong bất kỳ tệp nào, nhưng việc đặt nó trongkernel/sysproc.c sẽ đơn giản hóa việc phân loại.

Trang 14

extern uint64 sys_mkdir(void);

extern uint64 sys_close(void);

extern uint64 sys_trace(void);

Trang 15

num = p->trapframe->a7; // syscall number in a7

if(num > 0 && num < NELEM(syscalls) && syscalls[num]) { // Use num to lookup the system call function for num, call it, // and store its return value in p->trapframe->a0

p->trapframe->a0 = syscalls[num](); // trace

if (p->syscall_trace & (1 << num)) {

printf("%d: syscall %s -> %d\n", p->pid, syscall_names[num], p->trapframe->a0);

} } else {

printf("%d %s: unknown sys call %d\n", p->pid, p->name, num); p->trapframe->a0 = -1; }

}

Trang 16

3.2.2 Build và run

Thực hiện chạy lệnhmake clean,make qemu để build chương trình nhóm chúng em kết quả như sau: ALL TESTS PASSED

Kết quả thông báo toàn bộ tests đã pass tại dòngALL TESTS PASSED.

Trang 17

3.2.3 Testing

Thực hiện chạy lệnhmake grade để thực hiện test chương trình nhóm chúng em kết quả như sau: trace all grep: OK (0.9s) == Test trace nothing ==

Đề bài: Trong bài tập này chúng ta sẽ thêm một system call, cái có thể thu thập thông tin của hệ thống đang chạy System call này có một tham số duy nhất là con trỏ tới cấu trúc dữ liệusysinfo(xem file kernel/sysinfo.h để biết thêm) Kernel sẽ điền đầy đủ thông tin vào cấu trúc dữ liệu này, trong đó: trườngfreememlà số byte trống của bộ nhớ chính, và trườngnproclà số tiến trình trong hệ thống đang có trạng tháikhác UNUSED Chúng tôi cung cấp cho bạn chương trìnhsysinfotest để các bạn kiểm tra hoạt động của system call này; nếu nó in ra màn hình "sysinfotest: OK" thì bạn đã hoàn thành đúng bài tập này.

3.3.1 Thực hiện cài đặt:

Để hoàn thành được bài tập này chúng ta phải sử lý trên user và kernel •Ở user space:

- Trong file user/sysinfoteses dùng để kiểm tra cài đặt của system call sysinfo đã đúng chưa có gọi hàmsysinfovới tham số truyền vào là một biếninfo kiểusysinfo Để chương trình này có thể gọi được lời gọi hàm này thì đầu tiên ta phải thêm prototype của nó vào trong fileuser/user.h, để thông báo với các chương trình có include user/user.h biết rằng có một hàmsysinfovới tham số truyền vào là một biến kiểusysinfo.

Trang 18

int sleep( );int int uptime(void);

int trace( );int

int sysinfo(struct sysinfo*); //prototype of sysinfo

- Tiếp đó, để khi gọi hàm sysinfo trong user space thì một system được kích hoạt thì ta phải thêm một entry tương ứng vớisysinfotrong fileuser/usys.pl.

- Chúng ta phải cài đặt cách mà sysinfo hoạt động trong kernel Trong ker-nel/syscall.h chúng ta định nghĩa số củasysinfo

Trang 19

- Sau đó trong kernel/syscall.h chúng ta thêm prototype của hàm mà handle system call này (chúng ta đặt tên nó làsys_sysinfo), và kết nối hàm này với số đã được định nghĩa tương ứng với system callsysinfođể kernel có thể xử lý được.

// Prototypes for the functions that handle system calls .

extern uint64 sys_mkdir(void);

extern uint64 sys_close(void);

extern uint64 sys_trace(void);

extern uint64 sys_sysinfo(void);

// An array mapping syscall numbers from syscall.h // to the function that handles the system call.

static uint64 (*syscalls[])(void) = {

- Tiếp theo, chúng ta sẽ tiến hành cài đặt hàm xử lý system call này (tức là cài đặt sys_sysinfo) Ta sẽ cài đặt nó trong kernel/sysproc.c.

- Hàm này sau khi đọc địa chỉ của con trỏ tới cấu trúc sysinfo mà người dùng truyền vào thì truyền nó vào hàmsysinfo- đây là hàm sẽ xử lý logic củasys_sysinfo Hàmsysinfo được định nghĩa trong kernel/proc.c và để các chương trình khác có thể thấy và dùng được nó thì ta phải thêm prototype của hàm này vào trong kernel/defs.h.

//kernel/defs.h // proc.c

void procdump(void);

int sysinfo(uint64 addr);

Trang 20

sysinfo(uint64 addr){

struct proc *p = myproc();

struct sysinfo info;

- Trong hàm sysinfo ở kernel/proc.c, tham số đầu vào là địa chỉ tới vùng nhớ trong user space của tham số người dùng truyền vào trong system call Ta tạo ra một biến thuộc kiểu dữ liệusysinfo(đặt tên làinfo), và gán giá trị các trường của nó bằng việc gọi các hàmget_freemem() để lấy số byte đang không được dùng trong bộ nhớ chính vàget_nproc()để lấy số tiến trình đang không ở trong trạng thái UNUSED Hàmget_freemem()được định nghĩa ởkernel/kalloc.c và hàm get_nproc() được định nghĩa ở chính kernel/proc.c.

- Sau đó ta thực hiện copyout(p->pagetable, addr, (char *)&info, sizeof(info)) < 0 để đẩy dữ liệu từ kernel space về user space ở đúng địa chỉ mà người dùng đang muốn lấy dữ liệu.

- Với hàm get_freemem() được định nghĩa ở kernel/kalloc.c, nó sẽ trả về số byte đang không được dùng trong bộ nhớ chính và được cài đặt như sau:

Ngày đăng: 09/04/2024, 16:16

Xem thêm:

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

TÀI LIỆU LIÊN QUAN

w