คุณจะได้รับ Verson ล่าสุดของ XV6 ตามที่เก็บนี้ที่นี่
โคลนที่เก็บ XV6 อย่างเป็นทางการจากที่นี่ เราต้องการอีมูเลเตอร์เพื่อบูต xv6 เราจะใช้ QEMU เพื่อจุดประสงค์นี้ ในการติดตั้ง QEMU ให้เรียกใช้จากเทอร์มินัลของคุณ
sudo apt install qemu
จากที่ที่ xv6 ถูกโคลนเรียก make เพื่อรวบรวม xv6 จากนั้นเพื่อเปิดตัว emulator ให้เรียกใช้ make qemu และคุณจะเห็น QEMU ในหน้าต่างอื่น หาก Qemu ไม่เปิดใช้งานให้เรียกใช้
sudo apt install qemu-system-x86
make qemu
คราวนี้มันควรจะทำงาน ถึงกระนั้นคุณอาจประสบปัญหาเช่นนี้แล้วนี่ก็เป็นวิธี
ในการเรียกใช้ QEMU ในเทอร์มินัลเดียวกันกับที่คุณใช้ให้เรียกใช้ make qemu-nox แทน make qemu
หลังจากเปิดตัว QEMU คุณจะเห็นการโทรระบบต่อไปนี้โดยเรียกใช้ ls 
เราสามารถปรับเปลี่ยนซอร์สโค้ดและดูเอฟเฟกต์ได้ทันที Lets บอกว่าเราต้องการแทนที่ $ sign ด้วยอย่างอื่นเพื่อทำสิ่งนี้ไปที่ไฟล์ sh.c และเปลี่ยนวิธี getcmd
printf ( 2 , ANSI_COLOR_GREEN " afnan@Xv6:$ " ANSI_COLOR_RESET);เพิ่มสองบรรทัดที่ด้านบนของไฟล์นี้
# define ANSI_COLOR_GREEN " x1b [32m "
# define ANSI_COLOR_RESET " x1b [0m " ตอนนี้ออกจากเทอร์มินัล QEMU ที่กด cntrl+A , ปล่อยและพิมพ์ X ทันที (อย่างที่คุณเห็นว่าเป็นงานที่น่าเบื่อและเราจะสร้างการโทรระบบเพื่อออกจากเทอร์มินัล) จากนั้นวิ่ง make qemu-nox อีกครั้งและดูผลลัพธ์ตอนนี้ตอนนี้

การใช้งาน CPU ทั้งสองดูเหมือนจะเป็น 100%เพื่อแก้ไขปัญหานี้ทำตามการปรับเปลี่ยน
ใน proc.c , แก้ไขฟังก์ชัน schduler
void
scheduler ( void )
{
struct proc *p;
int ran;
struct cpu *c = mycpu ();
c-> proc = 0 ;
for (;;){
// Enable interrupts on this processor.
sti ();
// Loop over process table looking for process to run.
acquire (&ptable. lock );
for (ran = 0 , p = ptable. proc ; p < &ptable. proc [NPROC]; p++){
if (p-> state != RUNNABLE)
continue ;
// Switch to chosen process. It is the process's job
// to release ptable.lock and then reacquire it
// before jumping back to us.
ran = 1 ;
c-> proc = p;
switchuvm (p);
p-> state = RUNNING;
swtch (&(c-> scheduler ), p-> context );
switchkvm ();
// Process is done running for now.
// It should have changed its p->state before coming back.
c-> proc = 0 ;
}
release (&ptable. lock );
if (ran == 0 ) {
halt ();
}
}
} และใน x86.h เพิ่มฟังก์ชั่น halt
static inline void
halt ()
{
asm volatile ( " hlt " : : );
} มาสร้างการเรียกระบบเพื่อออกจากเทอร์มินัล QEMU เราตั้งชื่อมันว่าเป็นการ shutdown ดังนั้นเราต้องการทำอะไรบางอย่างที่จะช่วยให้เราออกจากเทอร์มินัลโดยเพียงแค่เขียนคำสั่ง shutdown
ก่อนอื่นสร้างไฟล์ชื่อ shutdown.c
# include " types.h "
# include " stat.h "
# include " user.h "
int main ( int argc, char * argv[])
{
printf ( 1 , " Exiting n " );
shutdown ();
exit (); // eq to return zero
}ขอให้สังเกตว่าในการพิมพ์อะไรในคอนโซลเราจำเป็นต้องเพิ่มตัวอธิบายไฟล์เป็นพารามิเตอร์แรกของ PRINTF ซึ่งแตกต่างจากภาษา C
จากนั้นใน makefile ให้เพิ่มใน uprogs
UPROGS=
_cat
_echo
_forktest
_grep
_init
_kill
_ln
_ls
_mkdir
_rm
_sh
_stressfs
_usertests
_wc
_zombie
_shutdownเพิ่มในพิเศษ
EXTRA=
mkfs.c ulib.c user.h cat.c echo.c forktest.c grep.c kill.c
ln.c ls.c mkdir.c rm.c stressfs.c usertests.c wc.c zombie.c shutdown.c ตอนนี้คุณสามารถออกจากเทอร์มินัล QEMU และเรียกใช้ make qemu-nox อีกครั้งและดูว่า ls จะแสดงรายการการ shutdown ระบบ แต่การเรียกใช้คำสั่งนี้จะไม่ทำอะไรเลยตอนนี้เราได้เพิ่มการโทรระบบนี้ไปยัง 4 ไฟล์ต่อไปนี้
extern int sys_shutdown(void); จากนั้นในบล็อกถัดไปให้เพิ่ม [SYS_shutdown] sys_shutdown,#define SYS_shutdown 23SYSCALL(shutdown)void shutdown(void); ตอนนี้มีสองไฟล์ที่มีวิธีการสำหรับการโทรระบบ sysfile.c มีวิธีการที่เกี่ยวข้องกับไฟล์และ sysproc.c มีวิธีการที่เกี่ยวข้องกับกระบวนการเราต้องเขียนวิธีการใหม่ชื่อ sys_shutdown ใน sysproc.c
void sys_shutdown ( void ){
outw ( 0xB004 , 0x0 | 0x2000 );
outw ( 0x604 , 0x0 | 0x2000 );
} หากทุกอย่างเรียบร้อยดีคุณสามารถออกจาก QEMU ให้เรียกใช้ make qemu-nox และดูการโทร SYTEM ที่มีอยู่โดยเรียกใช้ ls . รันคำสั่ง shutdown และคุณจะเห็นเทอร์มินัลออก

NB : ฉันได้ดำเนินการโทร Sytem อีกสองสามรายการคุณจะไม่เห็น ADD, inc, getSize ฯลฯ ในตอนนี้หากไม่ได้ใช้งาน
ก่อนอื่นให้ปรับเปลี่ยนฟังก์ชั่น atoi ในไฟล์ ulib.c เพื่อให้สามารถจัดการตัวเลขเชิงลบได้เช่นกัน