Networks Business Online Việt Nam & International VH2

Lab 7 – ĐẠI HỌC QUỐC GIA TP HỒ CHÍ MINH TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN o Tài liệu hướng dẫn – StuDocu

Đăng ngày 04 October, 2022 bởi admin
ĐẠI HỌC QUỐC GIA TP HỒ CHÍ MINH TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN  o 

Tài liệu hướng dẫn thực hành

HỆ ĐIỀU HÀNH

Biên soạn : ThS Phan Đình Duy ThS Nguyễn Thanh Thiện KS Trần Đại Dương KS Trần Hoàng LộcLƯU HÀNH NỘI BỘ Thành phố Hồ Chí Minh –

MỤC LỤC

BÀI 7. THỰC HÀNH TRÊN HỆ ĐIỀU HÀNH PINTOS …………. 1

7 PHẦN 1 : TỔNG QUAN VỀ PINTOS …………………………………………………… 17 PHẦN 2 : THỰC HÀNH ……………………………………………………………………… 10

Bài 7. THỰC HÀNH TRÊN HỆ ĐIỀU HÀNH

PINTOS

( Dành riêng cho sinh viên học thực hành thực tế Hệ điều hành theo hình thức 2 )7 PHẦN 1 : TỔNG QUAN VỀ PINTOS7.1 Giới thiệu PintosPintos là một hệ điều hành đơn thuần dành cho kiến trúc tập lệnh x86. Nó được tăng trưởng tại Đại học Stanford bởi Ben Pfaff vào năm 2004. Pintos được kiến thiết xây dựng để thay thế sửa chữa cho Not Another Completely Heuristic Operating System ( Nachos ) – một hệ điều hành tựa như được tăng trưởng trước đó tại Đại học UC Berkeley bởi Thomas E. Anderson. Cả Nachos và Pintos được sử dụng hầu hết cho mục tiêu giảng dạy với 1 số ít bài tập lập trình đi kèm. Thông qua việc thực thi những bài tập này, sinh viên được tiếp cận với những khái niệm cơ bản trong phong cách thiết kế và thiết lập hệ điều hành, gồm có tiểu trình, quản trị bộ nhớ và truy vấn mạng lưới hệ thống tập tin. Pintos cũng đồng thời cũng giúp sinh viên tăng trưởng năng lực debug khi viết chương trình. Pintos và những bài tập thực hành thực tế đi kèm với nó được viết bằng ngôn từ C. Nội dung phần thực hành thực tế bên dưới được kiến thiết xây dựng dựa trên tài liệu hướng dẫn thực hành thực tế Pintos của Đại học Stanford [ 1 ] và họcphần CS162 của Đại học UC Berkeley [ 2 ] ( chi tiết cụ thể xem ở phần tài liệu tìm hiểu thêm ). Mã nguồn của Pintos dùng cho phần thực hành thực tế này được phân phối tại website môn học. 7.1 Cấu trúc PintosPintos được tổ chức triển khai thành những thư mục như sau : threads / : Nhân ( kernel ) của Pintos. Nội dung thực hành thực tế 1 sẽ thực thi với những mã nguồn trong thư mục này. userprog / : Thư mục chứa những chương trình của người dùng ( user program ). Nội dung thực hành thực tế 2 sẽ thực thi với những mã nguồn trong thư mục này. vm / : Thư mục chứa những mã nguồn dành cho việc quản trị bộ nhớ. Mặc định đây là một thư mục trống, những mã nguồn thiết yếu sẽ được setup ở nội dung thực hành thực tế 3. filesys / : Hệ thống quản trị tập tin của Pintos. devices / : Thư mục chứa những thư viện dành cho những tác vụ nhập / xuất tài liệu : bàn phím, đĩa cứng, bộ định thời, … lib / : Thư viện chính của Pintos, là một tập con của thư viện C chuẩn. Các mã nguồn trong thư mục này được biên dịch và sử dụng cho nhân của Pintos cũng như chương trình của người dùng. Tất cả những header trong thư mục này đều hoàn toàn có thể được sử dụng trải qua cú pháp # include < ... >. Chú ý không chỉnh sửa những mã nguồn bên trong thư mục này .

  • GCC phiên bản 4 trở đi.
  • GNU binutils. Pintos sử dụng các thư viện addr2line, ar, ld,
    objcopy và ranlib nằm trong gói thư viện này.
  • Perl phiên bản 5.8 trở đi.
  • GNU make phiên bản 3 trở đi.
    Bên cạnh các công cụ bắt buộc ở trên, có thể cài thêm một số
    công cụ sau: QEMU, phiên bản 0.8 trở đi, GDB (sử dụng để
    debug), X server.
    Sau khi cài đặt các công cụ trên, tiến hành cài đặt Pintos theo
    các bước sau:
  • Cài đặt Bochs phiên bản 2.2 (tham khảo hướng dẫn tại:
    web.stanford/class/cs140/projects/pintos/pintos_12.htm
    l#SEC167)
  • Cài đặt scripts trong thư mục src/utils. Sao chép các tập tin
    backtrace, pintos, pintos-gdb, pintos-mkdisk, pintos-set-cmdline,
    và Pintos vào trong đường dẫn PATH.
    Cài đặt src/misc/gdb-macros vào một thư mục public. Kế tiếp,
    chỉnh sửa GDBMACROS trong tập tin pintos-gdb (tập tin vừa
    được sao chép, không phải tập tin gốc) trỏ đến thư mục cài đặt
    gdb-macros. Kiểm tra việc cài đặt bằng cách chạy pintos-gdb
    (không có tham số). Nếu không có bất cứ thông báo lỗi nào về
    việc thiếu gdb-macros thì chứng tỏ nó đã được cài đặt một cách
    chính xác.

Biên dịch những thành phần còn lại của Pintos bằng cách chuyển dời vào thư mục src / utils, gõ lệnh make. Thêm thư viện squish-pty vào PATH. Quá trình thiết lập Pintos đã hoàn tất. 7.1.3 Build PintosSau khi setup xong, thực thi build những mã nguồn dành cho nội dung thực hành thực tế 1. Di chuyển đến thư mục threads ( bằng lệnh cd ). Kế tiếp, thực thi lệnh make. Một thư mục con có tên build sẽ được tạo ra, gồm 1 tập tin Makefile và một vài thư mục con. Tiếp tục thực thi lệnh make để build mã nguồn kernel bên trong. Quá trình build sẽ diễn ra trong khoảng chừng 30 giây. Kết thúc quy trình build, trong thư mục build sẽ có những tập tin sau : Makefile : Đây là bản sao của tập tin / src / Makefile. Nó miêu tả cách build mã nguồn nhân của Pintos. kernel : Tập tin object chứa hàng loạt kernel. Tập tin này là tác dụng của việc link những tập tin object được biên dịch từ những tập tin mã nguồn kernel riêng không liên quan gì đến nhau. Nó cũng chứa những thông tin debug nên hoàn toàn có thể dùng GDB ( hoặc những công cụ debug khác ) để debug nó. kernel : Tập tin image của kernel. Về thực chất, tập tin này chính là tập tin kernel nhưng phần thông tin debug được bỏ đi để tiết kiệm ngân sách và chi phí khoảng trống tàng trữ, đồng thời cũng giữ cho size của kernel ở mức 512 kB, không vượt quá số lượng giới hạn được đặt ra theo phong cách thiết kế của kernel loader .lệnh pintos và ý nghĩa của chúng bằng cách thực thi lệnh pintos với tham số – h. 7.1.3 Debug Pintos

Pintos hỗ trợ nhiều công cụ dùng để debug. Danh sách các
công cụ có thể xem đầy đủ trong hướng dẫn trên website của
Pintos. Ở đây chỉ giới thiệu một số công cụ phổ biến, thường được
sử dụng
a. printf()
Hàm printf() được cài đặt sẵn trong Pintos, người dùng có thể
gọi nó từ bất cứ đâu trong kernel. Cách sử dụng hàm này tương tự
như hàm printf() trong ngôn ngữ C.
b. Macro ASSERT
Pintos cung cấp macro ASSERT, được định nghĩa trong tập
tin ‘’, để đánh giá biểu thức. Cú pháp của macro này
như sau:
ASSERT (expression)
Macro này sẽ kiểm tra giá trị của biểu thức. Nếu biểu thức này
có giá trị 0 (false), kernel sẽ phát sinh lỗi thông qua một thông
báo. Nội dung thông báo này sẽ bao gồm biểu thức gây ra lỗi, tập
tin mã nguồn, vị trí và backtrace dùng để tìm nguyên nhân gây ra
lỗi.

c. Hàm và các tham số hàm
Bên cạnh macro ASSERT, trong tập tin ‘’, Pintos
cung cấp thêm một số macro khác để định nghĩa một số thuộc tính
đặc biệt cho hàm hoặc các tham số của hàm. Có thể sử dụng các
tham số này cho mục đích debug:
UNUSED: Sử dụng macro này để thông báo cho trình biên
dịch biết là tham số này sẽ không được sử dụng bên trong hàm.
NO_RETURN: Sử dụng macro này để thông báo cho trình
biên dịch biết là hàm sẽ không có kết quả trả về.
NO_INLINE: Sử dụng macro này để thông báo cho trình biên
dịch biết là không sử dụng các hàm nội tuyến (inline function).
PRINTF_FORMAT (format, first): Sử dụng macro này để
thông báo cho trình biên dịch biết hàm này sẽ hoạt động như lệnh
printf() với danh sách tham số và định dạng được truyền vào.
d. Backtraces
Khi có một lỗi phát sinh trong kernel, nó sẽ in ra một
backtrace – một thông báo ngắn diễn tả lỗi nào đã phát sinh, đi
kèm với nó là một danh sách địa chỉ các hàm đã thực hiện tại thời
điểm lỗi phát sinh.
Có thể thêm hàm debug_backtrace() – hàm này được định
nghĩa trong ‘’ – để in ra backtrace tại bất cứ vị trí nào
trong mã nguồn. Ngoài ra cũng có thể sử dụng hàm

7 PHẦN 2: THỰC HÀNH

Trước khi bắt đầu thực hiện các nội dung thực hành bên dưới,
cần đảm bảo Pintos đã được cài đặt và hoạt động ổn định.
7.2 NỘI DUNG 1: TIỂU TRÌNH

7.2.1 Mục tiêuPhần thực hành thực tế này giúp sinh viên : Làm quen và hiểu khái niệm tiểu trình trong Pintos. Hiểu, sử dụng và thiết lập được những thao tác tương quan đến tiểu trình trên Pintos. Hiểu và thiết lập những thuật toán định thời CPU trên Pintos : priority và multilevel feedback queue. 7.2.1 Sinh viên chuẩn bị sẵn sàngĐọc trước nội dung thực hành thực tế ở phần 7.2. Đọc trước những khái niệm và những thao tác tương quan đến tiểu trình ở phần 7.2. Đọc trước chính sách cấp phép bộ nhớ của Pintos ở phần 7.2. Tìm hiểu những chính sách đồng điệu trên PintosÔn lại giải thuật định thời theo độ ưu tiên. Đọc trước và hiểu được những bước thực thi giải thuật định thời multilevel feedback queue ở phần 7.2. 7.2.1 Nội dung thực hành thực tếa. Alarm clock Trong Pintos, những tiểu trình hoàn toàn có thể gọi hàm timer_sleep ( ) để tự đưa chúng vào trạng thái sleep : / * *

  • This function suspends execution of the calling thread until time has
  • advanced by at least x timer ticks. Unless the system is otherwise idle, the
  • thread need not wake up after exactly x ticks. Just put it on the ready queue
  • after they have waited for the right number of ticks. The argument to
  • timer_sleep() is expressed in timer ticks, not in milliseconds or any another
  • unit. There are TIMER_FREQ timer ticks per second, where TIMER_FREQ is
  • a constant defined in devices/timer (spoiler: it’s 100 ticks per second).
    */
    void timer_sleep (int64_t ticks);
    Mã nguồn được cài đặt hiện tại của hàm timer_sleep() hoạt
    động chưa hiệu quả vì có khả năng xuất hiện busy waiting khi
    thực thi. Do đó, cần cài đặt lại hàm timer_sleep() để giải quyết vấn
    đề trên. Như vậy, yêu cầu ở phần này là cài đặt lại hàm
    timer_sleep() trong tập tin devices/timer để giải quyết vấn đề
    busy waiting.

Pintos để có năng lực lựa chọn giải thuật theo độ ưu tiên hoặc giải thuật multilevel feedback queue trong quy trình thực thi, trải qua việc sử dụng biến bool thread_mlfqs trong tập tin thread. Các hàm cần thiết lập sẽ nằm ở những tập tin sau : threads / synch, threads / thread và threads / thread. 7.2.1 Tiểu trìnha. Tổng quan về tiểu trình Mã nguồn hiện tại của Pintos đã thiết lập sẵn hàm tạo và kết thúc tiểu trình, một bộ lập lịch để quy đổi giữa những tiểu trình và một số ít giải pháp đồng nhất ( semaphores, locks, condition variables và optimization barriers ). Các mã nguồn này trông có vẻ như khó hiểu khi mới đọc qua. Có thể đặt những hàm printf ( ) ( hoặc sử dụng những công cụ debug khác đã ra mắt ở phần debug ) vào bất kỳ đâu trong những mã nguồn này, sau đó biên dịch và chạy lại để hoàn toàn có thể hiểu rõ phương pháp hoạt động giải trí của chúng. Khi một tiểu trình được tạo bằng hàm thread_create ( ), nó sẽ cần phải nhận vào một tham số là tên một hàm đã khai báo trước – hàm này chính là hàm mà tiểu trình sẽ thực thi. Khi tiểu trình được tạo ra và chạy, nó sẽ khởi đầu thực thi từ đầu hàm thực thi này. Khi hàm thực thi này kết thúc ( trả về hiệu quả ), tiểu trình cũng sẽ kết thúc .Mỗi tiểu trình, về thực chất, hoạt động giải trí như một chương trình con nằm bên trong Pintos, trong đó hàm thực thi được truyền vào thread_create ( ) có vai trò giống như hàm main ( ). Tại một thời gian bất kể, chỉ có một tiểu trình chạy, toàn bộ những tiểu trình khác đều không hoạt động giải trí. Bộ lập lịch sẽ quyết định hành động tiểu trình nào sẽ được chạy tiếp theo. Nếu không có tiểu trình nào chuẩn bị sẵn sàng để chạy, một tiểu trình idle ( đang nghỉ ) đặc biệt quan trọng sẽ chạy. Mã nguồn thực thi quy trình chuyển ngữ cảnh ( context switch ) được thiết lập bên trong threads / switch, đây là mã nguồn x86. Nó lưu trạng thái của tiểu trình đang chạy và Phục hồi trạng thái của tiểu trình tiếp nối khi tiểu trình này nhận CPU. Có thể sử dụng GDB để theo vết việc chuyển ngữ cảnh và hiểu rõ những gì xảy ra trong quy trình này. b. Cấu trúc thread Mỗi tiểu trình được bộc lộ bằng một trang nhớ có kích cỡ 4KB. Các thông tin về cấu trúc của tiểu trình nằm ở phần đầu trang nhớ này. Phần còn lại được sử dụng cho stack của thread, stack sẽ được mở rộng lớn dần từ trên xuống ( xem hình bên dưới ) .vòng đời của nó. tid có kiểu số nguyên ( int ) và mỗi tiểu trình sẽ nhận giá trị tid tăng dần, mở màn bằng 1 ở tiến trình khởi đầu .

  • enum thread_status status : Trạng thái của tiểu trình, gồm những trạng thái sau : THREAD_RUNNING, THREAD_READY, THREAD_BLOCKED, THREAD_DYING .
  • char name [ 16 ] : Tên của tiểu trình
  • uint8_t * stack : Stack của tiểu trình
  • int priority: Độ ưu tiên của tiểu trình, có giá trị từ PRI_MIN
    (0) đến PRI_MAX (63). Giá trị càng nhỏ ứng với độ ưu tiên
    càng thấp, 0 là độ ưu tiên thấp nhất, 63 là độ ưu tiên cao
    nhất. Pintos hiện tại không sử dụng các giá trị độ ưu tiên
    này, tuy nhiên, khi thực hiện nội dung thực hành 1, cần sử
    dụng các giá trị ưu tiên này để cài đặt thuật toán lập lịch
    theo độ ưu tiên.

  • struct list_elem allelem : Thành phần này được sử dụng để link tiểu trình với list tổng thể những tiểu trình. Mỗi tiểu trình sẽ được thêm vào list khi nó được tạo ra và xóa khỏi list khi nó kết thúc .
  • struct list_elem elem : Thành phần này được sử dụng để đưa tiểu trình vào trong list link, đó hoàn toàn có thể là ready_list ( hàng đợi những tiểu trình chuẩn bị sẵn sàng chạy những tiểu

trình ) hoặc list những tiểu trình đang đợi semaphore trong hàm sema_down ( ) .

  • uint32_t *pagedir: Bảng trang của tiến trình (nếu là tiến trình
    người dùng). Chỉ sử dụng thành phần này ở nội dung thực
    hành 2 và 3.
  • unsigned magic: Luôn được thiết lập giá trị là
    THREAD_MAGIC, giá trị này được định nghĩa trong
    threads/thread và được dùng để phát hiện lỗi tràn stack
    (khi stack bị tràn, giá trị này sẽ thay đổi).
    Khi thực hiện các nội dung thực hành, có thể thêm các thành
    phần khác cũng như thay đổi hoặc xóa các thành phần hiện tại của
    cấu trúc tiểu trình.
    c. Các hàm của tiểu trình
    Mã nguồn tập tin threads/thread đã cài đặt sẵn một số hàm
    public để hỗ trợ việc thực thi tiểu trình:
  • void thread_init (void): Khởi tạo tiểu trình hệ thống
  • void thread_start (void): Khởi chạy tiểu trình
  • void thread_tick (void): Timer interrupt sẽ gọi hàm này mỗi
    khi timer tick.
  • tid_t thread_create (const char *name, int priority,
    thread_func *func, void *aux): Khởi tạo tiểu trình với các
    tham số gồm tên, độ ưu tiên, hàm thực thi của tiểu trình và
    tham số truyền cho hàm thực thi. Hàm thread_create sẽ trả

Source: https://vh2.com.vn
Category : Ứng Dụng