*หากพารามิเตอร์ของโปรแกรมผู้ใช้ชี้ไปที่ส่วนหนึ่งของหน่วยความจำในหน้า 3 (หน้าสุดท้าย) มีความขัดแย้งเนื่องจากเคอร์เนลจะแมปหน้า RAM ของมันในหน้าเดียวกันนี้ในระหว่าง syscall ดังนั้นจะทำการปรับปรุงหน้า 3 ของผู้ใช้ในหน้า 2 (หน้าสาม) เพื่อเข้าถึงพารามิเตอร์ของโปรแกรม แน่นอนว่าในกรณีที่พารามิเตอร์เป็นพอยน์เตอร์พวกเขาจะได้รับการแก้ไขเพื่อให้พวกเขาชี้ไปที่ที่อยู่เสมือนใหม่ (กล่าวอีกนัยหนึ่งตัวชี้จะถูกลบด้วย 16KB เพื่อให้มันชี้ไปที่หน้า 2)
เพื่อให้สามารถพอร์ตระบบปฏิบัติการ 8 บิตไปยังคอมพิวเตอร์ที่ใช้ Z80 ที่ไม่มี MMU/หน่วยความจำ Mapper ที่จัดขึ้นตามที่แสดงไว้ด้านบนเคอร์เนลมีโหมดใหม่ที่สามารถเลือกได้ผ่าน menuconfig : NO-MMU
ในโหมดนี้รหัส OS ยังคงคาดว่าจะแมปในหน่วยความจำ 16KB แรกจาก 0x0000 ถึง 0x3FFF และส่วนที่เหลือคาดว่าจะเป็น RAM
ตามหลักการแล้ว RAM 48KB ควรถูกแมปเริ่มต้นที่ 0x4000 และจะสูงถึง 0xFFFF แต่ในทางปฏิบัติมันเป็นไปได้ที่จะกำหนดค่าเคอร์เนลให้คาดหวังน้อยกว่านั้น ในการทำเช่นนั้นจะต้องมีการกำหนดค่าสองรายการใน menuconfig อย่างเหมาะสม:
KERNEL_STACK_ADDR : นี่เป็นจุดสิ้นสุดของพื้นที่เคอร์เนล RAM และตามที่ระบุชื่อของมันจะเป็นด้านล่างของเคอร์เนลสแต็คKERNEL_RAM_START : นี่เป็นเครื่องหมายจุดเริ่มต้นของเคอร์เนล RAM ที่สแต็กตัวแปรทั้งหมดที่ใช้โดยเคอร์เนลและไดรเวอร์จะถูกเก็บไว้ แน่นอนว่าต้องมีขนาดใหญ่พอที่จะเก็บข้อมูลเหล่านี้ทั้งหมด สำหรับข้อมูลขนาดส่วน BSS เคอร์เนลปัจจุบันอยู่ที่ประมาณ 1KB ความลึกของสแต็คขึ้นอยู่กับการใช้งานของไดรเวอร์เป้าหมาย การจัดสรร 1KB สำหรับสแต็กควรมีมากเกินพอตราบเท่าที่ไม่มีการเก็บบัฟเฟอร์ (ใหญ่) ไว้ การจัดสรรโดยรวมอย่างน้อย 3KB สำหรับเคอร์เนล RAM ควรปลอดภัยและพิสูจน์ได้ในอนาคตโดยสรุปนี่คือไดอะแกรมเพื่อแสดงการใช้หน่วยความจำ:
เกี่ยวกับโปรแกรมผู้ใช้ที่อยู่สแต็กจะถูกตั้งค่าเป็น KERNEL_RAM_START - 1 โดยเคอร์เนลก่อนดำเนินการ นอกจากนี้ยังสอดคล้องกับที่อยู่ของไบต์สุดท้ายที่มีอยู่ในพื้นที่ที่อยู่ที่ใช้งานได้ ซึ่งหมายความว่าโปรแกรมสามารถกำหนดขนาดของ RAM ที่มีอยู่ได้โดยการดำเนินการ SP - 0x4000 ซึ่งให้ในการประกอบ:
ld hl, 0
add hl, sp
ld bc, -0x4000
add hl, bc
; HL contains the size of the available RAM for the program, which includes the program's code and its stack.
Z80 นำเสนอการลงทะเบียนอเนกประสงค์ทั่วไปหลายรายการไม่ใช่ทั้งหมดที่ใช้ในเคอร์เนลนี่คือขอบเขตของแต่ละคน:
| ลงทะเบียน | ขอบเขต |
|---|---|
| AF, BC, DE, HL | ระบบและแอปพลิเคชัน |
| af ', bc', de ', hl' | ตัวจัดการขัดจังหวะ |
| ix, iy | แอปพลิเคชัน (ไม่ได้ใช้ในระบบปฏิบัติการ) |
ซึ่งหมายความว่าระบบปฏิบัติการจะไม่เปลี่ยนแปลง IX และ IY ลงทะเบียนดังนั้นพวกเขาจึงสามารถใช้งานได้อย่างอิสระในแอปพลิเคชัน
อาจใช้การลงทะเบียนสำรอง (ชื่อตามด้วย ' ) เฉพาะในตัวจัดการขัดจังหวะ 1 แอปพลิเคชันไม่ควรใช้การลงทะเบียนเหล่านี้ หากด้วยเหตุผลบางอย่างคุณยังต้องใช้พวกเขาโปรดพิจารณาปิดการใช้งานการขัดจังหวะในช่วงเวลาที่พวกเขาใช้:
my_routine:
di ; disable interrupt
ex af, af' ; exchange af with alternate af' registers
[...] ; use af'
ex af, af' ; exchange them back
ei ; re-enable interrupts
โปรดทราบว่าการปิดการใช้งานการขัดจังหวะเป็นเวลานานเกินไปอาจเป็นอันตรายได้เนื่องจากระบบจะไม่ได้รับสัญญาณใด ๆ จากฮาร์ดแวร์ (ตัวจับเวลา, แป้นพิมพ์, GPIOS ... )
Z80 จัดเตรียมเวกเตอร์รีเซ็ต 8 ตัวที่แตกต่างกันเนื่องจากระบบมีความหมายที่จะเก็บไว้ในหน้าเสมือนจริงของหน่วยความจำแรกเสมอเหล่านี้สงวนไว้สำหรับระบบปฏิบัติการ:
| เวกเตอร์ | การใช้งาน |
|---|---|
| $ 00 | รีเซ็ตซอฟต์แวร์ |
| $ 08 | syscall |
| $ 10 | ข้ามไปที่ที่อยู่ใน HL (สามารถใช้สำหรับการโทร HL) |
| $ 18 | ไม่ได้ใช้ |
| $ 20 | ไม่ได้ใช้ |
| $ 28 | ไม่ได้ใช้ |
| $ 30 | ไม่ได้ใช้ |
| $ 38 | สงวนไว้สำหรับโหมดขัดจังหวะ 1 ใช้งานได้โดยการใช้งานเป้าหมาย |
เมื่อมีการดำเนินการโปรแกรมผู้ใช้เคอร์เนลจะจัดสรร RAM 3 หน้า (48KB) อ่านไฟล์ไบนารีเพื่อดำเนินการและโหลดเริ่มต้นที่ที่อยู่เสมือน 0x4000 โดยค่าเริ่มต้น จุดเริ่มต้นที่อยู่เสมือนนี้สามารถกำหนดค่าได้ผ่าน menuconfig พร้อมตัวเลือก KERNEL_INIT_EXECUTABLE_ADDR แต่โปรดจำไว้ว่าโปรแกรมที่มีอยู่จะไม่ทำงานอีกต่อไป
ดังที่อธิบายไว้ด้านล่าง exec SYSCALL ใช้สองพารามิเตอร์: ชื่อไฟล์ไบนารีเพื่อดำเนินการและพารามิเตอร์
พารามิเตอร์นี้จะต้องเป็นสตริงที่มีการสิ้นสุดที่เป็นโมฆะซึ่งจะถูกคัดลอกและส่งไปยังไบนารีเพื่อดำเนินการผ่านการลงทะเบียน DE และ BC :
DE มีที่อยู่ของสตริง สตริงนี้จะถูกคัดลอกไปยังพื้นที่หน่วยความจำของโปรแกรมใหม่โดยปกติจะอยู่ด้านบนของสแต็กBC มีความยาวของสตริงนั้น (ดังนั้นไม่รวม Null-byte) หาก BC เป็น 0 DE ยกเลิก โปรแกรมผู้ใช้ ระบบอาศัย SyScalls เพื่อดำเนินการตามคำขอระหว่างโปรแกรมผู้ใช้และเคอร์เนล ดังนั้นนี่จะเป็นวิธีการดำเนินการกับฮาร์ดแวร์ การดำเนินการที่เป็นไปได้แสดงอยู่ในตารางด้านล่าง
| จำนวน | ชื่อ | พารามิเตอร์ 1 | พารามิเตอร์ 2 | พารามิเตอร์ 3 |
|---|---|---|---|---|
| 0 | อ่าน | u8 dev | U16 BUF | ขนาด U16 |
| 1 | เขียน | u8 dev | U16 BUF | ขนาด U16 |
| 2 | เปิด | ชื่อ U16 | ธง U8 | |
| 3 | ปิด | u8 dev | ||
| 4 | DSTAT | u8 dev | U16 DST | |
| 5 | สถิติ | ชื่อ U16 | U16 DST | |
| 6 | แสวงหา | u8 dev | u32 ชดเชย | u8 เมื่อใด |
| 7 | ioctl | u8 dev | U8 CMD | u16 arg |
| 8 | mkdir | เส้นทาง U16 | ||
| 9 | chdir | เส้นทาง U16 | ||
| 10 | เสียงอึกทึกครึกโครม | เส้นทาง U16 | ||
| 11 | Opendir | เส้นทาง U16 | ||
| 12 | readdir | u8 dev | U16 DST | |
| 13 | RM | เส้นทาง U16 | ||
| 14 | ติดตั้ง | u8 dev | จดหมาย U8 | u8 fs |
| 15 | การออก | รหัส U8 | ||
| 16 | ผู้บริหาร | ชื่อ U16 | u16 argv | |
| 17 | จุ่ม | u8 dev | u8 ndev | |
| 18 | msleep | ระยะเวลา U16 | ||
| 19 | ช่วงเวลา | u8 id | เวลา u16 | |
| 20 | รับช่วงเวลา | u8 id | เวลา u16 | |
| 21 | การตั้งค่า | U16 วันที่ | ||
| 22 | getDate | U16 วันที่ | ||
| 23 | แผนที่ | U16 DST | U24 src | |
| 24 | แลกเปลี่ยน | u8 dev | u8 ndev |
โปรดตรวจสอบส่วนด้านล่างสำหรับข้อมูลเพิ่มเติมเกี่ยวกับการโทรแต่ละครั้งและพารามิเตอร์ของพวกเขา
หมายเหตุ : syscalls บางตัวอาจไม่ได้รับการปรับปรุง ตัวอย่างเช่นในคอมพิวเตอร์ที่ไม่ได้รับการสนับสนุนไดเรกทอรีอาจละเว้น syscalls ที่เกี่ยวข้องกับไดเรกทอรี
ในการดำเนินการ syscall หมายเลขการดำเนินการจะต้องเก็บไว้ในการลงทะเบียน L พารามิเตอร์จะต้องเก็บไว้ตามกฎเหล่านี้:
| ชื่อพารามิเตอร์ใน API | Z80 ลงทะเบียน |
|---|---|
| u8 dev | H |
| u8 ndev | E |
| ธง U8 | H |
| U8 CMD | C |
| จดหมาย U8 | D |
| รหัส U8 | H |
| u8 fs | E |
| u8 id | H |
| u8 เมื่อใด | A |
| U16 BUF | DE |
| ขนาด U16 | BC |
| ชื่อ U16 | BC |
| U16 DST | DE |
| u16 arg | DE |
| เส้นทาง U16 | DE |
| u16 argv | DE |
| ระยะเวลา U16 | DE |
| เวลา u16 | DE |
| U16 วันที่ | DE |
| U24 src | HBC |
| u32 ชดเชย | BCDE |
และในที่สุดรหัสจะต้องดำเนินการคำสั่ง RST $08 (โปรดตรวจสอบการรีเซ็ตเวกเตอร์)
ค่าที่ส่งคืนจะถูกวางไว้ใน A. ความหมายของค่านั้นเฉพาะสำหรับการโทรแต่ละครั้งโปรดตรวจสอบเอกสารของรูทีนที่เกี่ยวข้องสำหรับข้อมูลเพิ่มเติม
เพื่อเพิ่มความเข้ากันได้ของโปรแกรมผู้ใช้กับเคอร์เนล 8 บิตที่กระตือรือร้นโดยไม่คำนึงว่าเคอร์เนลถูกรวบรวมในโหมด MMU หรือ NO-MMU ข้อ จำกัด ของพารามิเตอร์ SyScalls จะเหมือนกัน:
บัฟเฟอร์ใด ๆ ที่ส่งผ่านไปยัง syscall จะ ไม่ ข้ามหน้าเสมือน 16kb
กล่าวอีกนัยหนึ่งถ้า buf ขนาด n ตั้งอยู่ในหน้าเสมือนจริง i ไบต์สุดท้ายของมันชี้ไปที่ buf + n - 1 จะต้องอยู่ในหน้าเดียวกันที่แน่นอน i
ตัวอย่างเช่นหาก read Syscall ด้วย:
DE = 0x4000 และ BC = 0x1000 พารามิเตอร์นั้น ถูกต้อง เนื่องจากบัฟเฟอร์ที่ชี้ด้วย DE พอดีกับหน้า 1 (จาก 0x4000 ถึง 0x7FFF )DE = 0x4000 และ BC = 0x4000 พารามิเตอร์ถูก ต้อง เนื่องจากบัฟเฟอร์ที่ชี้ด้วย DE พอดีในหน้า 1 (จาก 0x4000 ถึง 0x7FFF )DE = 0x7FFF และ BC = 0x2 พารามิเตอร์ ไม่ถูกต้อง เนื่องจากบัฟเฟอร์ที่ชี้โดย DE อยู่ในระหว่างหน้า 1 และหน้า 2exec แม้ว่าระบบปฏิบัติการ 8 บิต Zeal เป็นระบบปฏิบัติการแบบโมโนทำงาน แต่ก็สามารถดำเนินการและเก็บโปรแกรมหลายโปรแกรมไว้ในหน่วยความจำ เมื่อโปรแกรม A ดำเนินการโปรแกรม B ขอบคุณ exec SyScall มันจะให้พารามิเตอร์ mode ที่สามารถเป็น EXEC_OVERRIDE_PROGRAM หรือ EXEC_PRESERVE_PROGRAM :
EXEC_OVERRIDE_PROGRAM : ตัวเลือกนี้บอกเคอร์เนลว่าโปรแกรม A ไม่จำเป็นต้องดำเนินการอีกต่อไปดังนั้นโปรแกรม B จะถูกโหลดในพื้นที่ที่อยู่เดียวกันกับโปรแกรม A ในคำอื่น ๆ โปรแกรม B จะถูกโหลดภายในหน้า RAM เดียวกันกับโปรแกรม AEXEC_PRESERVE_PROGRAM : ตัวเลือกนี้บอกเคอร์เนลว่าโปรแกรมจะต้องเก็บไว้ใน RAM จนกว่าโปรแกรม B จะเสร็จสิ้นการดำเนินการและเรียก Syscall exit ในการทำเช่นนั้นเคอร์เนลจะจัดสรรหน้าหน่วยความจำใหม่ 3 หน้า ( 16KB * 3 = 48KB ) ซึ่งจัดเก็บโปรแกรมที่โหลดใหม่ B. เมื่อโปรแกรม B ออกเคอร์เนลจะปลดปล่อยหน้าเว็บที่จัดสรรก่อนหน้านี้สำหรับโปรแกรม B ความลึกของแผนผังการดำเนินการถูกกำหนดไว้ใน menuconfig ขอบคุณตัวเลือก CONFIG_KERNEL_MAX_NESTED_PROGRAMS มันแสดงถึงจำนวนสูงสุดของโปรแกรมที่สามารถเก็บไว้ใน RAM ในครั้งเดียว ตัวอย่างเช่นหากความลึกคือ 3 โปรแกรม A CAN CALL PROGRAM B โปรแกรม B สามารถเรียกโปรแกรม C ได้ แต่โปรแกรม C ไม่สามารถเรียกโปรแกรมอื่น ๆ ได้ อย่างไรก็ตามหากโปรแกรมเรียกใช้ exec ด้วย EXEC_OVERRIDE_PROGRAM ความลึกจะ ไม่ เพิ่มขึ้นเนื่องจากโปรแกรมใหม่ในการโหลดจะแทนที่โปรแกรมปัจจุบัน ดังนั้นหากเรานำตัวอย่างก่อนหน้านี้กลับมาโปรแกรม C สามารถเรียกโปรแกรมหากมันเรียกใช้ exec SyScall ในโหมด EXEC_OVERRIDE_PROGRAM
ระวังเมื่อดำเนินการโปรแกรมย่อยตารางอุปกรณ์ที่เปิดทั้งหมด (รวมถึงไฟล์ไดเรกทอรีและไดรเวอร์) ไดเรกทอรีปัจจุบันและการลงทะเบียน CPU จะถูก แชร์
ซึ่งหมายความว่าหากโปรแกรม A เปิดไฟล์ด้วย descriptor 3, โปรแกรม B จะสืบทอดดัชนีนี้และสามารถอ่านเขียนหรือปิดคำอธิบายนั้นได้ ซึ่งกันและกันหาก B เปิดไฟล์ไดเรกทอรีหรือไดรเวอร์และออก โดยไม่ต้อง ปิดโปรแกรม A จะสามารถเข้าถึงได้เช่นกัน ด้วยเหตุนี้แนวทางทั่วไปที่จะปฏิบัติตามคือก่อนที่จะออกโปรแกรมจะต้องปิดคำอธิบายที่เปิดอยู่เสมอ ช่วงเวลาเดียวที่ตารางอุปกรณ์ที่เปิดและไดเรกทอรีปัจจุบันคือการรีเซ็ตคือเมื่อโปรแกรมเริ่มต้น (โปรแกรม A ในตัวอย่างก่อนหน้า) ออก ในกรณีนั้นเคอร์เนลจะปิดตัวบ่งชี้ทั้งหมดในตารางอุปกรณ์ที่เปิดขึ้นเปิดอินพุตและเอาต์พุตมาตรฐานอีกครั้งและโหลดโปรแกรมเริ่มต้นใหม่
นอกจากนี้ยังหมายความว่าเมื่อเรียกใช้ exec Syscall ในโปรแกรมการประกอบความสำเร็จการลงทะเบียนทั้งหมดยกเว้น HL จะต้องได้รับการพิจารณาการเปลี่ยนแปลงเพราะพวกเขาจะถูกใช้โดยโปรแกรมย่อย ดังนั้นหากคุณต้องการรักษา AF , BC , DE , IX หรือ IY พวกเขาจะต้องถูกผลักดันบนสแต็กก่อนที่จะเรียกใช้ exec
Syscalls ทั้งหมดได้รับการบันทึกไว้ในไฟล์ส่วนหัวที่มีให้สำหรับทั้งแอสเซมบลีและ C คุณจะพบไฟล์ส่วนหัวเหล่านี้ใน kernel_headers/ Directory ตรวจสอบไฟล์ readme สำหรับข้อมูลเพิ่มเติม
ไดรเวอร์ประกอบด้วยโครงสร้างที่มี:
SER0 , SER1 , I2C0 ฯลฯ อักขระที่ไม่ใช่ ASCII ได้รับอนุญาต แต่ไม่แนะนำinit ที่เรียกว่าเมื่อรองเท้าเคอร์เนลread โดยที่พารามิเตอร์และที่อยู่ส่งกลับเหมือนกับในตาราง SYSCALLwrite เช่นเดียวกับด้านบนopen เช่นเดียวกับด้านบนclose เช่นเดียวกับด้านบนseek กิจวัตรประจำวันเช่นเดียวกับด้านบนioctl เช่นเดียวกับด้านบนdeinit เรียกว่าเมื่อขนถ่ายไดรเวอร์นี่คือตัวอย่างของการลงทะเบียนไดรเวอร์อย่างง่าย:
my_driver0_init:
; Register itself to the VFS
; Do something
xor a ; Success
ret
my_driver0_read:
; Do something
ret
my_driver0_write :
; Do something
ret
my_driver0_open :
; Do something
ret
my_driver0_close :
; Do something
ret
my_driver0_seek :
; Do something
ret
my_driver0_ioctl :
; Do something
ret
my_driver0_deinit :
; Do something
ret
SECTION DRV_VECTORS
DEFB "DRV0"
DEFW my_driver0_init
DEFW my_driver0_read
DEFW my_driver0_write
DEFW my_driver0_open
DEFW my_driver0_close
DEFW my_driver0_seek
DEFW my_driver0_ioctl
DEFW my_driver0_deinit การลงทะเบียนไดรเวอร์ประกอบด้วยการใส่ข้อมูลนี้ (โครงสร้าง) ภายในส่วนที่เรียกว่า DRV_VECTORS คำสั่งซื้อมีความสำคัญมากเนื่องจากการพึ่งพาไดรเวอร์ใด ๆ จะได้รับการแก้ไขในเวลาคอมไพล์ ตัวอย่างเช่นหากไดรเวอร์ A ขึ้นอยู่กับไดรเวอร์ B โครงสร้างของ B จะต้องใส่ไว้ก่อนที่ A ในส่วนของ DRV_VECTORS
ในการบูตส่วนประกอบ driver จะเรียกดูส่วน DRV_VECTORS ทั้งหมดและเริ่มต้นไดรเวอร์ทีละคนโดยเรียกรูทีน init ของพวกเขา หากรูทีนนี้ส่งคืน ERR_SUCCESS ไดรเวอร์จะลงทะเบียนและโปรแกรมผู้ใช้สามารถเปิดอ่านเขียนเขียน iOCTL ฯลฯ ...
ไดรเวอร์สามารถซ่อนอยู่ในโปรแกรมนี้มีประโยชน์สำหรับไดรเวอร์ดิสก์ที่ต้องเข้าถึงโดยเลเยอร์ระบบไฟล์ของเคอร์เนลเท่านั้น ในการทำเช่นนั้นรูทีน init ควรส่งคืน ERR_DRIVER_HIDDEN
เนื่องจากการสื่อสารระหว่างแอปพลิเคชันและฮาร์ดแวร์ทั้งหมดทำผ่าน syscalls ที่อธิบายไว้ข้างต้นเราจำเป็นต้องมีเลเยอร์ระหว่างแอปพลิเคชันผู้ใช้และเคอร์เนลที่จะพิจารณาว่าเราจำเป็นต้องโทรหาไดรเวอร์หรือระบบไฟล์ ก่อนที่จะแสดงลำดับชั้นของสถาปัตยกรรมดังกล่าวมาพูดคุยเกี่ยวกับดิสก์และไดรเวอร์
เลเยอร์ที่แตกต่างกันสามารถมองเห็นได้เช่นนี้:
ผังงาน TD;
แอพ (โปรแกรมผู้ใช้)
VFS (ระบบไฟล์เสมือนจริง)
DSK (โมดูลดิสก์)
DRV (การใช้งานไดรเวอร์: วิดีโอ, แป้นพิมพ์, อนุกรม, ฯลฯ ... )
FS (ระบบไฟล์)
Sysdis (Syscall Dispatcher)
HW (ฮาร์ดแวร์)
เวลา (โมดูลเวลาและวันที่)
mem (โมดูลหน่วยความจำ)
โหลดเดอร์ (โมดูลตัวโหลด)
แอพ -Syscall/Rst 8 -> sysdis;
sysdis-getDate/เวลา-> เวลา;
Sysdis-Mount-> DSK;
sysdis -> vfs;
Sysdis--map-> mem;
Sysdis -Exec/Exit -> Loader;
VFS -> DSK & DRV;
dsk <-> fs;
fs -> drv;
drv -> hw;
ระบบปฏิบัติการ 8 บิต Zeal รองรับดิสก์ได้มากถึง 26 ดิสก์ในครั้งเดียว ดิสก์ถูกแสดงด้วยจดหมายจาก A ถึง Z มันเป็นความรับผิดชอบของดิสก์คนขับในการตัดสินใจว่าจะติดตั้งดิสก์ในระบบได้ที่ไหน
ไดรฟ์แรกคือ A มีความพิเศษเนื่องจากเป็นระบบที่ระบบจะมองหาการตั้งค่าหรือการกำหนดค่า
ในแอปพลิเคชัน path อาจเป็น:
my_dir2/file1.txt/my_dir1/my_dir2/file1.txtB:/your_dir1/your_dir2/file2.txt แม้ว่าระบบปฏิบัติการนั้นสามารถใช้งานได้อย่างสมบูรณ์และไม่จำเป็นต้องใช้ระบบไฟล์หรือดิสก์ใด ๆ ในการบูตทันทีที่จะพยายามโหลดโปรแกรมเริ่มต้นที่เรียกว่า init.bin โดยค่าเริ่มต้นมันจะตรวจสอบดิสก์เริ่มต้นและขอไฟล์นั้น ดังนั้นแม้แต่ที่เก็บข้อมูลพื้นฐานที่สุดก็ต้องการระบบไฟล์หรือสิ่งที่คล้ายกัน
"ระบบไฟล์" แรกซึ่งถูกนำไปใช้แล้วเรียกว่า "Rawtable" ตามชื่อของชื่อมันแสดงถึงการสืบทอดไฟล์ไม่ใช่ไดเรกทอรีในอุปกรณ์จัดเก็บข้อมูลในลำดับที่ไม่เฉพาะเจาะจง ขีด จำกัด ขนาดชื่อไฟล์เหมือนกับเคอร์เนล: 16 ตัวอักษรรวมถึงตัว . และส่วนขยาย หากเราต้องการเปรียบเทียบกับรหัส C มันจะเป็นอาร์เรย์ของโครงสร้างที่กำหนดแต่ละไฟล์ตามด้วยเนื้อหาของไฟล์ในลำดับเดียวกัน ซอร์สโค้ด Romdisk Packer มีอยู่ใน packer/ ที่รูทของ repo นี้ ตรวจสอบ readme สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้
ระบบไฟล์ที่สองซึ่งถูกนำไปใช้ก็มีชื่อว่า Zealfs วัตถุประสงค์หลักของมันคือการฝังอยู่ในห้องเก็บขนาดเล็กมากตั้งแต่ 8KB ถึง 64KB สามารถอ่านได้และเขียนได้รองรับไฟล์และไดเรกทอรี ข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ในที่เก็บข้อมูลเฉพาะ
ระบบไฟล์ที่สามที่ดีที่มีในระบบปฏิบัติการ 8 บิตที่กระตือรือร้นคือ FAT16 มีชื่อเสียงมากได้รับการสนับสนุนจากระบบปฏิบัติการเดสก์ท็อปเกือบทั้งหมดใช้งานได้บน CompactFlash และแม้แต่การ์ด SD นี่เป็นสิ่งที่ต้องมี ยัง ไม่ ได้ดำเนินการ แต่มีการวางแผน FAT16 ไม่สมบูรณ์แบบแม้ว่าจะไม่ได้รับการดัดแปลงสำหรับการจัดเก็บเล็ก ๆ นี่คือเหตุผลที่จำเป็นต้องใช้ Zealfs
ระบบปฏิบัติการ 8 บิตที่กระตือรือร้นนั้นขึ้นอยู่กับสององค์ประกอบหลัก: เคอร์เนลและรหัสเป้าหมาย เคอร์เนลคนเดียวไม่ทำอะไรเลย เป้าหมายจำเป็นต้องใช้ไดรเวอร์แมโคร MMU บางตัวที่ใช้ภายในเคอร์เนลและสคริปต์ Linker สคริปต์ Linker นั้นค่อนข้างง่ายมันจะแสดงรายการในลำดับที่พวกเขาจะต้องเชื่อมโยงในไบนารีสุดท้ายโดย z80asm Assembler
เคอร์เนลในปัจจุบันใช้ส่วนต่อไปนี้ซึ่งจะต้องรวมอยู่ในสคริปต์ linker ใด ๆ :
RST_VECTORS : มีเวกเตอร์รีเซ็ตSYSCALL_TABLE : มีตารางที่ Syscall i ที่อยู่ประจำถูกเก็บไว้ที่ INDEX i ต้องจัดตำแหน่ง 256SYSCALL_ROUTINES : มี syscall dispatcher เรียกจากเวกเตอร์รีเซ็ตKERNEL_TEXT : มีรหัสเคอร์เนลKERNEL_STRLIB : มีรูทีนที่เกี่ยวข้องกับสตริงที่ใช้ในเคอร์เนลKERNEL_DRV_VECTORS : แสดงถึงอาร์เรย์ของไดรเวอร์เพื่อเริ่มต้นตรวจสอบส่วนไดรเวอร์สำหรับรายละเอียดเพิ่มเติมKERNEL_BSS : มีข้อมูลที่ใช้โดยรหัสเคอร์เนล ต้อง อยู่ใน RAMDRIVER_BSS : ไม่ได้ใช้โดยตรงโดยเคอร์เนลมันจะถูกกำหนดและใช้ในไดรเวอร์ เคอร์เนลจะตั้งค่าเป็น 0s ในการบูตมันจะต้องใหญ่กว่า 2 ไบต์ ดังที่ได้กล่าวไว้ก่อนหน้านี้การสนับสนุน คอมพิวเตอร์ 8 บิตที่กระตือรือร้น ยังคงเป็นบางส่วน แต่เพียงพอที่จะให้โปรแกรมบรรทัดคำสั่งทำงานอยู่ romdisk ถูกสร้างขึ้นก่อนที่เคอร์เนลจะสร้างสิ่งนี้จะทำใน script.sh ที่ระบุไว้ใน target/zeal8bit/unit.mk
สคริปต์นั้นจะรวบรวมโปรแกรม init.bin และฝังไว้ใน romdisk ที่จะถูกเชื่อมต่อกับไบนารีระบบปฏิบัติการที่รวบรวมไว้ ไบนารีสุดท้ายสามารถถูกกระพริบโดยตรงกับแฟลช
สิ่งที่ยังคงต้องดำเนินการโดยไม่มีลำดับ:
มีการสร้างพอร์ตอย่างรวดเร็วไปยังคอมพิวเตอร์ TRS-80 Model-I เพื่อแสดงวิธีการพอร์ตและกำหนดค่าระบบปฏิบัติการ 8 บิตที่กระตือรือร้นไปยังเป้าหมายที่ไม่มี MMU
พอร์ตนี้ค่อนข้างง่ายเพราะมันแสดงให้เห็นถึงแบนเนอร์บูตบนหน้าจอไม่มีอะไรเพิ่มเติม ในการทำเช่นนั้นจะมีการใช้งานวิดีโอสำหรับโหมดข้อความเท่านั้น
เพื่อให้มีพอร์ตที่น่าสนใจมากขึ้นคุณลักษณะต่อไปนี้จะต้องนำไปใช้:
init.bin /romdisk สามารถอ่านได้อย่างเดียวดังนั้นสามารถเก็บไว้ใน ROMพอร์ตไปยังไฟ Agon ที่ขับเคลื่อนด้วย EZ80 เขียนและบำรุงรักษาโดย Shawn Sijnstra อย่าลังเลที่จะใช้ส้อมสำหรับข้อบกพร่อง/คำขอเฉพาะของ AGON สิ่งนี้ใช้เคอร์เนลที่ไม่ใช่ MMU และใช้คุณสมบัติส่วนใหญ่ที่การใช้งานคอมพิวเตอร์ 8 บิตด้วยความกระตือรือร้นรองรับ
พอร์ตนี้ต้องการตัวโหลดสำหรับไบนารีที่จะจัดเก็บและดำเนินการจากตำแหน่งที่ถูกต้อง ไบนารีคือ Osbootz มีให้ที่นี่
โปรดทราบว่าพอร์ตใช้โหมดเทอร์มินัลเพื่อลดความซับซ้อนของแป้นพิมพ์ I/O นี่ก็หมายความว่าฟังก์ชั่นวันที่ไม่พร้อมใช้งาน
คุณสมบัติที่โดดเด่นอื่น ๆ :
ในพอร์ต Zeal 8-bit MMU รุ่น MMU ไปยังเครื่องอื่นตรวจสอบให้แน่ใจว่าคุณมี Memory Mapper ก่อนที่จะแบ่งพื้นที่ที่อยู่ 64KB ของ Z80 ออกเป็น 4 หน้า 16KB สำหรับรุ่น MMU
ในพอร์ต NO-MMU ความกระตือรือร้น 8 บิตให้แน่ใจว่า RAM พร้อมใช้งานจากที่อยู่เสมือนจริง 0x4000 ขึ้นไป กรณีที่เหมาะที่สุดคือการมี ROM คือ 16KB แรกสำหรับระบบปฏิบัติการและ RAM ใน 48KB ที่เหลือสำหรับโปรแกรมผู้ใช้และเคอร์เนล RAM
หากเป้าหมายของคุณเข้ากันได้ให้ทำตามคำแนะนำ:
Kconfig ที่รูทของ repo นี้และเพิ่มรายการไปยังตัวเลือก config TARGET และตัวเลือก config COMPILATION_TARGET นำสิ่งที่นำเสนอเป็นตัวอย่างแล้วtarget/ สำหรับเป้าหมายของคุณชื่อ จะต้อง เหมือนกับที่ระบุไว้ในตัวเลือก config TARGET ใหม่unit.mk ใหม่ นี่คือไฟล์ที่จะมีไฟล์ต้นฉบับทั้งหมดเพื่อประกอบหรือไฟล์ที่จะรวมunit.mk ของคุณเพื่อทำเช่นนั้นคุณสามารถเติมตัวแปร make ต่อไปนี้:SRCS : รายการไฟล์ที่จะประกอบ โดยทั่วไปแล้วสิ่งเหล่านี้คือไดรเวอร์ (บังคับ)INCLUDES : ไดเรกทอรีที่มีไฟล์ส่วนหัวที่สามารถรวมได้PRECMD : คำสั่ง bash ที่จะดำเนินการ ก่อนที่ เคอร์เนลจะเริ่มสร้างPOSTCMD : คำสั่ง bash ที่จะดำเนินการ หลังจาก การสร้างเคอร์เนลเสร็จสิ้นmmu_h.asm ซึ่งจะรวมอยู่ในเคอร์เนลเพื่อกำหนดค่าและใช้ MMU ตรวจสอบไฟล์ target/zeal8bit/include/mmu_h.asm เพื่อดูว่าควรมีลักษณะอย่างไรzos_disks_mount ซึ่งมีไฟล์ init.bin , โหลดและดำเนินการโดยเคอร์เนลในการบูตzos_vfs_set_stdoutสำหรับการเปลี่ยนแปลงที่สมบูรณ์โปรดตรวจสอบหน้ารุ่น
ยินดีต้อนรับ! อย่าลังเลที่จะแก้ไขข้อผิดพลาดใด ๆ ที่คุณอาจเห็นหรือเผชิญหน้าหรือใช้คุณสมบัติใด ๆ ที่คุณพบสำคัญ
มีส่วนร่วม:
(*) ข้อความการกระทำที่ดีมีดังนี้:
Module: add/fix/remove a from b
Explanation on what/how/why
ตัวอย่างเช่น:
Disks: implement a get_default_disk routine
It is now possible to retrieve the default disk of the system.
แจกจ่ายภายใต้ใบอนุญาต Apache 2.0 ดูไฟล์ LICENSE สำหรับข้อมูลเพิ่มเติม
คุณมีอิสระที่จะใช้เพื่อการใช้งานส่วนบุคคลและเชิงพาณิชย์แผ่นหม้อไอน้ำที่มีอยู่ในแต่ละไฟล์จะต้องไม่ถูกลบออก
สำหรับข้อเสนอแนะหรือคำขอใด ๆ คุณสามารถติดต่อฉันได้ที่ติดต่อ [ที่] zeal8bit [dot] com
สำหรับคำขอคุณสมบัติคุณยังสามารถเปิดปัญหาหรือคำขอดึง
พวกเขาจะ ไม่ ได้รับการพิจารณาว่าไม่ระเหย กล่าวอีกนัยหนึ่งตัวจัดการขัดจังหวะจะไม่ตั้งสมมติฐานว่าข้อมูลที่เขียนไว้ในการลงทะเบียนสำรองใด ๆ จะถูกเก็บไว้จนกว่าจะมีการเรียกว่าในครั้งต่อไป