Skip to content

luc1fe4/Room-s-Transcript-Rating

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Giải thích chi tiết: pgaccess (xv6, lab pgtbl)

1) Mục tiêu bài toán

  • Cần một system call pgaccess(base, len, mask) báo về các trang bộ nhớ user trong dải bắt đầu tại base, dài len trang, đã được truy cập (accessed) kể từ lần kiểm tra trước.
  • Kết quả trả về trong một biến 64-bit tại địa chỉ mask của user: bit i tương ứng trang i; bit=1 nếu trang đã được truy cập.
  • Sau khi ghi nhận, kernel xóa cờ truy cập của trang để lần gọi kế tiếp chỉ phản ánh truy cập mới phát sinh.
  • Giới hạn tối đa 64 trang mỗi lần gọi (tương ứng mặt nạ 64-bit).

2) Ý tưởng thực hiện

  • RISC-V và xv6 dùng bit PTE_A (Accessed) trong Page Table Entry để đánh dấu một trang đã được truy cập (do phần cứng đặt khi đọc/ghi/thực thi lần đầu).
  • Trong kernel, với mỗi trang trong phạm vi yêu cầu, tra PTE tương ứng:
    • Bỏ qua nếu PTE không hợp lệ (!PTE_V) hoặc không phải trang user (!PTE_U).
    • Nếu PTE có PTE_A: bật bit i trong mask và xóa PTE_A để “reset” cho lần kiểm tra sau.
  • Sao chép mask về user qua copyout. Giao diện người dùng sử dụng stub syscall sinh bởi usys.pl.

Lợi ích: triển khai đơn giản, tuyến tính theo số trang; không cần sửa đổi phần cứng hay cơ chế TLB. Xóa PTE_A giúp thu được semantics kiểu “edge-triggered” (chỉ truy cập mới).

3) Quy trình cài đặt chi tiết

3.1) Khai báo số hiệu syscall

  • File: kernel/syscall.h
    • Thêm/đảm bảo tồn tại: #define SYS_pgaccess 30
    • Ý nghĩa: gán một số hiệu duy nhất để user stub nạp vào thanh ghi a7 trước khi ecall.

3.2) Stub và khai báo phía user

  • File: user/usys.pl
    • Có mục: entry("pgaccess");
    • Ý nghĩa: sinh ra stub trong usys.S để nạp a7 = SYS_pgaccess rồi ecall.
  • File: user/user.h
    • Khai báo: int pgaccess(void *base, int len, void *mask);
    • Ý nghĩa: cho phép chương trình user gọi hàm pgaccess() như một API bình thường.

3.3) Đăng ký handler trong kernel

  • File: kernel/syscall.c
    • Khai báo: extern uint64 sys_pgaccess(void);
    • Ánh xạ trong bảng syscall: [SYS_pgaccess] sys_pgaccess, (đi kèm #ifdef LAB_PGTBL).
    • Ý nghĩa: khi trap ecall với a7=30, kernel gọi đúng handler sys_pgaccess().

3.4) Định nghĩa cờ PTE_A

  • File: kernel/riscv.h
    • Có: #define PTE_A (1L << 6)
    • Ý nghĩa: cờ do phần cứng đặt khi trang được truy cập; kernel đọc/xóa để theo dõi truy cập.

3.5) Handler sys_pgaccess

  • File: kernel/sysproc.c (bên trong #ifdef LAB_PGTBL)
  • Chức năng: nhận tham số user, quét bảng trang, lập mask, trả về kết quả, và xóa cờ PTE_A đã quan sát.
  • Ý nghĩa từng bước chính trong code:
    1. Đọc tham số syscall
      • argaddr(0, &uaddr); → địa chỉ bắt đầu base
      • argint(1, &npages); → số trang len
      • argaddr(2, &umask); → địa chỉ user để ghi kết quả
      • Kiểm tra npages < 0 → lỗi; cắt npages về 64 nếu lớn hơn.
    2. Duyệt từng trang và tra PTE
      • Tính va = uaddr + i * PGSIZE cho từng i.
      • pte = walk(p->pagetable, va, 0) để lấy con trỏ PTE.
      • Bỏ qua nếu pte == 0 hoặc !(*pte & PTE_V) (chưa map) hoặc !(*pte & PTE_U) (không phải của user).
    3. Ghi nhận và reset cờ truy cập
      • Nếu *pte & PTE_A khác 0: mask |= (1ULL << i)*pte &= ~PTE_A để xóa cờ.
      • Ý nghĩa: bật bit trong kết quả và “reset” để lần sau chỉ thấy truy cập mới.
    4. Trả kết quả về user
      • copyout(p->pagetable, umask, &mask, sizeof(mask)) → lỗi thì trả -1, thành công trả 0.

3.6) Kiểm thử với chương trình user

  • File: user/pgtbltest.c
    • Cấp phát buf = malloc(32 * PGSIZE); lần 1 gọi pgaccess(buf, 32, &abits) kỳ vọng abits=0.
    • Ghi 1 byte vào các offset trang 1, 2, 30: buf[PGSIZE * k] += 1;.
    • Lần 2 gọi pgaccess(buf, 32, &abits) và kiểm: abits == (1<<1) | (1<<2) | (1<<30).
    • Ý nghĩa: viết 1 byte đảm bảo phần cứng đặt PTE_A cho các trang tương ứng.

3.7) Cách chạy và chấm điểm

  • Chạy thủ công trong QEMU:

    cd source
    make clean && make qemu

    Trong shell của xv6 sau khi boot:

    pgtbltest
    

    Kỳ vọng: pgaccess_test: OKpgtbltest: all tests succeeded.

  • Chạy script chấm điểm (nếu toolchain đã sẵn sàng):

    cd source
    ./grade-lab-pgtbl

3.8) Lưu ý biên và bảo mật

  • base không cần thẳng hàng trang; bit 0 ứng với trang chứa base (khuyến nghị căn trang để dễ suy luận).
  • Bắt buộc kiểm tra PTE_U để chỉ báo cáo trang user (tránh lộ thông tin vùng kernel).
  • Trang chưa map hoặc không hợp lệ bị bỏ qua (bit = 0), không gây lỗi toàn bộ.

Tham chiếu nhanh (điểm tựa khi vấn đáp):

  • Số hiệu syscall: kernel/syscall.h → SYS_pgaccess
  • Đăng ký syscall: kernel/syscall.c → extern sys_pgaccess + syscalls[]
  • Bit truy cập: kernel/riscv.h → PTE_A
  • Handler: kernel/sysproc.c → sys_pgaccess()
  • Stub và khai báo user: user/usys.pl, user/user.h
  • Bài test: user/pgtbltest.c

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors