ãã¼ãããã®OSèªä½å ¥éãã Rust ã§ãã (第6ç« ãã®1)
ä»æ¥ãä»æ¥ã¨ã¦ãã¼ãããã®OSèªä½å ¥éããRustã§ãã£ã¦ããã¾ãã
- ã·ãªã¼ãºæåã®è¨äº: 「ゼロからのOS自作入門」を Rust でやる (第1章~第4章) - gifnksmの雑多なメモ
- åå: 「ゼロからのOS自作入門」を Rust でやる (第5章) - gifnksmの雑多なメモ
- 次å: 「ゼロからのOS自作入門」を Rust でやる (第8章) - gifnksmの雑多なメモ
- é¢é£è¨äºä¸è¦§: ゼロからのOS自作入門 カテゴリーの記事一覧 - gifnksmの雑多なメモ
6ç«
MikanOS ã USB ãã¦ã¹ã¸å¯¾å¿ãããç« ã§ãã
ãã¦ã¹ã«ã¼ã½ã«ã¨ãã¹ã¯ããããæç» (day06a)
ãã¦ã¹ã«ã¼ã½ã«ã¨ãã¹ã¯ããããæç»ããç¯ã§ãã æç»ããã¨ãã£ã¦ãããã 表示ããã ãã§æä½ãªã©ã¯ã§ããªããã®ãªã®ã§ç°¡åã§ãã
ãã¹ã¯ãããã®æç»ã¨ãã¦ã¹ã«ã¼ã½ã«ã®æç»ã¯ãããã desktop
, mouse
ã¨ããã¢ã¸ã¥ã¼ã«ã¸ã¨åå²ãã¦ãã¾ãã
ãã¹ã¯ãããã®æç»å¦çã§ã¯ã¹ã¯ãªã¼ã³ã®ãµã¤ãºæ
å ±ãå¿
è¦ã§ãã
FrameBufferInfo
æ§é ä½ã®ã¡ã³ãã使ããã®ã§ãããå½è©²æ§é ä½ã¡ã³ãã®å㯠usize
ã§ããããã
æç»å¦çã§å©ç¨ãã¦ããåã§ãã i32
ã¸ã®å¤æãå¿
è¦ã§ãã
ã¹ã¯ãªã¼ã³ãµã¤ãºãå¿
è¦ã¨ããå¦çã¯ä»ã«ãç»å ´ãããã¨ãäºæ³ãããããããã§åå¤æãããã«ä¼´ãã¨ã©ã¼ãã³ããªã³ã°ãå®è£
ããã®ã¯ããã©ãããããã i32
åã§ã¹ã¯ãªã¼ã³ãµã¤ãºçã®æ
å ±ãæ ¼ç´ãã ScreenInfo
æ§é ä½ãç¨æãã framebuffer ã®åæåæã«1度ã ãåæåããããã«ãã¾ããã
PCI ããã¤ã¹ã®æ¢ç´¢ (day06b)
IO å½ä»¤ã«ãã PCI ã³ã³ãã£ã°ã¬ã¼ã·ã§ã³ç©ºéã«ã¢ã¯ã»ã¹ãã USB ã®ãã¹ãã³ã³ããã¼ã© (ä»å㯠xHC) ã«å¯¾å¿ããããã¤ã¹ãæ¢ç´¢ãã¾ãã
å¦ç㯠C++ çã¨åãã§ãã工夫ããç¹ãããã¤ãç´¹ä»ãã¾ãã
ã¤ã³ã©ã¤ã³ã¢ã»ã³ããªã使ããªã
IO ãã¼ãã«ã¢ã¯ã»ã¹ããããã«ã¯é常ã¢ã»ã³ããªãæ¸ãå¿
è¦ãããã¾ãã
ä»å㯠x86_64
ã¯ã¬ã¼ã ã® x86_64::instructions::port::Port
ãå©ç¨ãããã¨ã§ãã¤ã³ã©ã¤ã³ã¢ã»ã³ããªãææ¸ãããã«æ¸ã¾ãã¾ããã
ã¢ãããã¯ãª IO ãã¼ãã¢ã¯ã»ã¹
PCI ã³ã³ãã£ã°ã¬ã¼ã·ã§ã³ç©ºéã«ã¢ã¯ã»ã¹ããããã«ã¯
CONFIG_ADDRESS
ã¬ã¸ã¹ã¿ã¸ãã¢ã¯ã»ã¹ããã PCI ã³ã³ãã£ã°ã¬ã¼ã·ã§ã³ç©ºéã®ä½ç½®ãè¨å®CONFIG_DATA
ã¬ã¸ã¹ã¿ãèªã¿æ¸ããã
ã¨ãã2ã¤ã®æé ãå¿
è¦ã§ãã
ãã® 1 㨠2 ã®éã«å¥ã®ã¿ã¹ã¯ã CONFIG_ADDRESS
ã¬ã¸ã¹ã¿ã®æä½ãè¡ã£ã¦ãã¾ãã¨æå³ãã¬çµæã¨ãªãå¯è½æ§ãããããã両ã¬ã¸ã¹ã¿ã¸ã¢ã¯ã»ã¹ãã¦ããé㯠spin::Mutex
ã®ããã¯ãåå¾ããããã«ãã¾ããã
bit_field::BitField
ã®å©ç¨
PCI ã³ã³ãã£ã°ã¬ã¼ã·ã§ã³ç©ºéããããã¤ã¹ã®æ
å ±ãåå¾ããããã«ã¯ãããããã£ã¼ã«ãæä½ãå¿
è¦ã«ãªãã¾ãã
u32
ã®ãã¡ n ãããç®ãã m ãããç®ã¾ã§ãç¹å®ã®æ°å¤ãè¨å®ãããã¨ãã£ãæä½ã§ãã
ãã®æä½ãç°¡ååãããã bit_field
ã¯ã¬ã¼ã ã® bit_field::BitField
æ§é ä½ã使ãã¾ããã
ããããã£ã¼ã«ãã®èªã¿æ¸ãã以ä¸ã®ããã«æ¸ãã¾ãã
// å¤ã®è¨å® let mut value = 0u32; value.set_bits(0..8, u32::from(reg_addr)); value.set_bits(8..11, u32::from(function)); value.set_bits(11..16, u32::from(device)); value.set_bits(16..24, u32::from(bus)); value.set_bits(24..31, 0); value.set_bit(31, true); // å¤ã®åå¾ let bus = values.get_bits(16..24) as u8;
range ã®å½¢å¼ã§ãããç¯å²ã表ããã®ã¯é常ã«åããæãã§ããã
USB ãã¦ã¹ã¸ã®å¯¾å¿ (day06c)
ãã¦ããããåé¡ã®USBãã¦ã¹å¯¾å¿ã§ãã
å®è£ æ¹é
C++ çå®è£ ã§ã¯ããã¼ãããã®OSèªä½å ¥éãèè ã®æ¹ãéçºããã USB ãã©ã¤ãä¸å¼ãã¤ã³ãã¼ããã¦ä½¿ã£ã¦ãã¾ãã æ°ãããUSBé¢é£ã®ãã©ã¤ãã¯æ¬æ¸ã§èª¬æããã«ã¯é«åº¦ã§è¤éããã¾ãã®ã§ãçè ãéçºãããã©ã¤ãã使ãæ¹æ³ã説æããã ãã«ãã¾ããã¨ã®ãã¨ã OSèªä½ã主é¡ã§ãããããã®å¯¾å¿ã¯ã¾ã£ããæ£ããã¨æãã¾ãã
ã§ã¯ Rust çãå®è£ ããã«ãããã©ããããã§ãããç§ããã¼ãããã®OSèªä½å ¥éãã¨åãã¢ããã¼ããåãããã¨æãã¾ãã ã¤ã¾ããC++ã®USBãã©ã¤ãå®è£ ãæµç¨ãããã¨ã¨ãã¾ãã
USB ãã©ã¤ãã Rust ã§å®è£ ããã®ãèå³æ·±ãã§ãããå®éã«ãã®ã¢ããã¼ã㧠Rust ç MikanOS ãå®è£ ãããã¨ããã¦ããæ¹ããã¾ãã USB ãã©ã¤ãã®å®è£ ã«æåãããæ¹ãããã£ãããã¾ãã ããããç§ãåããã¨ããããã¨ããã¨ééããªãæéããããã§ããããããã®éãã®ããã°ã®æ´æ°ã¯æ¢ã¾ã£ã¦ãã¾ãã§ããããããªã«ããä½æ¥ã®ã¢ããã¼ã·ã§ã³ãä¿ã¤ã®ãé£ãããã ã¨èããã®ã§ã USB ãã©ã¤ãã® Rust 移æ¤ã¯ã¾ãã¯è«¦ãããã¨ã¨ãã¾ããã
USB ãã©ã¤ãã®ç§»æ¤ã¯ãä¸éã OS å®è£ ãå®äºãæºè¶³ããå¾ã§æ¬¡ã®èª²é¡ã¨ãã¦åãçµãããåãçµããããªã¨ããã¹ã¿ã³ã¹ã§é²ãã¦ããããã¨æãã¾ãã
ã¨ãããã㧠C++ ã½ã¼ã¹ã¨ Rust ã½ã¼ã¹ãçµåãã¦ä¸ã¤ã®ãã¤ã㪠(ã«ã¼ãã«) ãä½ããã¨ã«ãªãããã§ããã以ä¸ã®ãããªä½æ¦ãã¨ãã¾ããã
- MikanOS ã® USB ãã©ã¤ãä¸å¼ (ã¨ãRust ããå¼ã³åºãããã®ã°ã«ã¼ã³ã¼ã) ãå«ãã¯ã¬ã¼ã
mikanos_usb
ãä½æ mikanos_usb
ã®build.rs
㧠C++ ã½ã¼ã¹ãã³ã³ãã¤ã«ããéçã©ã¤ãã©ãªlibmikanos_usb.a
ãä½æããã¯ã¬ã¼ãã«å«ãã- 1, 2 ã§ä½æããã¯ã¬ã¼ããã«ã¼ãã«ã®ã¯ã¬ã¼ã (sabios) ããå©ç¨ãã
ãã®ä¸ã§ããã¤ã³ãã¨ãªã build.rs
ã®ä¸èº«ã«ã¤ãã¦èª¬æãã¾ãã
C++ ã½ã¼ã¹ã®ã³ã³ãã¤ã«
build.rs
ã®ä¸ã§ C++ ã½ã¼ã¹ãã³ã³ãã¤ã«ããããã«ã cc
ã¯ã¬ã¼ã ã使ãã¾ããã
ã³ã³ãã¤ã©ã¯ gcc/g++ ã§ã¯ãªã clang/clang++ ã使ãããããããå°ãè¡åãæªãã§ãã build.rs
å
ã§ç°å¢å¤æ° CC
㨠CXX
ã« clang
/ clang++
ãè¨å®ãã¦ãã¾ãã
ãªãã C++ ã®æ¨æºããããã¡ã¤ã«ãä¸å¼ç¨æããå¿ è¦ãããã¾ãã å½åã¯ã½ã¼ã¹ã³ã¼ãä¸ã«ããããã¡ã¤ã«ãå ¨ã¦å«ãã¦ããã®ã§ãããå¾ã«æ¹éå¤æ´ãã¦ãã¾ã (å¾è¿°)ã
ä¾åã©ã¤ãã©ãªã®å梱
C++ ã½ã¼ã¹ã¯ newlib
ã® libc
ããã³ LLVM ã® libc++
, libc++abi
ã«ä¾åãã¦ããããã libmikanos_usb.a
ãã«ã¼ãã«ã«ãªã³ã¯ããå ´åã¯ã libc.a
ããã³ libc++.a
, libc++abi.a
ããªã³ã¯ããå¿
è¦ãããã¾ãã
C++ çã§ã¯ä½è
ã®æ¹ãã³ã³ãã¤ã«ãããã¤ããªã使ã£ã¦ãã¾ãã
Rust çã§ã¯æ¬æ¥ã¯ãããã®ã©ã¤ãã©ãªã«ã¤ãã¦ãã½ã¼ã¹ãããã«ãããã®ãè¯ãã®ã§ãããã³ã³ãã¤ã«æéãé·ããªãããã ã£ãã®ã§ãä½è
ã®æ¹ãã³ã³ãã¤ã«ãããã¤ããªã使ããã¨ã«ãã¾ããã
å
·ä½çã«ã¯ã build.rs
ã®ä¸ã§ GitHub ããã©ã¤ãã©ãªãå«ãã ã¢ã¼ã«ã¤ãããã¦ã³ãã¼ãã OUT_DIR
é
ä¸ã«å±éã
println!("cargo:rustc-link-lib=static={}", lib);
ã«ãã cargo
ã«ã©ã¤ãã©ãªããªã³ã¯ãããã¨ãæ示ããã¨ããããæ¹ããã¾ããã
buiild.rs
ã®ä¸ã§ã¦ã§ãã«ã¢ã¯ã»ã¹ããã®ã¯ç¦ãæã§ãããããã¾ã§ã®å¦ç¿ç¨ã®ããã¸ã§ã¯ãã¨ãããã¨ã§ã容赦é ããã...
å¯ä½ç¨ã¨ãã¦ã GitHub ãããã¦ã³ãã¼ãããã¢ã¼ã«ã¤ãã«ã¯ããããã¡ã¤ã«ä¸å¼ãå«ã¾ãã¦ãããããC++ ã®ãã«ãæã«ããã®ããããã¡ã¤ã«ãå©ç¨ãããã¨ã¨ãã¾ããã ãªãã¸ããªã«å¤§éã®ããããã¡ã¤ã«ãç»é²ããªãã¦ãæ¸ãããã«ãªã£ãã¨ããã¯å¬ããã§ããã
ãã¦ãå¾ã¯ Rust ãã C++ ã³ã¼ããå¼ã³åºããããã«ãã¾ãã C++ ãã Rust ãå¼ã³åºããããã«ãã°ã«ã¼ã³ã¼ããæ¸ãã¾ãã
é©å½ã« extern "C"
ãªé¢æ°ãå®ç¾©ããã° OK ã§ãã
ãã¦ã C++ ã§å®ç¾©ãããã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãå¼ã³åºãã¨ããã¾ã§å®è£ ã§ãã¾ããã ã¾ã ãã¹ã¦ã¯å®è£ ã§ãã¦ãã¾ããããã§ããã¨ããããåä½ç¢ºèªãã¦ããã®ãè¯ãã§ãããã
åä½ç¢ºèª
C++ ã©ã¤ãã©ãªããªã³ã¯ & å¼ã³åºãããã«ãããã£ããå®è¡ãã¦ã¿ãã¨ããã OS ã reset ããã QEMU ä¸ã§åèµ·åãç¹°ãè¿ãããã«ãªã£ã¦ãã¾ããã ãªãã§ã§ããããã
ãããã°ã®ãã QEMU ã®èµ·åãªãã·ã§ã³ã« -d int --no-reboot --no-shutdown
ã追å ãã¾ãã
ããã«ãããå²ãè¾¼ã¿çºçæã«å²ãè¾¼ã¿ã®æ
å ±ãæ¨æºåºåã«åãåºããã¾ãã
ã¾ããOS ãªã»ããæã«ä»®æ³ãã·ã³ãåèµ·åããæ¢ã¾ã£ãç¶æ
ã®ã¾ã¾ã«ãªãã¾ãã
åå®è¡ããã¨ãããã©ãããä¾å¤ 0xe
ãçºçãã¦ããããã§ãã
OSDev Wiki ã«ããã¨ã 0xe
㯠Page Fault ã¨ã®ãã¨ã
ã©ãããä¸æ£ãªã¢ãã¬ã¹ã¸ã®ã¢ã¯ã»ã¹ãèµ·ãã¦ããããã§ããã
QEMU ã®åºåãããä¾å¤çºçæã® RIP ãåããã¾ãã
QEMU ã®ã³ã³ã½ã¼ã«ãã x /5i 0x<RIPã®å¤>
ãå®è¡ãããã¨ã§ RIP å¨è¾ºã®å®è¡å½ä»¤ãåããã¾ãã
ã¬ã¸ã¹ã¿ã®å¤ãªã©åããã¦å¤æããã«ã xhc_mmio_base
ã®ã¢ãã¬ã¹ã«ã¢ã¯ã»ã¹ãããã¨ã㦠Page Fault ãçºçãã¦ããããã§ãã
ãã®å¤ã¯ä»åå¼ã³åºãã追å ãã C++ ã® usb::xhc::Controller
ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã«æ¸¡ãã¦ããå¤ã§ããããã¤ãã¤ã¾ãåãã¾ããã
ãã¹ã¦ã®ç©çã¡ã¢ãªããããã³ã°ãã
ä»åå©ç¨ãã¦ãããã¼ããã¼ãã¼ã® bootloader
ã¯ã¬ã¼ãã¯ãã¼ã¸ãã¼ãã«ãæ´æ°ãã¦ããããã§ãã
xhc_mmio_base
ã®å¤ã¯ç©çã¢ãã¬ã¹ã®ã¯ãã§ããããã®ã¢ãã¬ã¹ã«åããä»®æ³ã¢ãã¬ã¹ããããã³ã°ããã¦ããªãã®ã§ã¯ãªããã¨èãã¾ããã
bootloader
ã®è¨å® ãåç
§ããã¨ããã map-physical-page
ã¨ããè¨å®ããããããã©ã«ãå¤ã¯ false
ã§ããã
ããã true
ã«ãããã¨ã§ç©çã¡ã¢ãªããããã³ã°ããã xhc_mmio_base
ã®ã¢ãã¬ã¹ã¸ãã¢ã¯ã»ã¹ã§ããããã«ãªãã®ã§ã¯ãªããã¨èã試ãã¦ã¿ã¾ããã
ãã®ãªãã·ã§ã³ã§ã¯ç©çã¢ãã¬ã¹0以éã®ã¡ã¢ãªã physical_memory_offset
ã ãããããä»®æ³ã¡ã¢ãªã¢ãã¬ã¹ã«ãããã³ã°ããããã xhc_mmio_base
ã®ã¢ãã¬ã¹ã« physical_memory_offset
ã ã足ãããã®ã usb::xhc::Controller
ã®ã³ã³ã¹ãã©ã¯ã¿ã«æ¸¡ãã¦ã¿ã¾ãã
ã ãã§ããã
bootloader
ã® map-physical-page æå¹æã®å¦ç ã§ã¯ãã¢ãã¬ã¹ 0 ããç©çã¡ã¢ãªãµã¤ãºåã®é åãä»®æ³ã¢ãã¬ã¹ã«ãããã³ã°ãã¦ãã¾ãã
ä»å xhc_mmio_base
ã®å¤ã¯ 0x8_0000_0000
ã ã£ãã®ã§ããããã㯠0x0
ãã 32GiB åã ãé¢ããé åã«ãªãã¾ãã
QEMU ä»®æ³ãã·ã³ã«ã¯ã®ã¡ã¢ãªå®¹éã¯ãã£ã¨å°ããã¯ããªã®ã§ã xhc_mmio_base
ã®é åãä»®æ³ã¢ãã¬ã¹ã«ãããã³ã°ãããªãã®ã¯å½ç¶ã§ãã
ã©ãããèªå㧠xhc_mmio_base
ã®ç©çã¢ãã¬ã¹ãä»®æ³ã¢ãã¬ã¹ã«ãããã³ã°ããå¿
è¦ãããããã§ããã
ãããã6ç« æç¹ã§ã¯ã¾ã ãã¼ã¸ã³ã°é¢é£å¦çã¯å®è£ ããã¦ãã¾ããã 6ç« ãé²ããã®ã¯ä¸æ¦ããã§ãããå ã«ãã¼ã¸ã³ã°ãå®è£ ãããã¨ã¨ãã¾ããã
ã¾ã¨ã
USB ãã©ã¤ããå©ç¨ãããã¨ããã¨ãããC++ããã°ã©ã ã®ã³ã³ãã¤ã«ã¨ãªã³ã¯ã¯ãã¾ãããã¾ãããã
bootloader
ã¯ã¬ã¼ãã®ä»æ§ã«ãã xhc_mmio_base
ã¸ã®ã¢ã¯ã»ã¹ãã§ãã¾ããã§ããã
対å¦ã®ããã«ã¯ãã¼ã¸ãã¼ãã«ãæ´æ°ãã¦å½è©²ã¢ãã¬ã¹ã¸ã¢ã¯ã»ã¹ã§ããããã«ããå¿
è¦ãããã¾ãã
ä¸æ¦6ç« ã¯ä¸æããå ã«8ç« ã«é²ããã¨ã«ãã¾ããã次åãã楽ãã¿ã«ã
- ã·ãªã¼ãºæåã®è¨äº: 「ゼロからのOS自作入門」を Rust でやる (第1章~第4章) - gifnksmの雑多なメモ
- åå: 「ゼロからのOS自作入門」を Rust でやる (第5章) - gifnksmの雑多なメモ
- 次å: 「ゼロからのOS自作入門」を Rust でやる (第8章) - gifnksmの雑多なメモ
- é¢é£è¨äºä¸è¦§: ゼロからのOS自作入門 カテゴリーの記事一覧 - gifnksmの雑多なメモ