Linux-0.11
หลักสูตรทฤษฎี: https://www.bilibili.com/video/bv1d4411v7u7
การอ้างอิงที่เป็นประโยชน์ ( Linux-0.11 เวอร์ชันแสดงความคิดเห็น): https://github.com/beride/linux0.11-1
สาขาหลัก คือ Linux-0.11 ซอร์สโค้ด
ดูความแตกต่างของรหัส: คำขอดึงเลือกสาขาที่เกี่ยวข้องและเปรียบเทียบกับหลัก
✔การบูตระบบปฏิบัติการ LAB0 (Branch Lab0)
การเขียน bootsect.s ใหม่ส่วนใหญ่ทำฟังก์ชั่นต่อไปนี้:
- bootsect.s สามารถพิมพ์ข้อความ "xxx กำลังบูท ... " บนหน้าจอ
การตั้งค่าการตั้งค่าใหม่ส่วนใหญ่ทำฟังก์ชั่นต่อไปนี้:
- Bootsect.s สามารถทำการโหลดการตั้งค่าและข้ามไปที่การตั้งค่าเริ่มต้นที่อยู่การดำเนินการ และ Setup.s เอาต์พุตบรรทัด "ตอนนี้เราอยู่ในการตั้งค่า" ไปยังหน้าจอ Setup.s สามารถรับพารามิเตอร์ฮาร์ดแวร์พื้นฐานอย่างน้อยหนึ่งพารามิเตอร์ (เช่นพารามิเตอร์หน่วยความจำพารามิเตอร์การ์ดกราฟิกพารามิเตอร์ฮาร์ดดิสก์ ฯลฯ ) จัดเก็บไว้ในที่อยู่เฉพาะในหน่วยความจำและส่งออกไปยังหน้าจอ Setup.s ไม่โหลดเคอร์เนล Linux อีกต่อไปเพียงเก็บข้อมูลด้านบนที่แสดงบนหน้าจอ
หนังสือแนะนำการทดลอง: https://www.lanqiao.cn/courses/115/labs/568/document/
✔ LAB1 ใช้การโทรของระบบ (Branch Lab1)
- จำนวนการโทรทั้งหมดของระบบที่แก้ไขในเคอร์เนล/system_call.s คือ 74
- เพิ่มมาโครในการรวม/unistd.h เพื่อระบุตำแหน่งตารางฟังก์ชั่นการโทร
- เขียนสองฟังก์ชั่น (SYS_IAM, SYS_WHOAMI) คำจำกัดความฟังก์ชันใน Intive/Linux/Sys.H และเพิ่มฟังก์ชั่นใหม่สองฟังก์ชั่นลงในตารางฟังก์ชั่นหลังจากนั้น
- เพิ่มเคอร์เนล/who.c เพื่อใช้การโทรสองระบบ
- แก้ไข makefile
- OBJs เพิ่มผู้ที่พึ่งพา (ใคร)
- เพิ่มเงื่อนไขการสร้างการพึ่งพาสำหรับ who.s และ who.o ในการพึ่งพา
- ทำให้ Execute ./run เข้าสู่ระบบย่อย Linux และเพิ่มคำจำกัดความแมโครของ IAM และ Whoami ใน /usr/include/unistd.h (เหมือนกับจุดที่ 2)
- การเขียนโปรแกรมทดสอบในการทดสอบสถานะผู้ใช้ว่าประสบความสำเร็จหรือไม่
หนังสือแนะนำการทดลอง: https://www.lanqiao.cn/courses/115/labs/569/document/
✔ LAB2 ใช้การติดตามวิถีการทำงานของกระบวนการ (Branch Lab2)
- Process.C ใช้สถานการณ์ที่จำลองการคำนวณ CPU แบบไฮบริดและการคำนวณ IO และทำงานในลักษณะหลายกระบวนการ
- พิมพ์หลายสถานะของการสลับกระบวนการเคอร์เนล (เวลาสถานะ PID) ถึง /var/process.log
- หลังจากฟังก์ชั่น init () ใน init/main เข้าสู่คำสั่งสถานะผู้ใช้, ไฟล์เชื่อมโยงไฟล์ descriptor 3 ถึง /var/process.log
- ใช้ฟังก์ชั่น fprintk () ในเคอร์เนล/printk เพื่อพิมพ์เอาต์พุตไปยัง process.log log
- ค้นหาจุดสลับสถานะและเพิ่ม fprintk () เพื่อเขียนบันทึก
- กระบวนการเริ่มต้นเคอร์เนล/system_call.s -> sys_fork (โทร copy_process)
- เรียกใช้, การปิดกั้นสถานะสวิตช์เคอร์เนล/sched.c -> กำหนดเวลา sys_pause sleep_on interruptible_sleep_on wake_up
- ออกจากเคอร์เนล/exit.c -> do_exit sys_waitpid
- หมายเหตุ: GCC ใน Linux-0.11 ไม่สามารถรวบรวมได้ // แสดงความคิดเห็น
หนังสือแนะนำการทดลอง: https://www.lanqiao.cn/courses/115/labs/570/document/
✔ LAB3 แทนที่กระบวนการ TSS ดั้งเดิมใน Linux0.11 เพื่อสลับไปที่การสลับสแต็ก (Branch Lab3)
วิธีการสลับดั้งเดิมคือผ่าน TSS ซึ่งเทียบเท่ากับภาพรวมของการลงทะเบียน มันจะถูกแทนที่โดยตรงในสถานที่ผ่านคำแนะนำที่ได้รับจาก Intel ซึ่งช้ากว่า การสลับสแต็กมีประสิทธิภาพมากขึ้น
เคอร์เนล/sched.c
- วิธี Switch_to ดั้งเดิมนั้นใช้สวิตช์ TSS และเราต้องการแสดงความคิดเห็นในไฟล์ส่วนหัว
- ใหม่ switch_to ต้องใช้พารามิเตอร์สองพารามิเตอร์ (1: ตัวชี้ไปยัง PCB 2 ถัดไป: ตำแหน่งของงานถัดไปในอาร์เรย์ใช้เพื่อสลับ LDT)
เคอร์เนล/system_call.s
- เขียนการใช้งานแอสเซมบลี switch_to
- การสลับ PCB
- เขียนตำแหน่งสแต็กเคอร์เนล TSS ใหม่ (TSS ยังคงอยู่ในเวลานี้ แต่มีเพียงหนึ่ง TSS ในโลกและไม่ได้ใช้ในการเปลี่ยนกระบวนการ)
- สลับสแต็คเคอร์เนล
- สวิตช์ LDT
เคอร์เนล/fork.c
- ออกจากระบบการตั้งค่า TSS ใน PCB
- เพิ่มตัวแปรสมาชิกใหม่ - เคอร์เนลสแต็กลงใน PCB ซึ่งใช้ในการจัดเก็บข้อมูลสแต็กเคอร์เนล
- เขียนข้อมูลสแต็กที่นี่และให้ PCB ตัวแปรสมาชิกชี้ไปที่ตัวชี้
หนังสือแนะนำการทดลอง: https://www.lanqiao.cn/courses/115/labs/571/document/
การอ้างอิง: https://blog.csdn.net/qq_42518941/article/details/119182097
✔ LAB4 ใช้การเรียกระบบ Semaphore ใน Linux0.11 (Branch Lab4)
คะแนนความรู้ล่วงหน้าคีย์
- เคอร์เนล/sched.c sleep_on ผ่านส่วนหัวคิวรอที่เข้ามาตั้งค่าปัจจุบันเป็นการปิดกั้นสถานะและดำเนินการกำหนดเวลา () TMP เก็บคิวการบล็อกดั้งเดิม เมื่อตื่นขึ้นมาคิวการปิดกั้นจะถูกเรียกใช้ให้ทำงานได้
- Kernel/Sched.C Wake_up ปลุก PCB ที่ถูกบล็อกทั้งหมด เฉพาะหัวหน้าทีมปลุกเท่านั้นที่สามารถเห็นได้ในโปรแกรม แต่จะต้องอ่านร่วมกับ Sleep_on เมื่อรวมกันแล้วคุณจะพบว่าหัวปลุกจะตื่นขึ้นมาทั้งหมดในภายหลัง
เขียนแอปพลิเคชัน "PC.C" เพื่อแก้ปัญหาผู้ผลิต-ผู้บริโภคคลาสสิกและทำฟังก์ชั่นต่อไปนี้ให้สมบูรณ์:
- สร้างกระบวนการผู้ผลิตกระบวนการของผู้บริโภค (n> 1)
- สร้างบัฟเฟอร์ที่ใช้ร่วมกันพร้อมไฟล์
- กระบวนการผู้ผลิตเขียนจำนวนเต็ม 0, 1, 2, …, m, m, m> = 500 ไปยังบัฟเฟอร์ในทางกลับกัน
- กระบวนการของผู้บริโภคอ่านจากบัฟเฟอร์อ่านทีละครั้งและลบหมายเลขการอ่านออกจากบัฟเฟอร์จากนั้นส่งออกรหัสกระบวนการและ + ไปยังเอาต์พุตมาตรฐาน
- บัฟเฟอร์สามารถบันทึกได้สูงสุด 10 หมายเลขในเวลาเดียวกัน
ใช้งาน Semaphore
sem_t * sem_open ( const char * name , unsigned int value );
int sem_wait ( sem_t * sem );
int sem_post ( sem_t * sem );
int sem_unlink ( const char * name );
- SEM_OPEN เปิดสัญญาณ
- หากเซมาฟอร์มีค่าเท่ากับศูนย์การปิดกั้นกระบวนการ
- เพิ่มหนึ่งเซมาฟอร์
- ปิดเซมาฟอร์
จุดสนใจของการรอคอยและโพสต์
- รอ
- โทรไปที่เคอร์เนล/sched.c sleep_on เพื่อรอการบล็อก
- ใช้การขัดจังหวะ Linux (Linux0.11 Single Core) เพื่อป้องกันโซนวิกฤต
- ลบค่าหนึ่งของ SEM
- โพสต์
- เพิ่มหนึ่งในค่าของ SEM หากค่ามากกว่า 0 ให้โทรเคอร์เนล/sched.c wake_up เพื่อปลุกกระบวนการที่ถูกบล็อกโดยสัญญาณนี้
- ใช้การขัดจังหวะ Linux (Linux0.11 Single Core) เพื่อป้องกันโซนวิกฤต
หนังสือแนะนำการทดลอง: https://www.lanqiao.cn/courses/115/labs/572/document/
✔การทำแผนที่และการแบ่งปันที่อยู่ LAB5 (Branch Lab5)
ที่อยู่โลจิคัล -> gdt -> ldt -> ตารางหน้า -> ที่อยู่ทางกายภาพ
ความรู้ทฤษฎีเครื่องมือ
ตัวเลือกส่วน
การเข้าถึงตาราง descriptor ส่วนกลางโดย GDTR ทำได้ผ่าน "เซ็กเมนต์ตัวเลือก" (เซ็กเมนต์ลงทะเบียนในโหมดจริง)
15 3 2 1 0
- ดัชนี | - RPL |
- 3-15 เป็นดัชนี descriptor ซึ่งระบุตัวบ่งชี้ของเซ็กเมนต์ที่ต้องการในตาราง descriptor
- 2 เพื่อระบุว่าตัวเลือกถูกเลือกใน GDT หรือใน LDT (0 หมายถึง GDT 1 หมายถึง LDT)
- 0-1 คือระดับสิทธิพิเศษในการเลือก
ตัวเลือกเซ็กเมนต์ประกอบด้วยสามส่วน: ดัชนี descriptor (ดัชนี), TI และระดับสิทธิพิเศษขอ (RPL) ชิ้นส่วนดัชนี (ดัชนี descriptor) ระบุตัวบ่งชี้ของเซ็กเมนต์ที่ต้องการในตำแหน่งตาราง descriptor จากตำแหน่งนี้ตัวบ่งชี้ที่สอดคล้องกันสามารถพบได้ตามที่อยู่ฐานตาราง descriptor ที่เก็บไว้ใน GDTR จากนั้นที่อยู่ฐานส่วนเซ็กเมนต์ในตาราง descriptor บวกกับที่อยู่โลจิคัล (SEL: Offset) สามารถแปลงเป็นที่อยู่เชิงเส้นได้ ค่า TI ในตัวเลือกเซ็กเมนต์เป็นเพียงหนึ่ง 0 หรือ 1 0 หมายถึงตัวเลือกถูกเลือกใน GDT และ 1 หมายความว่าตัวเลือกถูกเลือกใน LDT ระดับสิทธิ์การร้องขอ (RPL) แสดงถึงระดับสิทธิพิเศษของตัวเลือกและมี 4 ระดับสิทธิพิเศษ (ระดับ 0, ระดับ 1, ระดับ 2 และระดับ 3)
หมายเหตุเกี่ยวกับระดับสิทธิพิเศษ: แต่ละเซ็กเมนต์ในงานมีระดับเฉพาะ เมื่อใดก็ตามที่โปรแกรมพยายามเข้าถึงเซ็กเมนต์ระดับสิทธิพิเศษที่โปรแกรมได้เปรียบเทียบกับระดับสิทธิพิเศษที่จะเข้าถึงเพื่อตรวจสอบว่าสามารถเข้าถึงเซ็กเมนต์ได้หรือไม่ อนุสัญญาระบบคือ CPU สามารถเข้าถึงเซ็กเมนต์ของระดับสิทธิพิเศษเดียวกันหรือในระดับสิทธิพิเศษที่ต่ำกว่า
ตัวอย่างเช่นให้ที่อยู่ตรรกะ: 21H: 12345678H แปลงเป็นที่อยู่เชิงเส้น
. ตัวเลือก SEL = 21H = 0000000000100 0 01 (b) หมายถึง: ดัชนีของตัวเลือก = 4 นั่นคือ 0100 และตัวอธิบายที่สี่ใน GDT ถูกเลือก; Ti = 0 หมายความว่าตัวเลือกถูกเลือกใน GDT; 01 สุดท้ายหมายถึงระดับสิทธิพิเศษ RPL = 1
ข. Offset = 12345678H หากที่อยู่ฐานส่วนที่อธิบายไว้ในตัวอธิบายที่สี่ของ GDT ในเวลานี้คือ 1111111H ดังนั้นที่อยู่เชิงเส้น = 111111H + 12345678H = 23456789H
เยี่ยมชม GDT
- ก่อนอื่นรับที่อยู่ฐาน GDT จากการลงทะเบียน GDTR
- จากนั้นใน GDT ตัวบ่งชี้เซ็กเมนต์จะมีมูลค่าที่ตัวเลือกเซ็กเมนต์สูงดัชนีตำแหน่ง 13 บิต
- รับที่อยู่พื้นฐานเพิ่มออฟเซ็ตเพื่อรับที่อยู่เชิงเส้น
เข้าถึง LDT
- ก่อนอื่นรับที่อยู่ฐาน GDT จากการลงทะเบียน GDTR
- รับดัชนีตำแหน่งของเซ็กเมนต์ที่ LDT อยู่จากการลงทะเบียน LDTR (LDTR สูงกว่า 13 บิต)
- ตัวอธิบายเซ็กเมนต์ LDT ได้รับใน GDT ด้วยดัชนีตำแหน่งนี้เพื่อรับที่อยู่ฐานส่วน LDT
- ใช้ตัวเลือกเซ็กเมนต์เพื่อรับตัวบ่งชี้เซ็กเมนต์จากเซ็กเมนต์ LDT
- รับที่อยู่พื้นฐานเพิ่มออฟเซ็ตเพื่อรับที่อยู่เชิงเส้น
หนังสือแนะนำการทดลอง: https://www.lanqiao.cn/courses/115/labs/573/document/
✔การควบคุมอุปกรณ์เทอร์มินัล LAB6 (Branch Lab6)
- เมื่อการขัดจังหวะแป้นพิมพ์เกิดขึ้นรหัสสแกนแป้นพิมพ์จะถูกลบออกและรหัสการสแกนจะถูกประมวลผลตามตาราง key_table
- กรอกฟังก์ชั่นการเขียนสำหรับคีย์ F12
- หลังจากการประมวลผลใส่อักขระด้วยรหัสสแกนที่เกี่ยวข้องลงใน Put_queue
- โทรหา do_tty_interrupt สำหรับการประมวลผลขั้นสุดท้ายโดยที่ copy_to_cooked ทำการประมวลผลล่วงหน้าขั้นสุดท้ายจากนั้นเรียก con_write เพื่อส่งออกไปยังกราฟิกการ์ด
- เขียน -> sys_write -> tty_write -> con_write
หนังสือแนะนำการทดลอง: https://www.lanqiao.cn/courses/115/labs/574/document/
✔การใช้งานระบบไฟล์ LAB7 PROC (Branch Lab7)
ความรู้ทางทฤษฎี
ดิสก์
การอ่านและการเขียนดิสก์เชิงกลต้องใช้พารามิเตอร์สามตัวในการค้นหา
- กระบอกสูบ (C)
- หัว (h)
- ภาค
block = C * ( H * S ) + H * S + S ;
การแบ่งหลายภาคส่วนเป็นหนึ่งบล็อกเพื่อปรับปรุงประสิทธิภาพของดิสก์ IO (Linux0.11 แบ่ง 2 ภาคออกเป็นหนึ่งบล็อก) สำหรับระดับที่สูงขึ้นคุณจะต้องป้อนหมายเลขการอ่านและเขียนบล็อกเพื่อดำเนินการดิสก์ IO
ส่วน: boot block | Super Block | inode bitmap | ข้อมูลบิตแมป | บล็อก inode | บล็อกข้อมูล
เอกสาร
ใช้ FCB (Inode ใน Linux0.11) เพื่อจัดเก็บข้อมูลไฟล์รวมถึงไฟล์ประเภทต่าง ๆ (ตัวอย่างเช่น: ไฟล์อุปกรณ์ไฟล์ไดเรกทอรี ... )
struct m_inode
{
unsigned short i_mode ; // 文件类型和属性(rwx 位)。
unsigned short i_uid ; // 用户id(文件拥有者标识符)。
unsigned long i_size ; // 文件大小(字节数)。
unsigned long i_mtime ; // 修改时间(自1970.1.1:0 算起,秒)。
unsigned char i_gid ; // 组id(文件拥有者所在的组)。
unsigned char i_nlinks ; // 文件目录项链接数。
unsigned short i_zone [ 9 ]; // 直接(0-6)、间接(7)或双重间接(8)逻辑块号。
/* these are in memory also */
struct task_struct * i_wait ; // 等待该i 节点的进程。
unsigned long i_atime ; // 最后访问时间。
unsigned long i_ctime ; // i 节点自身修改时间。
unsigned short i_dev ; // i 节点所在的设备号。
unsigned short i_num ; // i 节点号。
unsigned short i_count ; // i 节点被使用的次数,0 表示该i 节点空闲。
unsigned char i_lock ; // 锁定标志。
unsigned char i_dirt ; // 已修改(脏)标志。
unsigned char i_pipe ; // 管道标志。
unsigned char i_mount ; // 安装标志。
unsigned char i_seek ; // 搜寻标志(lseek 时)。
unsigned char i_update ; // 更新标志。
}; หมายเลขบล็อกของไฟล์บนดิสก์จะถูกเก็บไว้ใน Inode และข้อมูลคำอธิบายไฟล์อื่น ๆ อาจมีคำแนะนำตำแหน่งตำแหน่งบล็อกดิสก์หลายระดับซึ่งแบ่งออกเป็นดัชนีโดยตรงและดัชนีทางอ้อมเพื่อให้ได้ตำแหน่งบล็อก
สารบัญ
ค้นหาข้อมูลในหมายเลขบล็อกดิสก์ข้อมูลที่สอดคล้องกันตามไดเรกทอรี inode ซึ่งมีหมายเลขบล็อกดิสก์ inode ของไดเรกทอรีย่อยที่มีอยู่ในไดเรกทอรี ค้นหาเลเยอร์ด้วยเลเยอร์และคุณสามารถค้นหาตำแหน่งของไดเรกทอรีเป้าหมายสุดท้าย
หนังสือแนะนำการทดลอง: https://www.lanqiao.cn/courses/115/labs/575/document/