12 điểm bởi GN⁺ 2025-06-29 | 4 bình luận | Chia sẻ qua WhatsApp
  • Chia sẻ về trải nghiệm trong một dự án thời đại học, nơi nhóm đã thử port hệ điều hành Xv6 bằng CPU dựa trên RISC ISA do tự thiết kếtrình biên dịch C do tự phát triển
  • Dự án được triển khai theo hướng tự làm toàn bộ các thành phần như thiết kế CPU, phát triển trình biên dịch C (Ucc), và port Xv6
  • Để chạy được hệ điều hành, nhóm đã thử sức với việc thiết kế các chức năng phần cứng và phần mềm cốt lõi như ngắt, bộ nhớ ảo, cache
  • Trong quá trình port Xv6, nhóm gặp phải nhiều trở ngại như vấn đề về tính khả chuyển, độ khó khi gỡ lỗi, lỗi cache, nhưng đã tự mình giải quyết được
  • Cuối cùng, nhóm đã chạy thành công các ứng dụng tương tác như SL, Minesweeper, 2048 cùng cả chương trình ray-tracing, qua đó đạt được một thành tựu lớn cả về học thuật lẫn kỹ thuật

Tổng quan dự án

  • Đây là một bài thực nghiệm tiêu biểu của Khoa Khoa học Thông tin, University of Tokyo, tập trung vào việc giúp sinh viên tích lũy kinh nghiệm về CPU, thiết kế phần cứng, xây dựng trình biên dịch và chạy ứng dụng
  • Mục tiêu của dự án là hiện thực hóa ISA của CPU tự thiết kế trực tiếp trên FPGA, xây dựng toolchain C (Ucc) cho nó, rồi mở rộng sang port hệ điều hành như Xv6
  • Phần lớn quá trình thực nghiệm được tiến hành dưới hình thức tự học chủ động

Thực nghiệm CPU và bài tập

  • Mỗi nhóm gồm 4~5 người cùng tham gia thiết kế kiến trúc CPU mới, hiện thực nó trên FPGA, và phát triển trình biên dịch cho kiến trúc đó
  • Sau khi tạo trình biên dịch cho một tập con của OCaml, hạng mục đánh giá bắt buộc là chạy chương trình ray tracing
  • Nếu còn thời gian, sinh viên có thể tự đặt ra thử thách riêng; một số đã thực hiện các thí nghiệm mở rộng như tăng tốc CPU, phát triển đa lõi, chạy nhạc/trò chơi
  • Riêng nhóm Group 6 đặt mục tiêu port hệ điều hành, từ đó một nhóm liên hợp mới là Group X được thành lập

Xv6 và thử thách port hệ điều hành

  • Nhóm chọn Xv6 do MIT phát triển cho mục đích giáo dục (dựa trên Unix v6, dành cho x86) làm đối tượng port
  • Dù Xv6 là một hệ điều hành Unix đơn giản, để chạy trên phần cứng thực tế vẫn có nhiều vấn đề như cần trình biên dịch C89, ngắt đặc thù, hỗ trợ địa chỉ ảo, và tính khả chuyển kém
  • Xv6 được xây dựng với giả định đặc trưng của x86 như char là 1 byte, int là 4 byte, nên khi port đã phát sinh nhiều lỗi

Phát triển trình biên dịch và toolchain (Ucc)

  • Trong bài thực nghiệm ban đầu, việc phát triển trình biên dịch OCaml là chuẩn, nhưng để chạy Xv6 thì cần trình biên dịch C89, vì vậy nhóm quyết định tự xây dựng
  • Dựa trên nguyên mẫu trình biên dịch C do một thành viên trong nhóm tạo ra, cả nhóm đã tự xây dựng một toolchain mới mang tên Ucc
  • Không chỉ trình biên dịch, nhóm còn tự thiết kế Primitive Linker và các công cụ gỡ lỗi

Thiết kế CPU và trình mô phỏng

  • Sau khi thiết kế mạch CPU bằng ngôn ngữ mô tả phần cứng (HDL, ví dụ Verilog / VHDL), nhóm hiện thực nó trên FPGA thật thông qua quá trình tổng hợp logic với Vivado/Quartus
  • Quá trình tổng hợp logic lặp đi lặp lại mất rất nhiều thời gian, kéo theo thời gian chờ đợi đáng kể
  • Sau các chức năng CPU cơ bản, nhóm còn thiết kế thêm phần hỗ trợ phần cứng cần thiết để chạy OS như interrupt, MMU, TLB
  • CPU hoàn thiện được đặt tên là GAIA
  • Trình mô phỏng cũng được bổ sung interrupt thực, chuyển đổi địa chỉ ảo và các công cụ gỡ lỗi

Vấn đề trong quá trình port và cách giải quyết

  • Do tính khả chuyển kém của Xv6, hệ thống có thể hoạt động bất thường tùy theo đặc tả của CPU và trình biên dịch
    • Ví dụ: khi charint đều được định nghĩa là 32 bit, phép toán con trỏ và cấu trúc stack bị phá vỡ
    • Nhóm đã cải tiến trình biên dịch Ucc để char khớp với kích thước 8 bit
  • Xử lý interrupt là phần đặc biệt khó; vì vậy nhóm đã thêm vào trình mô phỏng tự viết disassembler, state dump và các công cụ gỡ lỗi khác
  • Vấn đề cache alias phát sinh do GAIA dùng địa chỉ ảo làm chỉ số cache, và đã được giải quyết bằng kỹ thuật Page Coloring

Kết quả cuối cùng: chạy OS và ứng dụng

  • Vào ngày 1 tháng 3, nhóm cuối cùng đã thành công chạy hoàn chỉnh Xv6 trên cả trình mô phỏng lẫn CPU thật (phần cứng)
  • Nhóm cũng chạy thành công mini curses tự viết, lệnh SL, Minesweeper, 2048 cùng các ứng dụng tương tác khác
    • Riêng 2048 còn được bổ sung thiết kế hỗ trợ nhập liệu non-canonical
    • Thông qua chỉnh sửa Xv6, nhóm cũng thêm các chức năng tương đương ioctl, termios kiểu POSIX
    • Một assembler cỡ nhỏ và mini vi cũng được hiện thực, tạo nên một môi trường lập trình thời gian thực thực thụ
  • Chương trình ray tracing cũng được chạy trên chính hệ điều hành, vượt xa mục tiêu ban đầu của bài thực nghiệm

Ý nghĩa của dự án và các trường hợp tiếp nối

  • Sau bài thực nghiệm này, nhiều thế hệ sinh viên tiếp theo đã tiếp tục tự tạo CPU và OS để tiến hành nhiều thử nghiệm đa dạng
    • Chẳng hạn như mở rộng sang dùng RISC-V ISA, xây dựng OS riêng, hoặc chạy Linux
  • Thông qua thực hành, sinh viên có thể trực tiếp trải nghiệm toàn bộ stack phần cứng/phần mềm và nâng cao hiểu biết thực chất về thuật toán, tích hợp phần cứng-phần mềm, cấu trúc mức thấp
  • Dù có ý kiến cho rằng “phát minh lại bánh xe” là kém hiệu quả, nhưng hiệu quả học tập và sự hứng thú khi tự tay làm ra là rất lớn

Trải nghiệm thực tế và mã nguồn

  • Có thể trực tiếp chạy thử tại GAIA CPU + Xv6 demo
  • Phiên bản port cho MIPS được công bố mã nguồn mở tại đây

Kết luận

  • Bài viết nhấn mạnh bài học rằng “không có gì giúp học tốt bằng tự tay làm”, đồng thời đề cao tầm quan trọng của trải nghiệm tích hợp phần cứng-phần mềm
  • Các thế hệ sinh viên sau đó cũng tiếp tục chinh phục những mục tiêu mới, với kỳ vọng trong tương lai có thể chạy Linux hoặc VM trên ISA tự thiết kế
  • Câu chuyện khép lại bằng danh sách tên các thành viên tham gia dự án

4 bình luận

 
regentag 2025-07-01

Thật ghen tị khi được có trải nghiệm như thế này ở trường đại học. Có vẻ sẽ rất thú vị..

 
qlghwp123 2025-06-30

Chắc là đã vui lắm.

 
iolothebard 2025-06-30

Xuống thêm một chút nữa…

Tự làm một CPU 8-bit…?
https://eater.net/8bit

 
GN⁺ 2025-06-29
Ý kiến trên Hacker News
  • Bài này làm tôi nhớ đến một dự án nhóm hồi còn học đại học, ba người làm trong 3 tuần. Có nhiều chủ đề để chọn, trong đó có cả việc tự làm một hệ điều hành rất cơ bản, và bọn tôi đã hỏi các giáo sư xem có thể port MINIX3 lên Raspberry Pi không thì được đồng ý (vì MINIX3 đã có bản port ARM cho BeagleBoard nên có vẻ là khả thi).<br>Độ khó cao hơn rất nhiều so với dự kiến, và hàng loạt vấn đề kỹ thuật không thể ngờ tới cứ xuất hiện. Đặc biệt, Raspberry Pi 3 lại khởi động ở chế độ hypervisor thay vì supervisor nên bọn tôi đã rất vất vả, còn độ chính xác của mô phỏng Raspberry Pi trong QEMU thì quá tệ nên gần như vô dụng cho việc phát triển OS. Bọn tôi đã mất hẳn một tuần chỉ để tìm cách giải quyết và gỡ lỗi phần cứng mức thấp. <br>Cuối cùng cũng tạo được một bản port hoạt động có kèm driver UART, GPIO và framebuffer, chạy thành công trên Raspberry Pi 2 và 3. Bọn tôi thuyết trình trực tiếp trên phần cứng thật, dùng shell script để xuất image ramdisk, theo dõi chân GPIO để chuyển slide tới/lùi, rồi tự thao tác bằng cách chập chân bằng dao. Xét về độ độc đáo thì đó là một bài thuyết trình cực kỳ ngầu, và chắc tôi vẫn còn giữ image thẻ SD đó đến giờ

    • Nghe như một trải nghiệm rất tuyệt<br>Ngay từ lúc đề xuất port MINIX3 lên Raspberry Pi, có khi các giáo sư đã đoán trước là sẽ thất bại rồi cũng nên<br>Khi độ chính xác của mô phỏng Raspberry Pi trong QEMU kém, tôi thường dùng chiến lược làm cho OS chạy được trên QEMU trước rồi phó mặc phần cứng cho may rủi. Dù vậy cũng vẫn ổn<br>Tôi tò mò là bạn đã gỡ lỗi trên Raspberry Pi thật như thế nào

    • Nghe bạn kể dùng dao để chập GPIO làm tôi nhớ đến lần mình chập hai chân nguồn để khởi động bo mạch chủ ATX khi không có công tắc nguồn<br>Dù vậy, bộ thiết lập của bạn vẫn ngầu hơn nhiều. Làm tốt lắm

  • Tôi cũng từng làm một việc tương tự ở SFU khoảng 25~30 năm trước. Không phải cài OS và compiler, cũng không phải dự án nhóm<br>Nếu bạn hứng thú với kiểu thử nghiệm này, tôi khuyên dùng Turing Complete vì có hướng dẫn và bộ công cụ rất dễ tiếp cận. Bạn có thể đi từ vài cổng logic đến một máy tính thực sự. Cũng có thể chia sẻ cộng đồng và linh kiện, thậm chí có cả lõi RiscV. Thật sự rất vui, tôi khuyên nên thử trên Steam<br>Liên kết Steam của Turing Complete

    • Nhìn cái này làm tôi thấy nó giống như phiên bản trò chơi của nand2tetris mà tôi từng chơi rất vui hồi trước. Đây cũng là một gợi ý đáng thử
  • Bài này khiến tôi nhớ đến một dự án học thuật (?) hơi giống như vậy. Ít nhất tôi nhớ là có custom C compiler và custom OS. Nhưng tôi không nhớ chính xác tên

  • Tham khảo topic liên quan đã từng được đăng trước đây Liên kết bài trước

  • Khi tự làm CPU + compiler + OS, bên dưới hoàn toàn không còn nền tảng nào cả. Chính tôi là nền tảng.<br>Bug chính là luật lệ của hệ thống. Bình thường ta gỡ lỗi trên các lớp trừu tượng do người khác tạo ra, còn ở đây thì ngay cả những quy tắc đó cũng do chính tôi định nghĩa. Có thể nói OP đã tự gỡ lỗi những quy tắc của riêng mình

  • Thật sự rất ấn tượng. Làm việc ở tầng rất thấp thường rất tẻ nhạt và tốn thời gian, đặc biệt còn khó hơn nữa nếu không có những công cụ thiết yếu như debugger

    • Nếu bạn chưa từng gỡ lỗi một lỗi kprintf kỳ quặc bằng oscilloscope thì có lẽ bạn vẫn chưa nếm được hương vị thực sự của low-level
  • Trước đây Magic-1 và BMOW cũng từng làm những việc tương tự<br>Xem chi tiết tại homebrewcpu.com<br>Danh sách các trang tự làm CPU có tại homebrewcpuring.org

  • Giờ có lẽ đã đến lúc thôi không chỉ triển khai trên FPGA nữa mà nên chạy thẳng vào phòng thí nghiệm bán dẫn và nhờ họ chế tạo CPU trực tiếp luôn