Tech

เส้นทางใหม่: โปรแกรมจำลอง venix บน vm86

Venix Emulator Update

ฉันมีเวลาทำงานกับโปรแกรมจำลอง Venix มาระยะหนึ่งแล้ว เมื่อฉันทิ้งมันไว้เมื่อกว่าปีที่แล้ว ฉันได้ใช้มันให้ไกลที่สุดเท่าที่จะทำได้ด้วยอีมูเลเตอร์ 8088 ที่ฉันพบทางออนไลน์ มันไม่มีการจำลอง FP และมี

ทำงานผิดปกติหลายอย่างที่ฉันทำไม่ถูก และผู้บริหารก็พิสูจน์ให้เห็นถึงการปฏิบัติได้ยาก แม้จะเขียนด้วย C ++ แต่อีมูเลเตอร์ดั้งเดิมก็ขัดขืนความพยายามของฉันในการสร้างอินสแตนซ์หลาย ๆ อัน

ดังนั้นฉันจึงวางมันไว้เมื่อเดือนพฤษภาคมปีที่แล้ว โดยคิดว่าฉันอาจจะกลับไปใช้เมื่อ qemu bsd- การเปลี่ยนแปลงของผู้ใช้ FreeBSD ได้รับการอัปสตรีมแล้ว

วันแรกของเดือนสิงหาคมฉันหยุดงานและได้รับการเปลี่ยนแปลงรูปร่างของผู้ใช้ bsd เป็นอัปสตรีม นั่นคือ 10% แรกของการเปลี่ยนแปลงที่ยากที่สุด เนื่องจากเป็นการแทนที่สิ่งที่มีด้วยสิ่งที่ได้ผลน้อยที่สุด สิ่งนี้ช่วยให้ฉันเรียนรู้ x86 CPU ของ qemu ดีขึ้นมาก และทำให้ฉันคิดว่าสิ่งที่อยู่ในโหมดผู้ใช้ของ qemu อาจเป็นวิธีที่จะไป

เกี่ยวกับเวลานี้ฉันยังพบโปรแกรมทดสอบ vm86 ในแผนผัง FreeBSD ดังนั้นฉันจึงสงสัยว่าฉันสามารถใช้ Venix vm86 ได้หรือไม่ กล่อง FreeBSD/amd64 ของฉัน และเขียนโปรแกรมทดสอบสั้นๆ สั้นๆ โปรแกรมทดสอบใช้งานได้ “ทำไมไม่ลองดู” ฉันย้าย pcvenix.cc จาก 86sim เป็นไดรฟ์จาก SIGSEGV ในโหมด vm86 สวัสดีชาวโลก ทำงานได้อย่างรวดเร็ว

ป้อน VM86VENIX

ดังนั้นฉันจึงทำใหม่ fork และ exec และ a.out loader เล็กน้อย ฉันสามารถใช้คอมไพเลอร์ C ได้ในการตั้งค่าใหม่นี้ คำสั่ง ‘cc’ เป็นเพียงสคริปต์แฟนซีที่รวมตัวประมวลผลล่วงหน้า คอมไพเลอร์ เครื่องมือเพิ่มประสิทธิภาพ แอสเซมเบลอร์ และลิงเกอร์เข้าด้วยกัน ยกเว้นใน Venix ไม่ใช่เชลล์สคริปต์ที่ฉันสามารถแฮ็คเพื่อเรียกใช้บน FreeBSD ได้ มันเป็นไบนารีแปลก ๆ ที่ทำการฟอร์ก, รัน, เปลี่ยนเส้นทางและอื่น ๆ ในบรรทัด เพิ่มเติมในหนึ่งนาที

ดังนั้นโหมด vm86 จึงเป็นโหมดพิเศษในซีพียู 32 บิตที่ให้คุณรันโค้ด 16 บิตแบบเก่าในบริบทของกระบวนการปกติ ติดตั้งง่ายสุด ๆ แต่มักมีการใช้งานจำกัด

โชคดีที่นักออกแบบ i386 ELF คิดล่วงหน้า ที่อยู่เริ่มต้นสำหรับไบนารีใน ELF คือ 0x00401430 แปลก ๆ ซึ่งสูงกว่า 4MB ซึ่งหมายความว่าสามารถแมปอะไรก็ได้ในหน่วยความจำเหลือน้อยและจะใช้งานได้ FreeBSD มีการหยุดความปลอดภัยในการทำแผนที่ทุกอย่างที่ตำแหน่ง 0 อย่างไรก็ตาม ส่วนที่เหลือของ 4MB แรกจะพร้อมใช้งาน 8086 รุ่นเก่าสามารถมองเห็นได้เพียง 1MiB แรกเท่านั้น แต่เนื่องจากไบนารี Venix อยู่ใน ‘โหมดขนาดเล็ก’ ที่แย่ที่สุด พื้นที่ที่อยู่ที่ใหญ่ที่สุดสำหรับกระบวนการคือ 128kiB มีพื้นที่เหลือเฟือที่จะหาสถานที่เพื่อทำแผนที่

ดังนั้นฉันจึงเขียนตัวโหลดที่จะโหลด Venix a.out ไบนารีเก่าลงในพื้นที่นี้ หรือว่าฉันแฮ็คตัวโหลดที่ฉันต้องทำแผนที่อยู่แล้ว ฉันสามารถใช้รหัสตัวโหลดซ้ำทั้งหมดจากโปรแกรมจำลองที่ใช้ 86sim ที่ฉันเคยมีมาก่อน

จากนั้นฉันก็ขโมยรหัสการติดตั้งจากไบนารีการทดสอบ FreeBSD vm86 ซึ่งน้อยกว่านี้ มากกว่าการสร้างตัวจัดการสัญญาณและทำให้บริบทเป็นศูนย์และตั้งค่าสแต็กและ IP รวมถึงการลงทะเบียนเซกเมนต์ ด้วยสิ่งนี้ในมือ ฉันสามารถใช้ sigreturn() เพื่อตั้งค่าแฟล็กโปรเซสเซอร์ เพื่อให้มันข้ามไปยังตำแหน่งที่ฉันต้องการจะไปใน Venix binary ฉันเคยกลัวโหมด vm86 หลังจากอ่านผ่าน doscmd เมื่อหลายปีก่อน แต่ไม่จำเป็นต้องกลัวอีกต่อไป: cruft ทั้งหมดใน doscmd (ฉันอ่านซ้ำหลังจากนี้) คือการสะสมของ cruft ในช่วงหลายปีที่ผ่านมาสำหรับ DOS, BIOS และอื่นๆ ความแปลกประหลาดที่พัฒนาขึ้นรอบ ๆ IBM PC, XT, AT และโคลนมากมายที่ไม่เกี่ยวข้องกับโหมด vm86 ต่อ se.

ทุกคำสั่ง INT xx จะดักจับไปยังเคอร์เนล . เคอร์เนลจะจดบันทึกการลงทะเบียนและส่งกระบวนการ SIGSEGV สำหรับการเข้าถึงเหล่านี้ ฉันสามารถดู CS:IP ใน mcontext และถอดรหัสคำสั่งที่ผิดพลาดได้ INT xx ถูกเข้ารหัสเป็นไบต์ 0xCD 0xXX สำหรับค่า X เกือบทั้งหมด (INT3 มี opcode 0xCC เป็นของตัวเอง) ในตัวจัดการสัญญาณ ฉันสามารถถอดรหัส opcode นี้ได้ ฉันรู้จากงานที่ผ่านมาว่า INT 0xf1 เป็นการเรียกของระบบ ดังนั้นฉันจึงเชื่อมต่อตัวจัดการการเรียกระบบ venix แบบเก่าเข้ากับสิ่งนี้ และฉันก็กลับมาที่เดิมด้วย 86sim ยิ่งไปกว่านั้น เนื่องจากจุดลอยตัวทำงานได้

ตัวจัดการสัญญาณมี sigreturn โดยปริยายโดยมีบริบทส่งผ่านไปยังตัวจัดการสัญญาณในตอนท้าย ฉันต้องข้ามคำสั่งที่ผิดพลาดหลังจากทำการเรียกระบบ จากนั้นกระบวนการจะดำเนินการต่อในโหมด 16 บิตหลังจาก INT 0xf1 นี่คือการดำเนินการตรงไปตรงมา

ฉันตัดสินใจที่จะใช้ส้อมเป็นส้อมจริง มันจะคัดลอกพื้นที่ที่อยู่, FDs ที่เปิดอยู่ทั้งหมด ฯลฯ ซึ่งพิสูจน์แล้วว่าเป็นวิธีที่ง่ายในการโกง ดังนั้นฉันจึงไม่ต้องสร้างวัตถุบริบทและใช้เธรดเพื่อจำลองกระบวนการ

Exec พิสูจน์แล้วว่าเป็นเพียงการเรียกตัวโหลดของฉันที่เริ่มต้นทั้งหมดนี้ สิ่งเดียวที่ฉันไม่ได้ใช้งานคือปิดใน exec แต่ที่เหลือก็ง่าย

เมื่อใช้งานแล้ว ฉันสามารถเรียกใช้คำสั่ง cc ของคอมไพเลอร์ C และสร้างไบนารีเล็กน้อยได้ แต่ถ้าฉันต้องใส่อะไรเข้าไป มันก็จะล้มเหลว ฉันสร้างตัวแปร env VENIX_ROOT สำหรับการเปิดทั้งหมด มันจะลองใช้ VENIX_ROOT / name แล้วตามด้วยชื่อธรรมดาถ้าชื่อ arg ที่จะเปิดขึ้นต้นด้วย ‘/’ นี้เพียงพอแล้วสำหรับตัวประมวลผลล่วงหน้าที่จะรวมไฟล์ .h และสำหรับ canonical hello world ที่จะสร้าง

มีเพียงปัญหาที่น่ารำคาญ: cc -o hello hello.c ใช้งานได้ อย่างไรก็ตาม cc -O -o สวัสดี hello.c ไม่ได้

การติดตามข้อผิดพลาดที่โง่เขลา

ก็มีอีกสิ่งที่น่ารำคาญ: / bin/sh ไม่ทำงาน ฉันตรวจสอบตามความจริงที่ว่าฉันไม่ได้ใช้งานผ่านสภาพแวดล้อมไปยังกระบวนการ และ /bin/sh กำลังสำลักอยู่ ตกลง. ดี. ฉันจะนำไปใช้ในภายหลัง /bin/csh ทำงานได้ แต่ฉันมีความสุข ความสุขของฉันอยู่ได้ไม่นาน อนิจจา เพราะฉันเรียกใช้คำสั่งและได้ผลลัพธ์แปลกๆ:

% ls
ls: Sig 44

%

มันแปลก. ดังนั้นฉันจึงเพิ่มการติดตาม ฉันลองใช้คำสั่ง cc ซึ่งในเวอร์ชันนี้เป็นโปรแกรมง่ายๆ ที่ประสานส่วนต่างๆ ของคอมไพเลอร์โดยใช้ fork, exec, dup และคู่ปิด/เปิดเชิงกลยุทธ์เพื่อตั้งค่า stdin เป็นต้น การติดตามทั้งหมดก็ดูดีเช่นกัน เรา จะเห็นบางอย่างเช่น:

123: fork() 124
123: wait()

124: … มากมาย
124: ออก 0

123: รอ pid 124 สถานะ 0

จากนั้น 123 จะดำเนินการลบไฟล์ temp ทั้งหมดและออก มันเหมือนกับว่าได้รับข้อผิดพลาดทั้งๆ ที่ลูกๆ ของมันออกมาโดยไม่มีข้อผิดพลาด ทุกครั้งมันเป็นแบบนี้ แต่เมื่อฉันรันตัวเพิ่มประสิทธิภาพเท่านั้น เมื่อฉันเรียกใช้การทดสอบ ls อีกครั้ง ฉันจะได้รับค่า Sig ที่แตกต่างกันด้วย

คอมไพเลอร์ 8086 ที่มีจำหน่ายในปี 1985

ดังนั้น ฉันคิดว่าคอมไพเลอร์นั้นมาจากคอมไพเลอร์ V7 อย่างไรก็ตาม มีคำใบ้หลายชื่อที่บอกว่าไม่ใช่ และคู่มือ Venix มีข้อยกเว้นสำหรับ 8086 มากกว่า pdp-11 เมื่ออธิบายตัวเลือกและการทำงานของ Intel ดังนั้นฉันจึงคิดว่ามันไม่ได้มาจาก V7 ดังนั้นฉันจึงเริ่มค้นหาคอมไพเลอร์ภาษาซี

MIT ได้ผลิตขึ้นสำหรับพีซีทีละตัว มันสามารถทำงานบน VAX และสร้างไบนารี a.out ที่โปรแกรมแปลงจะแปลงเป็นไฟล์ .COM หรือ .EXE ฉันคิดว่านี่อาจเป็นที่มาของคอมไพเลอร์ Venix แต่หลังจากเล่นกับมันสองสามชั่วโมง มันก็ชัดเจนว่ามันไม่ใช่ อย่างแรก มันมีเชลล์สคริปต์ cc ไม่ใช่โปรแกรม ประการที่สอง มีคำสั่งเฉพาะของ VAX จำนวนหนึ่งที่โปรยลงมาในบรรทัด และนั่นจะไม่ทำงานบน Rainbow :).

ฉันดูที่คอมไพเลอร์ C แบบพกพา ฉันคิดว่านี่เป็นต้นกำเนิดที่แท้จริงของสิ่งที่ส่งมาด้วย Venix แต่เวอร์ชันเก่าที่รองรับ 8086 นั้นหาได้ยาก แม้แต่ในโครงการคอมไพเลอร์ C แบบพกพาที่สืบทอดต่อซึ่งดำเนินมาเป็นเวลา 20 ปีแล้ว ฉันได้โปรแกรม cc จากการคอมไพล์ด้วย Venix ง่ายกว่าเล็กน้อยที่จะเอะอะมากกว่า V7 (แต่ V7 จะใกล้พอที่จะตีจุดบกพร่องที่ฉันพบในภายหลัง) เมื่อดูแหล่งข้อมูล System III แบบเก่าที่หาได้ทางอินเทอร์เน็ต จะมีสำเนาของคอมไพเลอร์ C แบบพกพาอยู่ที่นั่น แทนที่จะเป็นคอมไพเลอร์ C จาก DMR อย่างที่คุณจะพบในฉบับที่ 7 ฉันใช้โปรแกรม cc จากที่นั่นเพื่อพยายามสร้างสิ่งต่างๆ ฉันโดนแจ็คพอต: มันล้มเหลวเร็วกว่า!

ดังนั้นฉันจึงใช้เครื่องมือโปรแกรม pcc และพบว่าสถานะที่พิมพ์หลังจาก wait() ในโปรแกรมไม่ตรงกับสถานะที่ฉัน d กลับมาจากเคอร์เนล ความคืบหน้า!

ระบบรอ(2) โทร…

ฉันใช้การเรียกระบบ wait(2) ซึ่งเป็นส่วนหนึ่งของการทำให้ fork/exec ทำงานได้ ฉันทำจากคู่มือ VENIX ที่มีออนไลน์ ฉันดูส่วนแรกของคู่มือนี้:

สรุป

wait(statusp)

int *statusp;

ซึ่งแสดงการรอตัวชี้ ดังนั้นฉันจึงถือว่านี่คือสิ่งที่เคอร์เนลได้รับใน arg แรกที่ส่งผ่านไปยังเคอร์เนล (DX) ฉันคิดว่า DS:DX ชี้ไปที่จำนวนเต็มที่ฉันจะส่งคืนสถานะ โดยส่วนใหญ่ DX เป็นสิ่งที่ดูเหมือนตัวชี้บนสแต็ก ดังนั้นฉันจึงทำสำเนา ปัญหาคือไม่ถูกต้อง

ดังนั้นฉันจึงดูคู่มืออีกครั้ง ในตอนท้ายของ man page ฉันเห็น:

8086 BX=7
int 0xf1

AX=pid ของกระบวนการ

DX=status

แล้วมันก็โดนฉัน DX ไม่ใช่ตัวชี้ไปยังสิ่งใด หลังจาก int 0xf1 AX เป็น pid ของกระบวนการ (ค่าส่งคืนปกติ) และ DX คือสถานะ การแยกส่วน wait.o ยืนยันสิ่งนี้: หาก statusp ไม่ใช่ 0, dx จะถูกคัดลอกกลับไปที่ *statusp โธ่! ตัวชี้แบบคลาสสิกเทียบกับความผิดพลาดของค่า การแก้ไขการใช้งานของฉันเพื่อนำสำเนาออกและแทนที่ด้วยการตั้งค่า DX ในบริบทของตัวประมวลผลทำให้ pcc ทำงานได้ และซีซีก็ทำงาน และโปรแกรมทดสอบโง่ๆ ที่ฉันเขียนไว้ตรงกลางเพื่อแก้ไขข้อบกพร่องต่างๆ ที่ได้ผล Woo Hoo!

เมื่อฉันแก้ไขปัญหานี้แล้ว คอมไพล์แปลก ๆ ของการรวบรวมก็ใช้งานได้ทันที ฉันสามารถเพิ่มประสิทธิภาพ เปลื้องผ้า ฯลฯ และไม่มีสิ่งแปลกประหลาดใดๆ

บทสรุป

การอ่านคู่มืออย่างละเอียดจะช่วยให้อ่านคู่มืออย่างละเอียดได้!

ฉันต้องพยายามสร้างระบบ มีเชลล์สคริปต์ที่ต้องทำซึ่งไม่ขึ้นอยู่กับตัวแปรสภาพแวดล้อมที่ทำงานหากเรียกใช้โดยกำเนิด ดังนั้นฉันจะดูว่าทำงานได้หรือไม่และดูว่าระบบที่ฉันสามารถสร้างผ่านเส้นทางนี้ได้มากเพียงใด คอยติดตาม

รายการสิ่งที่ต้องทำของฉันยังคงมีการเริ่มใช้งาน env (ฉันไม่คิดว่ามันยาก แต่ฉันคิดว่าฉันต้องกรองสิ่งต่าง ๆ เนื่องจาก env เริ่มต้นของฉันมีขนาดใหญ่กว่า กองบนเครื่อง x86 เก่าเหล่านี้) ฉันยังต้องดูการปรับฐานอีมูเลเตอร์ของฉันเป็น *-user qemu emulator (แม้ว่าพวกเขาจะไม่ใช้อัพสตรีมก็ตาม) บางทีอาจเพิ่มการรองรับ PC/IX และ Xenix/86 เพื่อให้นักวิจัยคนอื่นๆ ได้ลองเล่นดู

จังหวัดตรังủ

  • ธุรกิจ
  • อาหาร ไลฟ์สไตล์

  • เทค
  • กลยุทธ์การตลาดดิจิทัล (การตลาดดิจิทัล)

    Back to top button