次ã®ããŒãã®æãæ¥ãŸããã ããã¯ã翻蚳ã©ãçªå·1ã®åŸåã§ãã ãã®åé¡ã§ã¯ãåšèŸºæ©åšãã©ã€ããŒïŒã¿ã€ããŒãGPIOãUARTïŒãèšè¿°ããXMODEMãããã³ã«ãš1ã€ã®ãŠãŒãã£ãªãã£ãå®è£
ããŸãã ããããã¹ãŠã䜿çšããŠãã«ãŒãã«ã®ã³ãã³ãã·ã§ã«ãšãmicroSDã«ãŒããååŸã«åãããªãããã«ããããŒãããŒããŒãäœæããŸãã
äžåå ã
èªæžã¯ãŒãã©ãã§å§ãŸããŸã ã
ãã§ãŒãº3ïŒè²æ®»ã§ã¯ãªã

ä»åã¯ãçµ±åãããåšèŸºæ©åšçšã®ãã©ã€ããŒãããã€ãäœæããŸãã çµã¿èŸŒã¿ã¿ã€ããŒãGPIOãããã³UARTã«èå³ããããŸãã ãããã¯çµã¿èŸŒã¿ã®ã³ãã³ãã©ã€ã³ãæžãã®ã«ååã§ãããå°ãåŸã«ããŒãããŒããŒãäœæããã®ã«äŸ¿å©ã«ãªããŸãïŒããã«ãããããã«äœæ¥ãããããç°¡åã«ãªããŸãïŒã
ãã©ã€ããŒãšã¯äœã§ããïŒ
ãã©ã€ããŒãŸãã¯ããã€ã¹ãã©ã€ããŒãšããçšèªã¯ãç¹å®ã®ããŒããŠã§ã¢ããã€ã¹ãšçŽæ¥å¯Ÿè©±ããããã管çãããœãããŠã§ã¢ãªã©ã§ãã ãã©ã€ããŒã¯ãå¶åŸ¡ããããã€ã¹ã«é«ã¬ãã«ã®ã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããŸãã ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¯ãããã€ã¹ãã©ã€ããŒãšå¯Ÿè©±ããŠããããã®äžã«ããã«é«åºŠãªæœè±¡åãæ§ç¯ããŸãïŒãã¡ããã䟿å®äžïŒã ããšãã°ãLinuxã«ãŒãã«ã¯ããã©ã€ããŒãšå¯Ÿè©±ãããªãŒãã£ãªçšã®APIã§ããALSAïŒAdvanced Linux Sound ArchitectureïŒãæäŸãããã©ã€ããŒã¯ãµãŠã³ãã«ãŒããšçŽæ¥éä¿¡ããŸãã
ãµããã§ãŒãºAïŒã¯ããã«
å²ãåœãŠã®æ®ãã®éšåã§ã¯ã osã«ãã®å
éšã§äœæ¥ããŸããããã¯ããã®éšåã ãã§ãªããã³ãŒã¹ã®æ®ãã®éšåã§ã䜿çšãããŸãã æçµçã«ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ãªãã®ã¯ããã®ãªããžããªã§ãã
ãã®ã³ãŒã¹ãåç
§ããŠãã©ããªã©ãã¹ãŠã«æ¬¡ã®ãã£ã¬ã¯ããªæ§é ããå§ãããŸãã
cs140e âââ 0-blinky â âââ Makefile â âââ phase3 â âââ phase4 âââ 1-shell â âââ ferris-wheel â âââ getting-started â âââ stack-vec â âââ ttywrite â âââ volatile â âââ xmodem âââ os âââ Makefile âââ bootloader âââ kernel âââ pi âââ std âââ volatile
å¿«é©ã§ç«¯æ£ãªã 0-blinkyããã³1-shellã¯ã以åã®ã©ããšçŸåšã®ã©ããæãã osã¯æ¬¡ã®ããã«ååŸã§ããŸãã
git clone https://web.stanford.edu/class/cs140e/os.git os git checkout master
ãã¹ãŠãæ£ããé
眮ãããŠããããšã確èªãã os/kernelå
ã§makeãå®è¡ãos/kernel ã ãã¹ãŠãæ£åžžã§ããã°ãã³ãã³ãã¯æ£åžžã«å®è¡ãããŸãã
ãããžã§ã¯ãæ§é
osãã£ã¬ã¯ããªã«ã¯ã次ã®äžé£ã®ãµããã£ã¬ã¯ããªãå«ãŸããŸãã
piã¯ããã©ã€ããŒãšOSçšã®äœã¬ãã«ã³ãŒããå«ãã©ã€ãã©ãªã§ããvolatileãã§ãŒãº2ããã®åãååã®ã©ã€ãã©ãªã®2çªç®ã®ããŒãžã§ã³std -Rustæšæºã©ã€ãã©ãªã®æå°éã®ã¹ã¿ãbootloader -ãã§ãŒãº4ã§è¿œå ããããŒãããŒããŒkernel -OSã®ã¡ã€ã³ã«ãŒãã«
ãã¹ãŠã®ãã©ã€ããŒã³ãŒãã¯piã©ã€ãã©ãªã«ãããŸãã piã¯volatileã©ã€ãã©ãªãšïŒãªãã·ã§ã³ã§ïŒ stdãŸãã kernelãšbootloaderã¯piã䜿çšããŠããã€ã¹ãšéä¿¡ããŸãã ãããŠãããã«å ããŠããããã¯stdã«äŸåããŠãstd ã volatileã¯äœã«ãäŸåããŸããã ã°ã©ãã£ã«ã«ã«ããã®é¢ä¿ã¯æ¬¡ã®ããã«ãªããŸãã

ãã¡ãŒã ãŠã§ã¢
ç¶è¡ããåã«ãã©ãºããªãŒãã¡ãŒã ãŠã§ã¢ãæŽæ°ããå¿
èŠããããŸãã ãããã¯ãã¹ãŠã osãã£ã¬ã¯ããªããmake fetchã³ãã³ãã§ããŠã³ããŒãã§ããŸãã å¿
èŠãªçŽ æãfiles/ããŒããfiles/ ã firmware/bootcode.bin ã firmware/config.txtããã³firmware/start.elfãmicroSDã«ãŒãã®ã«ãŒãã«ã³ããŒãfirmware/bootcode.bin ã åã®éšåããact-led-blink.binã³ããŒããååãkernel8.imgã«å€æŽkernel8.imgãŸãã ãããã£ãŠããã¹ãŠãæ©èœããããšã確èªã§ããŸãã ããã§ãã©ãºããªãŒèªäœã®ç·è²ã®LEDãç¹æ»
ããŸãã
æŽæ°ãããvolatile
osãã©ã«ããŒã«ãããã®ã©ã€ãã©ãªãŒã¯ããã§ãŒãº2ã§æ€èšããã³ãŒããšã¯å°ãç°ãªããŸãã倿Žã«ãããããã€ã¹ãã©ã€ããŒã®äœæã®ã³ã³ããã¹ãã§ãããå°ãç°¡åã«äœ¿çšã§ããããã«ãªããŸãã äž»ãªéãã¯æ¬¡ã®ãšããã§ãã
UniqueVolatileãUnique<Volatile>眮ãæããããŸããReservedã¿ã€ãã远å ããŸãããããã¯çµ¶å¯Ÿã«äœãã§ãããã¹ã¿ããšããŠäœ¿çšãããŸã
ãã1ã€ãããéèŠãªéãããããŸãã ã©ã€ãã©ãªã®ãã¹ãŠã®åã¯ã *mut T Tã§ã¯ãªãTã©ããããŸã*mut T ããã«ãããã©ããã³ã°ããã«ããããçš®é¡ã®çã®ã¢ãã¬ã¹ã䜿çšããæ¬¡ã®ããã«ãã£ã¹ãã§ããŸã0x1000 as *mut Volatile<T> ã ããã«å ããŠã Volatileã©ããããããã£ãŒã«ããå«ãæ§é ãæå®ã§ããŸãã ãã®ãããªãã®ïŒ
#[repr(C)] struct Registers { REG_A: Volatile<u32>, REG_B: Volatile<u8> }
#[repr(C)]ãšã¯äœã§ããïŒ
远èš#[repr(C)]ã¯ãRustãSmallãšåãæ¹æ³ã§ã¡ã¢ãªå
ã«æ§é ã圢æããããã«åŒ·å¶ããŸãã ããããªããã°ãRustã«ã¯ãã£ãŒã«ãã®é åºãšãã£ãŒã«ãéã®ã€ã³ãã³ããæé©åããæš©å©ããããŸãã çã®ãã€ã³ã¿ã䜿çšããå Žåãã»ãšãã©ã®å Žåãã¡ã¢ãªå
ã®ç¹å®ã®æ§é ãæå³ããŸãã ãããã£ãŠã #[repr(C)]䜿çšãããšãRustãæ³å®ã©ããã«æ§é ãã¡ã¢ãªã«é
眮ããããšãã¢ãµãŒãã§ããŸãã
ã³ã¢
os/kernelãã£ã¬ã¯ããªã«ã¯ãOSã®ã«ãŒãã«ã³ãŒãã®æºåãå«ãŸããŠããŸãã ãã®ãã£ã¬ã¯ããªå
ã®makeåŒã³åºãã¯ãã«ãŒãã«ãåéããŸãã ã¢ã»ã³ããªã®çµæã¯build/ãµããã£ã¬ã¯ããªã«ãããŸãã ãã®ããžãã¹ãéå§ããã«ã¯ã build/kernel.binãkernel8.imgãšããååã§microSDã«ãŒãã®ã«ãŒãã«ã³ããŒbuild/kernel.binå¿
èŠããããŸãã çŸåšãã«ãŒãã«ã¯äœãããŠããŸããã ãã®ãã§ãŒãºã®çµãããŸã§ã«ãã«ãŒãã«ã«ã¯ãã£ããå¯èœãªããã¹ãããŒã¹ã®å¯Ÿè©±åã·ã§ã«ãå«ãŸããŸãã
kernelã©ãã¯ã¯piã©ãã¯ã«äŸåããŸãã extern crate pi;ãèŠãããšãã§ããŸãextern crate pi; kernel/src/kmain.rsã«èšè¿°ãCargo.toml ã ã€ãŸã pi宣èšããããã¹ãŠã®åãšæ§é ãééžæçã«äœ¿çšã§ããŸãã
ããã¥ã¡ã³ã
ãã©ã€ããŒãäœæãããšãã BCM2837ããªãã§ã©ã«ããã¥ã¢ã«ã¯éåžžã«åœ¹ç«ã¡ãŸãã
ãµããã§ãŒãºBïŒã·ã¹ãã ã¿ã€ããŒ

ãã®ãµããã§ãŒãºã§ã¯ãçµã¿èŸŒã¿ã¿ã€ããŒã®ãã©ã€ããŒãäœæããŸãã äž»ãªäœæ¥ã¯ããã¡ã€ã«os/pi/src/timer.rsããã³os/kernel/src/kmain.rsãŸãã ã¿ã€ããŒã¯ã BCM2837åšèŸºæ©åšããã¥ã¢ã«ã® 172ããŒãžïŒã»ã¯ã·ã§ã³12ïŒã«èšèŒãããŠããŸãã
æåã«ããã§ã«os/pi/src/timer.rsããã³ãŒããèŠãŠos/pi/src/timer.rs ã å°ãªããšããããã®éšåïŒ
const TIMER_REG_BASE: usize = IO_BASE + 0x3000; #[repr(C)] struct Registers { CS: Volatile<u32>, CLO: ReadVolatile<u32>, CHI: ReadVolatile<u32>, COMPARE: [Volatile<u32>; 4] } pub struct Timer { registers: &'static mut Registers } impl Timer { pub fn new() -> Timer { Timer { registers: unsafe { &mut *(TIMER_REG_BASE as *mut Registers) }, } } }
æåã«æ³šæããå¿
èŠãããunsafeã§unsafeã³ãŒãã®1è¡ããããŸãã *mut Registersã®ã¢ãã¬ã¹TIMER_REG_BASEã¯ãã®è¡ã«ãã£ã¹ãããããã®åŸããã«&'static mut Registersã«å€ãããŸãã å®éã TIMER_REG_BASEã®æ§é ãžã®éçãªã³ã¯ãå¿
èŠã§ããããšãTIMER_REG_BASEãŠããŸãã
TIMER_REG_BASEã«ã¯æ£ç¢ºã«äœããããŸããïŒ ããã¥ã¢ã«ã® 172ããŒãžã§ã 0x3000ãã¿ã€ããŒã®åšèŸºã®å
é ããã®ãªãã»ããã§ããããšãããããŸãã ã€ãŸã TIMER_REG_BASEã¯ããã®ã¿ã€ããŒã®ã¬ãžã¹ã¿ãå§ãŸãã¢ãã¬ã¹ã§ãã unsafeã§unsafe 1è¡ã®åŸã«ã registersãã£ãŒã«ãã䜿çšããŠãããããã¹ãŠã«å®å
šã«å®å
šã«ã¢ã¯ã»ã¹ã§ããŸãã ããšãã°ã self.registers.CLO.read()ãself.registers.CLO.read()ãŠCLOã¬ãžã¹ã¿ãself.registers.CLO.read()ãããŸãã¯
self.registers.CS.write()ã䜿çšããCS ã
ãªãCLOããã³CHIã¬ãžã¹ã¿ã«æžã蟌ããªãã®ã§ããïŒ [å¶éä»ãèªã¿åã]
BCM2837ã®ããã¥ã¡ã³ãã«ã¯ã CLOããã³CHIã¬ãžã¹ã¿ãèªã¿åãå°çšã§ãããšèšèŒãããŠããŸãã ã³ãŒãã¯ãã®ããããã£ãæäŸããŸãã ã©ããã£ãŠïŒ äœãCLOãšCHIæžãããšã劚ããŸããïŒ
å®å
šã§ã¯ãªããã®ã¯äœã§ããïŒ
èŠããã«ã unsafeã¯Rustã³ã³ãã€ã©ãŒã®ããŒã«ãŒã§ããããŠãŒã¶ãŒã¯ã¡ã¢ãªãŒã®ã»ãã¥ãªãã£ãå¶åŸ¡ããŠãããšèšããŸãã ã³ã³ãã€ã©ãŒã¯ããããã®ã³ãŒãã®ã¡ã¢ãªãŒåé¡ãããŠãŒã¶ãŒãä¿è·ããŸããã ã³ãŒãã®unsafeéšåã§ã¯ãRustã䜿çšããŠãNeat Cã§å®è¡ã§ãããã¹ãŠã®æäœãå®è¡ã§ããŸãã ã§ãã ã³ã©ãã³ã奪ã ããã¿ã€ããå¥ã®ã¿ã€ãã«ãã£ã¹ãããçã®ãã€ã³ã¿ãŒã§éãã§ã寿åœãäœæããã ãã§ååã§ãã
ãã ãã unsafeãããã¯å
ã®ã³ãŒãã¯éåžžã«å±éºã§ãã å®å
šã§ãªãã»ã¯ã·ã§ã³ã§è¡ãããšã¯ãå®éã«å®å
šã§ããããšã確èªããå¿
èŠããããŸãã ããã¯äžèŠæããããããè€éã§ãã ç¹ã«ãRustã®ã»ãã¥ãªãã£æŠå¿µã¯ä»ã®èšèªããã峿 Œã§ããããã§ãã unsafeã§ãªããã®ã䜿çšãunsafeããŠãã ããã ãã¡ãããå¯èœãªç¯å²ã§ã ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãªã©ã®å Žåãæ©åšãšçŽæ¥éä¿¡ããå Žåã¯ã unsafeã䜿çšããå¿
èŠããããŸãã ãã ãããã®äœ¿çšã¯ã§ããéãå¶éããŸãã
unsafeã¢ã¢ã¬ãèªã¿ããå Žåã¯ãNomiconã®ç¬¬1ç« ãã芧ãã ãã ã ããã«ããã®å°ããªæ¬ãéããŠãRustã®ããŸããŸãªåŒ·åãªéè¡åž«ã«åœ¹ç«ã€å€ãã®ããšãåŠã¶ããšãã§ããŸãã
ãã©ã€ããŒã®å®è£
os/pi/src/timer.rs Timer::read() os/pi/src/timer.rsããTimer::read()å®è£
ãos/pi/src/timer.rs ã æ¬¡ã«ãã¡ãœããcurrent_time() ã spin_sleep_us() ã spin_sleep_ms()ãè¿ãã«ãããŸãã ãããã®é¢æ°ã®ã³ã¡ã³ããšååã¯ãæåŸ
ãããæ©èœã瀺ããŠããŸãã Timer::read()ãå®è£
ããã«ã¯ãé©åãªã»ã¯ã·ã§ã³ã®BCM2837ããã¥ã¡ã³ããèªãå¿
èŠãããTimer::read() ã å°ãªããšãã64ãããã¿ã€ããŒå€å
šäœãååŸããããã«èªã¿åãå¿
èŠãããã¬ãžã¹ã¿ãçè§£ããå¿
èŠããããŸãã cargo buildããŠããã€ã¯ã¬ãŒããçµã¿ç«ãŠãããšãã§ããŸãã ãã ãã cargo checkã䜿çšããŠèšè¿°ãããå
å®¹ã®æ£ç¢ºæ§ãåçŽã«ãã§ãã¯ããæ¹ãé«éã§ãã
ãã©ã€ããŒãã¹ã
spin_sleep_ms()颿°ãæ£ããå®è£
ãããŠããããšã確èªããããšã¯spin_sleep_ms()ã§ãã ãããè¡ãã«ã¯ã kernel/src/kmain.rsé©åãªã³ãŒããèšè¿°ãkernel/src/kmain.rs ã
ãŒãã©ãã®ãã§ãŒãº4ããLEDã®ç¹æ»
ã³ãŒããã³ããŒããŸãã ã«ãŒãå
ã§ã¹ãã³ããã ãã®ã¹ãªãŒã颿°ã®ä»£ããã«ã spin_sleep_ms()颿°ã䜿çšããŠãç¹æ»
éã®äŒæ¢ãäœæããå¿
èŠããããŸãã ã«ãŒãã«ãåã³ã³ãã€ã«ãã kernel8.imgãšããã¡ã¢ãªã«ãŒãã«ããŒãããŸãã ãã¹ãŠãå®è¡ããŠãèšç»ããé »åºŠã§LEDãç¹æ»
ããããšã確èªããŸãã å¥ã®é
å»¶ãµã€ãºãèšå®ããŠããã¹ãŠãæ©èœããããšã確èªããŠãã ããã ã¯ããmicrosdã«ãŒããåžžã«ååŸã«çªãã®ã¯éåžžã«é¢åã§ãã ãã®ããŒãã®çµãããŸã§ã«ããã®åé¡ã解決ããããŒãããŒããŒãã§ããŸãã
ã¿ã€ããŒã®ãã©ã€ããŒå®è£
ãæ©èœããå Žåãæ¬¡ã®ãµããã§ãŒãºã«é²ãããšãã§ããŸãã
ãµããã§ãŒãºCïŒGPIO
ãã®ãµããã§ãŒãºã§ã¯ãç¹å®ã®ãã³çªå·ã«é¢ä¿ãªããæ±çšGPIOãã©ã€ããŒãäœæããŸãã äž»ãªäœæ¥ã¯ããã¡ã€ã«os/pi/src/gpio.rsããã³os/kernel/src/kmain.rsãŸãã GPIOã®ããã¥ã¡ã³ãã¯ã BCM2837åšèŸºæ©åšããã¥ã¢ã«ã® 89ããŒãžïŒã»ã¯ã·ã§ã³6ïŒã«ãããŸã ã
ã¹ããŒããã·ã³

ãã¹ãŠã®ããŒããŠã§ã¢ããã€ã¹ã¯ãæ¬è³ªçã«ã¹ããŒããã·ã³ ïŒ eng ïŒãšèŠãªãããšãã§ããŸãã ãããã¯ããç¶æ
ã§åæåãããä»ã®ç¶æ
ã«æç€ºçãŸãã¯ããã§ã¯ãããŸããã åæã«ãããã€ã¹ã¯çŸåšã®ç¶æ
ã«å¿ããŠããŸããŸãªæ©èœãæäŸããŸãã ã€ãŸããç¹å®ã®ç¹å®ã®ç¶æ
ã§ã¯ãä»ã®ç¶æ
ãžã®ç¹å®ã®é·ç§»ã»ããã®ã¿ãåäœå¯èœã§ãã
ã»ãšãã©ã®ããã°ã©ãã³ã°èšèªã§ã¯ãæéç¶æ
ãã·ã³ã®ã»ãã³ãã£ã¯ã¹ãæ£ç¢ºã«è¿œè·¡ããããšã¯äžå¯èœã§ãã ãããããã¡ããããã¯Rustã«ã¯åœãŠã¯ãŸããŸããã Rustã䜿çšãããšããã®ã»ãã³ãã£ã¯ã¹ãéåžžã«æç¢ºã«è¿œè·¡ã§ããŸãã ããã䜿çšããŠãããå®å
šãªGPIOãã©ã€ããŒãå®è£
ããŸãã ãã©ã€ããŒã¯ããã¹ãŠã®GPIOãã³ãåžžã«æ£ãã䜿çšãããããã«ããŸãã ã³ã³ãã€ã«æ®µéã
* ããçš®ã®ç ç©¶ã®ããã«èŠãã...
ããªãã¯ç§ãæãŸããã ããã¯æ¬è³ªçã«ãçŸæç¹ã§ã®ç§ã®ç ç©¶åéã§ãã - ã»ã«ãžãª
以äžã«ãGPIOã¹ããŒããã·ã³ããããã£ã®ãµãã»ããïŒ1ãã³ïŒã®ç¶æ
å³ã瀺ããŸãã

ç§ãã¡ã®ç®æšã¯ãããããã¹ãŠãRustã§å®è£
ããããšã§ãã ãããããsobsnaã¯æ¬¡ã®å³ãæããŠãããŸãã
- GPIOã¯
STARTç¶æ
ããSTARTãŸã STARTç¶æ
ãããæ¬¡ã®ç¶æ
ã«ç§»åã§ããŸãã
ALT ãä»ã®ç¶æ
ãžã®é·ç§»ã¯ãããŸããOUTPUT -ããèªäœãžã®2ã€ã®äœ¿çšå¯èœãªé·ç§»ïŒ SETããã³CLEARINPUT - LEVELãšããååã®é·ç§»ã1ã€
ã©ã0ã§ã¯ã©ã®ãããªãã©ã³ãžã·ã§ã³ã䜿çšããŸãããïŒ [ãŸã°ããç¶æ
]
Lab 0ãããã§ãŒãº4ã®ã³ãŒããèšè¿°ãããšããæ¬è³ªçã«ã¹ããŒããã·ã³ã®ãµãã»ãããæé»çã«å®è£
ããŸããã ãã®å Žåãç¶æ
éã®ã©ã®ãããªé·ç§»ãå®çŸããŸãããïŒ
Rustã¿ã€ãã·ã¹ãã ã䜿çšããŠããã³ãOUTPUTç¶æ
ã«ããå Žåã«ã®ã¿SETããã³CLEAR ã INPUTç¶æ
ã«ããå Žåã«LEVELã®ã¿ãå¯èœã§ããããšãä¿èšŒããŸãã pi/src/gpio.rsã®GPIOæ§é 宣èšãèŠãŠãã ããïŒ
pub struct Gpio<State> { pin: u8, registers: &'static mut Registers, _state: PhantomData<State> }
æ§é äœã«ã¯ã Stateãšããäžè¬çãªåŒæ°ã1ã€ãããŸãã PhantomDataã®ã¿ã䜿çšããä»ã®PhantomDataã¯äœ¿çšããŸããã å®éããã®ãããªPhantomDataã®ããã«ãæ§é ãäœããã®åœ¢ã§äžè¬åãããåŒæ°ã䜿çšããŠããããšãRustã«çŽåŸãããããã«ååšããŸãã Gpioç¶æ
ã®ããŒã«ãŒãšããŠStateã䜿çšGpioãŸãã åæã«ããã®ãã©ã¡ãŒã¿ãŒã®ç¹å®ã®å€ãäœæã§ããªãããã«ããå¿
èŠããããŸãã
ãã¯ãstate! ããã«ãããšæãããåãçæããŸãããäœæããããšã¯ã§ããŸããã ãã®å Žåã Gpioã®ç¶æ
ã®ãªã¹ããçæãGpioãŸãã
states! { Uninitialized, Input, Output, Alt }
å€ã«èŠããŸã ã å¯èœãªå€ãªãã§åæãäœæããå¿
èŠãããã®ã¯ãªãã§ããïŒ åœŒãã¯1ã€ã®å¿«é©ãªããããã£ããããŸãã äœæã§ããŸããã ãã ããããŒã«ãŒãšããŠäœ¿çšã§ããŸãã Inputåã®å€ã¯äœæã§ããªããããã ããæž¡ãããšãã§ããŸããã ãããã¯ã¿ã€ãã®ã¬ãã«ã§ã®ã¿ååšããä»ã®ã©ãã«ãååšããŸããã
次ã«ãé©åãªé·ç§»ã»ããã䜿çšããŠåç¶æ
ã®ã¡ãœãããå®è£
ã§ããŸãã
impl Gpio<Output> {
ããã¯ã Gpioãç¶æ
ã«å¿ããŠå³å¯ã«å®çŸ©ãããæ¹æ³ã§ã®ã¿Gpioã§ãããšããä¿èšŒã®ããã«èŠããŸãã æªããªãã§ããïŒ ãããããããã®ç¶æ
ãã©ã®ããã«éæããã®ã§ããããïŒ ãããè¡ãã«ã¯ã Gpio::transition()ã¡ãœããããããŸãã
impl<T> Gpio<T> { fn transition<S>(self) -> Gpio<S> { Gpio { pin: self.pin, registers: self.registers, _state: PhantomData } } }
ãã®æ¹æ³ã䜿çšãããšã Gpioãããç¶æ
ããå¥ã®ç¶æ
ã«ç°¡åãã€èªç±ã«è»¢éã§ããŸãã ç¶æ
T GpioãååŸããç¶æ
S GpioãGpio S ãã¹ãŠã®Sããã³Tã§æ©èœããããšã«æ³šæããŠãã ããT ãã®ã¡ãœããã¯éåžžã«æ
éã«äœ¿çšããå¿
èŠããããŸãã ãã®ãã¹ãŠã«ééããç¯ããå Žåããã©ã€ããŒã¯èª€ã£ãŠèšè¿°ãããŠãããšèŠãªãããŸãã
transition()ã䜿çšããã«ã¯ã Gpio<S>ã¿ã€ãSãæå®ããå¿
èŠããããŸãã Rustã«ååãªæ
å ±ãæäŸããŠãRustããã¹ãŠèªåã§ååŸã§ããããã«ããŸãã ããšãã°ã into_outputã¡ãœããã®å®è£
ïŒ
pub fn into_output(self) -> Gpio<Output> { self.into_alt(Function::Output).transition() }
ãã®ã¡ãœããã§ã¯ãæ»ãå€ã®åãGpio<Output>ããšãå¿
èŠã§ãã Ruståã·ã¹ãã ã¯transition()åŒã³åºãã調ã¹ããšã Gpio::transition()ã¡ãœãããGpio<Output>ãŸãããã®ã¡ãœããã¯Gpio<Output>ãè¿ããŸãã 圌ã¯ãä»»æã®SååšããGpio<S>ãè¿ãã¡ãœãããèŠã€ããŸãS ãããã£ãŠã S代ããã«S Outputãå®å
šã«çœ®ãæããããšãã§ããŸãã ãã®çµæã Gpio<Alt> ïŒ into_alt颿°ããïŒãGpio<Output>ã«å€æããŸãã
ã¯ã©ã€ã¢ã³ããä»»æã®ç¶æ
ãæž¡ãããšãã§ããå Žåã¯ã©ããªããŸããïŒ [åœã®ç¶æ
]
ãŠãŒã¶ãŒã³ãŒããGpioæ§é ã®åæç¶æ
ãèªç±ã«éžæã§ããããã«ãããšã©ããªãããèããŠãã ããã äœãããããã®ã§ããããïŒ
ãªãããããã¹ãŠRustã§ããã§ããªãã®ã§ããïŒ
into_é·ç§»ã¯ç§»åã®ã»ãã³ãã£ã¯ã¹ã䜿çšãããšããå°ããªäºå®ã«æ³šæããŠãã ããã ããã¯ã Gpioãå¥ã®ç¶æ
ã«ãªããšããã«ã以åã®ç¶æ
ã§ã¯ã¢ã¯ã»ã¹ã§ããªããªãããšãæå³ããŸãã åãClone ã Copyããã³ãã®ä»ã®è€è£œã¡ãœãããå®è£
ãããŸã§ãéé·ç§»ã¯äœ¿çšã§ããŸããã ä»ã®èšèªã§ã¯ãããã§ããŸããã C++ã§ãã ãã¹ãŠã®ä¿èšŒä»ãã®ã³ã³ãã€ã«äžã®ãã®ãããªéè¡åž«ã¯ããã ãã§ãã ïŒãã©ã¹ãä»ã®äœãã®é人ã¯ããã®å£°æã«ææŠããããšããããšãã§ããŸãïŒ
ãã©ã€ããŒã®å®è£
unimplemented!()代ããã«å¿
èŠãªã³ãŒãããã¹ãŠæžããŠunimplemented!()ãã¡ã€ã«pi/src/gpio.rs ããããã¹ãŠã®æ¹æ³ã®ã³ã¡ã³ããšçœ²åãããçè§£ã§ããŸã æ§é€ã䜿çšã㊠æåŸ
ãããæ©èœã ããã¥ã¡ã³ãïŒ89ããŒãžã BCM2837ããã¥ã¢ã«ã®ã»ã¯ã·ã§ã³6ïŒãåç
§ããããšã¯äžèŠã§ãã cargo checkã®æçšæ§ãå¿ããªãã§cargo check ã
ãã³ãïŒäžæ¬åŒ§{ ... }ã䜿çšããŠä»»æã®åå¥ã¹ã³ãŒããäœæã§ããããšãå¿ããªãã§ãã ããã
ãã©ã€ããŒãã¹ã
æããã«ããã©ã€ããŒããã¹ãããã«ã¯ã kernel/src/kmain.rsããã€ãã®ã³ãŒããæžãå¿
èŠãããkernel/src/kmain.rs ã
ä»åã¯ãã¬ãžã¹ã¿èªäœãçŽæ¥èªã¿æžããã代ããã«ãLEDãç¹æ»
ãããããã«ãã©ã€ããŒã䜿çšããŸãã GPIOãã³çªå·16ããªã³/ãªãããããšã«ãããåæã«ãã³ãŒãå
šäœãããã¯ãªãŒã³ã§ãšã¬ã¬ã³ãã«ãªããŸãã ã«ãŒãã«ãã³ã³ãã€ã«ãã kernel8.imgãšããã«ãŒãã«ããŒãããŠã kernel8.imgã©ãºããªãŒãå®è¡ããŸãã LEDã¯ä»¥åãšãŸã£ããåãããã«ç¹æ»
ããã¯ãã§ãã
ããã§ãããå€ãã®LEDãæ¥ç¶ã§ããŸãã 5ã6ã13ã19ã26ã®çªå·ãä»ããããGPIOãã³ã䜿çšããŸãããŒãã©ãã®ãã³ã®çªå·ä»ãã®å³ãåç
§ããŠãç©ççãªäœçœ®ã確èªããŸãã ããªããæãããã«å€ãã®LEDã§ã³ã¢ãç¹æ»
ãããŠãã ããïŒ
ã©ã®ç¹æ»
ãã¿ãŒã³ãéžæããŸãããïŒ [LEDãã¿ãŒã³]
LEDããªã³/ãªãããããšã«ããã¹ããŒã ã¯äœã§ããïŒ å¥œã¿ã«åãããŠå€ãã®ãªãã·ã§ã³ããéžæã§ããŸãã ãã ããéžæãå³ããå Žåã¯ããµãŒã¯ã«ã§ãªã³ãšãªããåãæ¿ããããšãã§ããŸãã 
GPIOãã©ã€ããŒãå®å
šã«åäœå¯èœã«ãªã£ãããæ¬¡ã®ãµããã§ãŒãºã«é²ãããšãã§ããŸãã
ãµããã§ãŒãºDïŒUART
ãã®ãµããã§ãŒãºã§ã¯ãããUARTããã€ã¹ãã©ã€ããŒãäœæããŸããããã¯ãã©ãºããªãŒã®å²åã«çµã¿èŸŒãŸããŠããŸãã ã»ãšãã©ã®äœæ¥ã¯ããã¡ã€ã«os/pi/src/uart.rsããã³os/kernel/src/kmain.rsãŸãã Mini UARTã¯ã BCM2837ããã¥ã¢ã«ã® 8ããŒãžãš10ããŒãžïŒã»ã¯ã·ã§ã³2.1ãš2.2ïŒã«èšèŒãããŠããŸã ã
UARTïŒãŠãããŒãµã«éåæRX / TX
UART ïŒ ru ïŒãŸãã¯Universal Synchronous Reception Transmitterã¯ãè
ºã2æ¬ã®ã¯ã€ã€ã§éä¿¡ããããã®ããã€ã¹ããã³ã·ãªã¢ã«ãããã³ã«ã§ãã ãããã¯ãCP2102 USBã¢ãžã¥ãŒã«ã®UARTããã€ã¹ãã©ãºããªãŒã®UARTããã€ã¹ã«æ¥ç¶ããããã«ããŒãã©ãã®ãã§ãŒãº1ã§äœ¿çšããããã®ãšåã2ã€ã®é
ç·ïŒrx / txïŒã§ãã UARTãä»ããŠä»»æã®ããŒã¿ãéä¿¡ã§ããŸããããã¹ãããã€ããªãã¡ã€ã«ãã·ãŒã«ä»ãã®åçãªã©ããã¡ã³ã¿ãžãŒã«ååãªãã®ã§ãã äŸãšããŠã次ã®ãµããã§ãŒãºã§ãã©ãºããªãŒã®UARTããèªã¿åããCP2102ã®UARTã«æžã蟌ã察話åã·ã§ã«ãäœæããŸãã ãã§ãŒãº4ã§ã¯ãã»ãŒåãæ¹æ³ã§ãã€ããªæ
å ±ãéä¿¡ããŸãã
UARTãããã³ã«ã«ã¯ããã€ãã®æ§æãã©ã¡ãŒã¿ãŒããããŸãã ãã¹ãŠãæ©èœããããã«ã¯ãåä¿¡æ©ãšéä¿¡æ©ã®äž¡æ¹ãåäžã«æ§æããå¿
èŠããããŸãã ãããã¯æ¬¡ã®ãã©ã¡ãŒã¿ãŒã§ãã
- ããŒã¿ãµã€ãº - ããŒã¿ãå«ã1ãã¬ãŒã ã®é·ãïŒ8ãŸãã¯9ãããïŒ
- ããªãã£ããã -ããŒã¿ã®åŸã«ããªãã£ãããïŒå¶åŸ¡ãããïŒãéä¿¡ãããã©ãã
- ã¹ãããããã -ããŒã¿ãéä¿¡ãããããšã倿ããããã«äœ¿çšãããããæ°ïŒ1ãŸãã¯2ãããïŒ
- ããŒã¬ãŒã -ãããã¬ãŒã/ç§
Mini UARTã¯ããªãã£ãããããµããŒãããã1ã€ã®ã¹ããããããã®ã¿ããµããŒãããŸãã ãããã£ãŠãããŒã¬ãŒããšãã¬ãŒã é·ãèšå®ããã ãã§ãã UARTéä¿¡ã®åºæ¬ ïŒç¿»èš³ãå¿
èŠã§ããïŒïŒãšããããã¥ã¡ã³ãã§ãUARTèªäœã«ã€ããŠããå°ãèªãããšãã§ããŸãã
ãã©ã€ããŒã®å®è£
ãã®æ®µéã§ã¯ãåã¹ãããããã€ã³ãããããšãªãããã€ã¹ãã©ã€ããŒãäœæããããã«å¿
èŠãªãã¹ãŠã®ããŒã«ãçšæãããŠããŸãã ããã§ãšãããããŸãïŒ
ã¿ã¹ã¯ã¯ãå¿
èŠãªãã¹ãŠããã¡ã€ã«pi/src/uart.rsã«å®è£
ããããšã§ãã Registersæ§é ã®ã³ã³ãã³ãã远å ããå¿
èŠããããŸãã ãã®å Žåãåã¬ãžã¹ã¿ã«æäœéå¿
èŠãªæ©èœã®ã»ãããåãã[ Volatileã¿ã€ã]ãªãã·ã§ã³ã䜿çšããŸãã ãããã®èªã¿åãå°çšã¬ãžã¹ã¿ã¯ReadVolatileã䜿çšããå¿
èŠããããŸãã WriteVolatileã®ã¿WriteVolatileèš±å¯ãããŠããå Žåã WriteVolatile ã äºçŽã¹ããŒã¹ã«ã¯ReservedãŸãã new() 115200 ( 270) 8 . unimplemented!() , . fmt::Write , io::Read io::Write MiniUart .
: LCR , BAUD CNTL new /
: GPIO .
, ( kernel/src/kmain.rs ), . :
loop { write_byte(read_byte()) }
screen /dev/<_> 115200 UART. screen TTY . , . ã€ãŸã . :
loop { write_byte(read_byte()) write_str("<-") }
, â .
E: The Shell
UART . os/kernel/src/console.rs , os/kernel/src/shell.rs os/kernel/src/kmain.rs .
Console

, , - / . Unix stdin stdout . Console . Console kprint! kprintln! ã , print! println! ã . Console , .
os/kernel/src/console.rs . Console . - MiniUart . . . MiniUart MiniUart Console .
â , . Rust. Rust . , ? , unsafe . : Rust'y, , .. , "" . , . Rust . :
. . , , unsafe Rust. , . " ". ã€ãŸã . .
, . , . , ( & ). , ( &T -> &mut ).
. , , :
fn lock<T>(value: &T) -> Locked<&mut T> { unsafe { lock(value); cast value to Locked<&mut T> } } impl Drop for Locked<&mut T> { fn drop(&mut self) { unlock(self.value) } }
Mutex . â , :
fn get_mut<T>(value: &T) -> Mut<&mut T> { unsafe { if ref_count(value) != 0 { panic!() } ref_count(value) += 1; cast value to Mut<&mut T> } } impl Drop for Mut<&mut T> { fn drop(&mut self) { ref_count(value) -= 1; } }
, RefCell::borrow_mut() . â , :
fn get_mut<T>(value: &T) -> Option<Mut<&mut T>> { unsafe { if ref_count(value) != 0 { None } else { ref_count(value) += 1; Some(cast value to Mut<&mut T>) } } } impl Drop for Mut<&mut T> { fn drop(&mut self) { ref_count(value) -= 1; } }
RefCell::try_borrow_mut() . " ": . Console Mutex . std::Mutex â . . kernel/src/mutex.rs . , , , Rust. Mutex , , .
ã ããã CONSOLE kernel/src/console.rs . kprint! kprintln! , . , Console â Console . CONSOLE Console .
Rust Sync .
T static , T Sync . , Rust . , Rust , . Send Sync , Rust .
** &mut T ? [drop-container]
, , Drop . , &mut T ?
write_fmt ? [write-fmt]
_print write_fmt MutexGuard ( Mutex<Console>::lock() . write_fmt ?
Console
, unimplemented!() kernel/src/console.rs . kprint! kprintln! , kernel/src/kmain.rs , , . , print! println! ã screen /dev/<-> 115200 .
...
println! â Rust. printf . Rust , , . . , ? .
: Console : .

. kernel/src/shell.rs . Command . Command::parse() Command . parse args StackVec , buf . Command::path() .
( Command , StackVec , Console CONSOLE , kprint! , kprintln! , ) shell . prefix , . "> " . , . ad-infinitum . . echo .
, :
echo $a $b $c , $a $b $c\r \n enter ,- backspace delete (ASCII 8 127)
- (ASCII 7),
unknown command: $command $command- ,
- 512
- 64
prefix ,error: too many arguments
shell . kernel/src/kmain.rs . SOS, , . , . â . .
:
b'a' u8 'a'
\u{b} ASCII b
\r \n
, backspace, , backspace
StackVec
std::str::from_utf8
std !
, std . . , , xargo doc --open os/std .
? [shell-lookback]
. , .
4:
, , Raspberry Pi. os/bootloader/src/kmain.rs
, MicroSD- . , , . , .
â "", , XMODEM UART. , . ttywrite . :
ttywrite -i -.bin /dev/<->
Raspberyy Pi 3 kernel8.img 0x80000 . , , kernel8.img 0x80000 ARM' (program counter) 0x80000 . , . , 0x80000 .
(linker, ). . : , . , . os/kernel/ext/layout.ld ( ). , 0x80000 . 0x80000 .
, , 0x80000 . . 0x80000 . ã€ãŸã ! . . . . ã©ããã£ãŠïŒ
. os/bootloader/ext/layout.ld , , 0x4000000 . , 0x80000 . kernel_address config.txt . bootloader/ext/config.txt . , . ã€ãŸã MicroSD-.
0x80000 0x4000000 "" .
63.5 ? [small-kernels]
, , , . â . , . ?
, . macOS - /System/Library/Kernels/kernel . /mach_kernel . Linux - /boot/ vmlinuz , vmlinux bzImage . ? 63.5 ?
bootloader/src/kmain.rs . , , . const . jump_to , addr . . pi xmodem UART, , . , .
, XMODEM, ( 750 ). . â . , â . os/kernel/build/kernel.bin ttywrite . â , screen .
? [bootloader-timeout]
. ?
config.txt , !
:
kmain() 15 .
std::slice::from_raw_parts_mut .
&mut [u8] io::Write .
UPD