From 981360c19c74dec01e21fdf00a2b6408df3f59fe Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Wed, 9 Aug 2023 10:28:51 +0200 Subject: [PATCH] ko: refresh translation for bare-metal (#928) Part of #925. Co-authored-by: Jiyong Park <55639800+jiyongp@users.noreply.github.com> --- po/ko.po | 2439 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2439 insertions(+) diff --git a/po/ko.po b/po/ko.po index 197618dd..bae35a27 100644 --- a/po/ko.po +++ b/po/ko.po @@ -15803,6 +15803,2445 @@ msgid "" "the class having a piece of code which you can turn in to Rust on the fly." msgstr "이 연습문제는 열려있기 때문에 해답이 제공되지 않습니다. 클래스에서 제출된 코드에 의존합니다." +#: src/bare-metal.md:3 +msgid "" +"This is a standalone one-day course about bare-metal Rust, aimed at people " +"who are familiar with the\n" +"basics of Rust (perhaps from completing the Comprehensive Rust course), and " +"ideally also have some\n" +"experience with bare-metal programming in some other language such as C." +msgstr "" +"이 과정은 Rust에 대해 어느정도 경험이 있고 (아마도 Comprehensive Rust 과정을 통해) C와 " +"같은 다른 언어로\n" +"bare-metal 프로그래밍을 해 본 사용자를 대상으로 하는 bare-metal Rust에 관한\n" +" 독립적인 1일 과정입니다." + +#: src/bare-metal.md:7 +msgid "" +"Today we will talk about 'bare-metal' Rust: running Rust code without an OS " +"underneath us. This will\n" +"be divided into several parts:" +msgstr "" +"오늘은 OS를 사용하지 않고 Rust 코드를 실행하는 'bare-metal' Rust에 관해 알아" +"봅니다. 본 강의의\n" +"구성은 다음과 같습니다." + +#: src/bare-metal.md:10 +msgid "" +"- What is `no_std` Rust?\n" +"- Writing firmware for microcontrollers.\n" +"- Writing bootloader / kernel code for application processors.\n" +"- Some useful crates for bare-metal Rust development." +msgstr "" +"- `no_std` Rust란 무엇인가요?\n" +"- 마이크로컨트롤러용 펌웨어 작성\n" +"- 애플리케이션 프로세서를 위한 부트로더 / 커널 코드 작성\n" +"- bare-metal Rust 개발을 위한 유용한 크레이트" + +#: src/bare-metal.md:15 +msgid "" +"For the microcontroller part of the course we will use the [BBC micro:bit]" +"(https://microbit.org/) v2\n" +"as an example. It's a [development board](https://tech.microbit.org/" +"hardware/) based on the Nordic\n" +"nRF51822 microcontroller with some LEDs and buttons, an I2C-connected " +"accelerometer and compass, and\n" +"an on-board SWD debugger." +msgstr "" +"이 강의에서는 [BBC micro:bit](https://microbit.org/) v2" +"마이크로컨트롤러를 사용합니다.\n" +"이 마이크로컨트롤러는 Nordic nRF51822 마이크로컨트롤러에 기반한\n" +"[개발 보드](https://tech.microbit.org/hardware/)로써,\n" +"LED와 버튼, I2C 연결 가속도계 및 나침반, 온보드 " +"SWD 디버거를 포함하고 있습니다." + +#: src/bare-metal.md:20 +msgid "" +"To get started, install some tools we'll need later. On gLinux or Debian:" +msgstr "시작하기전에, 앞으로 사용할 도구를 설치해야 합니다. gLinux 또는 Debian를 사용하고 있다면 아래와 같이 하세요." + +#: src/bare-metal.md:22 +msgid "" +"```bash\n" +"sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom pkg-" +"config qemu-system-arm\n" +"rustup update\n" +"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n" +"rustup component add llvm-tools-preview\n" +"cargo install cargo-binutils cargo-embed\n" +"```" +msgstr "" +"```bash\n" +"sudo apt install gcc-aarch64-linux-gnu gdb-multiarch libudev-dev picocom pkg-" +"config qemu-system-arm\n" +"rustup update\n" +"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n" +"rustup component add llvm-tools-preview\n" +"cargo install cargo-binutils cargo-embed\n" +"```" + +#: src/bare-metal.md:30 +msgid "" +"And give users in the `plugdev` group access to the micro:bit programmer:" +msgstr "" +"`plugdev` 그룹의 사용자에게 micro:bit 프로그래머 장치에 대한 액세스 권한을 부여합" +"니다." + +#: src/bare-metal.md:32 +msgid "" +"```bash\n" +"echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0d28\", MODE=\"0664\", " +"GROUP=\"plugdev\"' |\\\n" +" sudo tee /etc/udev/rules.d/50-microbit.rules\n" +"sudo udevadm control --reload-rules\n" +"```" +msgstr "" +"```bash\n" +"echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0d28\", MODE=\"0664\", " +"GROUP=\"plugdev\"' |\\\n" +" sudo tee /etc/udev/rules.d/50-microbit.rules\n" +"sudo udevadm control --reload-rules\n" +"```" + +#: src/bare-metal.md:38 +msgid "On MacOS:" +msgstr "MacOS에서:" + +#: src/bare-metal.md:40 +msgid "" +"```bash\n" +"xcode-select --install\n" +"brew install gdb picocom qemu\n" +"brew install --cask gcc-aarch64-embedded\n" +"rustup update\n" +"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n" +"rustup component add llvm-tools-preview\n" +"cargo install cargo-binutils cargo-embed\n" +"```" +msgstr "" +"```bash\n" +"xcode-select --install\n" +"brew install gdb picocom qemu\n" +"brew install --cask gcc-aarch64-embedded\n" +"rustup update\n" +"rustup target add aarch64-unknown-none thumbv7em-none-eabihf\n" +"rustup component add llvm-tools-preview\n" +"cargo install cargo-binutils cargo-embed\n" +"```" + +#: src/bare-metal/no_std.md:1 +msgid "# `no_std`" +msgstr "# `no_std`" + +#: src/bare-metal/no_std.md:3 +msgid "" +"\n" +"\n" +"\n" +"
" +msgstr "" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"
" + +#: src/bare-metal/no_std.md:7 +msgid "`core`" +msgstr "`core`" + +#: src/bare-metal/no_std.md:9 src/bare-metal/no_std.md:14 +msgid "" +"" +msgstr "" +"" + +#: src/bare-metal/no_std.md:12 +msgid "`alloc`" +msgstr "`alloc`" + +#: src/bare-metal/no_std.md:17 +msgid "`std`" +msgstr "`std`" + +#: src/bare-metal/no_std.md:19 +msgid "" +"
" +msgstr "" +"\n" +"
" + +#: src/bare-metal/no_std.md:24 +msgid "" +"* Slices, `&str`, `CStr`\n" +"* `NonZeroU8`...\n" +"* `Option`, `Result`\n" +"* `Display`, `Debug`, `write!`...\n" +"* `Iterator`\n" +"* `panic!`, `assert_eq!`...\n" +"* `NonNull` and all the usual pointer-related functions\n" +"* `Future` and `async`/`await`\n" +"* `fence`, `AtomicBool`, `AtomicPtr`, `AtomicU32`...\n" +"* `Duration`" +msgstr "" +"* Slices, `&str`, `CStr`\n" +"* `NonZeroU8`...\n" +"* `Option`, `Result`\n" +"* `Display`, `Debug`, `write!`...\n" +"* `Iterator`\n" +"* `panic!`, `assert_eq!`...\n" +"* `NonNull` 및 모든 일반적인 포인터 관련 함수\n" +"* `Future` and `async`/`await`\n" +"* `fence`, `AtomicBool`, `AtomicPtr`, `AtomicU32`...\n" +"* `Duration`" + +#: src/bare-metal/no_std.md:35 src/bare-metal/no_std.md:42 +msgid "" +"" +msgstr "" +"" + +#: src/bare-metal/no_std.md:38 +msgid "" +"* `Box`, `Cow`, `Arc`, `Rc`\n" +"* `Vec`, `BinaryHeap`, `BtreeMap`, `LinkedList`, `VecDeque`\n" +"* `String`, `CString`, `format!`" +msgstr "" +"* `Box`, `Cow`, `Arc`, `Rc`\n" +"* `Vec`, `BinaryHeap`, `BtreeMap`, `LinkedList`, `VecDeque`\n" +"* `String`, `CString`, `format!`" + +#: src/bare-metal/no_std.md:45 +msgid "" +"* `Error`\n" +"* `HashMap`\n" +"* `Mutex`, `Condvar`, `Barrier`, `Once`, `RwLock`, `mpsc`\n" +"* `File` and the rest of `fs`\n" +"* `println!`, `Read`, `Write`, `Stdin`, `Stdout` and the rest of `io`\n" +"* `Path`, `OsString`\n" +"* `net`\n" +"* `Command`, `Child`, `ExitCode`\n" +"* `spawn`, `sleep` and the rest of `thread`\n" +"* `SystemTime`, `Instant`" +msgstr "" +"* `Error`\n" +"* `HashMap`\n" +"* `Mutex`, `Condvar`, `Barrier`, `Once`, `RwLock`, `mpsc`\n" +"* `File` 및 나머지 `fs`\n" +"* `println!`, `Read`, `Write`, `Stdin`, `Stdout` 및 나머지 `io`\n" +"* `Path`, `OsString`\n" +"* `net`\n" +"* `Command`, `Child`, `ExitCode`\n" +"* `spawn`, `sleep` 및 나머지 `thread`\n" +"* `SystemTime`, `Instant`" + +#: src/bare-metal/no_std.md:56 +msgid "" +"
\n" +"\n" +"
" +msgstr "" +"\n" +"
\n" +"\n" +"
" + +#: src/bare-metal/no_std.md:62 +msgid "" +"* `HashMap` depends on RNG.\n" +"* `std` re-exports the contents of both `core` and `alloc`." +msgstr "" +"* `HashMap`은 RNG에 의존합니다.\n" +"* `std`는 `core` 및 `alloc`를 포함합니다." + +#: src/bare-metal/minimal.md:1 +msgid "# A minimal `no_std` program" +msgstr "# 최소한의 `no_std` 프로그램" + +#: src/bare-metal/minimal.md:3 +msgid "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"use core::panic::PanicInfo;\n" +"\n" +"#[panic_handler]\n" +"fn panic(_panic: &PanicInfo) -> ! {\n" +" loop {}\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"use core::panic::PanicInfo;\n" +"\n" +"#[panic_handler]\n" +"fn panic(_panic: &PanicInfo) -> ! {\n" +" loop {}\n" +"}\n" +"```" + +#: src/bare-metal/minimal.md:17 +msgid "" +"* This will compile to an empty binary.\n" +"* `std` provides a panic handler; without it we must provide our own.\n" +"* It can also be provided by another crate, such as `panic-halt`.\n" +"* Depending on the target, you may need to compile with `panic = \"abort\"` " +"to avoid an error about\n" +" `eh_personality`.\n" +"* Note that there is no `main` or any other entry point; it's up to you to " +"define your own entry\n" +" point. This will typically involve a linker script and some assembly code " +"to set things up ready\n" +" for Rust code to run." +msgstr "" +"* 이 코드는 빈 바이너리로 컴파일됩니다.\n" +"* `std`는 패닉 핸들러를 제공하지만, 우리는 자체적으로 핸들러를 만들어야" +"합니다.\n" +"* 패닉 핸들러는 `panic-halt`와 같은 크레이트를 통해서 만들수도 있습니다.\n" +"* 타겟에 따라 `panic = \"abort\"`로 컴파일해야 할 수 있습니다. 이는 " +"`eh_personality`에 관한 오류를\n" +" 방지하기 위함입니다.\n" +"* `main` 과 같은 프로그램 진입점이 없습니다. 개발자가 자체적으로 진입점을 정의해야\n" +" 합니다. 진입점을 정의하는 작업은, 일반적으로 링커 스크립트와 어셈블리 코드를 필요로 합니다." + +#: src/bare-metal/alloc.md:1 +msgid "# `alloc`" +msgstr "# `alloc`" + +#: src/bare-metal/alloc.md:3 +msgid "" +"To use `alloc` you must implement a\n" +"[global (heap) allocator](https://doc.rust-lang.org/stable/std/alloc/trait." +"GlobalAlloc.html)." +msgstr "" +"`alloc`을 사용하려면 [전역 (힙) 할당자](https://doc.rust-lang.org/stable/std/" +"alloc/trait.GlobalAlloc.html)를\n" +"구현해야 합니다." + +#: src/bare-metal/alloc.md:6 +msgid "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate alloc;\n" +"extern crate panic_halt as _;\n" +"\n" +"use alloc::string::ToString;\n" +"use alloc::vec::Vec;\n" +"use buddy_system_allocator::LockedHeap;\n" +"\n" +"#[global_allocator]\n" +"static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();\n" +"\n" +"static mut HEAP: [u8; 65536] = [0; 65536];\n" +"\n" +"pub fn entry() {\n" +" // Safe because `HEAP` is only used here and `entry` is only called " +"once.\n" +" unsafe {\n" +" // Give the allocator some memory to allocate.\n" +" HEAP_ALLOCATOR\n" +" .lock()\n" +" .init(HEAP.as_mut_ptr() as usize, HEAP.len());\n" +" }\n" +"\n" +" // Now we can do things that require heap allocation.\n" +" let mut v = Vec::new();\n" +" v.push(\"A string\".to_string());\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate alloc;\n" +"extern crate panic_halt as _;\n" +"\n" +"use alloc::string::ToString;\n" +"use alloc::vec::Vec;\n" +"use buddy_system_allocator::LockedHeap;\n" +"\n" +"#[global_allocator]\n" +"static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::<32>::new();\n" +"\n" +"static mut HEAP: [u8; 65536] = [0; 65536];\n" +"\n" +"pub fn entry() {\n" +" // Safe because `HEAP` is only used here and `entry` is only called " +"once.\n" +" unsafe {\n" +" // Give the allocator some memory to allocate.\n" +" HEAP_ALLOCATOR\n" +" .lock()\n" +" .init(HEAP.as_mut_ptr() as usize, HEAP.len());\n" +" }\n" +"\n" +" // 이제 힙 할당이 필요한 작업을 실행할 수 있습니다.\n" +" let mut v = Vec::new();\n" +" v.push(\"A string\".to_string());\n" +"}\n" +"```" + +#: src/bare-metal/alloc.md:39 +msgid "" +"* `buddy_system_allocator` is a third-party crate implementing a basic buddy " +"system allocator. Other\n" +" crates are available, or you can write your own or hook into your existing " +"allocator.\n" +"* The const parameter of `LockedHeap` is the max order of the allocator; i." +"e. in this case it can\n" +" allocate regions of up to 2**32 bytes.\n" +"* If any crate in your dependency tree depends on `alloc` then you must have " +"exactly one global\n" +" allocator defined in your binary. Usually this is done in the top-level " +"binary crate.\n" +"* `extern crate panic_halt as _` is necessary to ensure that the " +"`panic_halt` crate is linked in so\n" +" we get its panic handler.\n" +"* This example will build but not run, as it doesn't have an entry point." +msgstr "" +"* `buddy_system_allocator`는 간단한 버디 시스템 할당자를 구현하는 서드 파티 크" +"레이트입니다. 이 외에도, 다른\n" +" 크레이트를 사용하거나, 직접 할당자를 만들거나, 이미 존재하는 다른 할당자에 후킹할 수 있습니다.\n" +"* `LockHeap` 타입의 const 매개변수는 할당자의 최대 크기를 2진수로 표현했을 때의 자릿수입니다. 즉, 이 경우처럼 32인 경우 최대 " +"2**32바이트 크기의\n" +" 영역을 다룰 수 있습니다.\n" +"* 한 바이너리에서 `alloc`에 의존하는 크레이트가 하나라도 있다면\n" +"바이너리 전체에서 전역 할당자가 반드시 하나 존재해야 합니다. 일반적으로 전역 할당자를 선언하는 작업은 최상위 바이너리 크레이트" +"에서 이루어집니다.\n" +"* `panic_halt` 크레이트가 연결되어 패닉 핸들러를 가져오도록 하려면\n" +" `extern crate panic_halt as _`가 필요합니다.\n" +"* 이 예시 코드는 빌드는 되지만, 진입점이 없기 때문에 실행되지는 않습니다." + +#: src/bare-metal/microcontrollers.md:1 +msgid "# Microcontrollers" +msgstr "# 마이크로컨트롤러" + +#: src/bare-metal/microcontrollers.md:3 +msgid "" +"The `cortex_m_rt` crate provides (among other things) a reset handler for " +"Cortex M microcontrollers." +msgstr "" +"'cortex_m_rt' 크레이트는 Cortex M 마이크로컨트롤러를 초기화 하는 핸들러" +"를 제공합니다." + +#: src/bare-metal/microcontrollers.md:5 +msgid "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"mod interrupts;\n" +"\n" +"use cortex_m_rt::entry;\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" loop {}\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"mod interrupts;\n" +"\n" +"use cortex_m_rt::entry;\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" loop {}\n" +"}\n" +"```" + +#: src/bare-metal/microcontrollers.md:21 +msgid "" +"Next we'll look at how to access peripherals, with increasing levels of " +"abstraction." +msgstr "" +"이제, 주변장치에 액세스하는 방법을 알아보겠습니다. 가장 기계에 가까운 낮은 단계에서 시작해서 점점 추상화 수준을 올리겠습니다." + +#: src/bare-metal/microcontrollers.md:25 +msgid "" +"* The `cortex_m_rt::entry` macro requires that the function have type `fn() -" +"> !`, because returning\n" +" to the reset handler doesn't make sense.\n" +"* Run the example with `cargo embed --bin minimal`" +msgstr "" +"* `cortex_m_rt::entry` 매크로는 진입점으로 사용되는 함수가`fn() -> !` 타입(즉, 리턴하지 않는)임을 요구합니다. " +"만약, 리턴하게 되면, 프로그램 수행 후 리셋 핸들러로 돌아가게 되는 것인데 이는 말이 되지 않기 때문입니다.\n" +"* `cargo embed --bin minimal`을 사용하여 예시를 실행합니다." + +#: src/bare-metal/microcontrollers/mmio.md:1 +msgid "# Raw MMIO" +msgstr "# 원시 MMIO" + +#: src/bare-metal/microcontrollers/mmio.md:3 +msgid "" +"Most microcontrollers access peripherals via memory-mapped IO. Let's try " +"turning on an LED on our\n" +"micro:bit:" +msgstr "" +"대부분의 마이크로컨트롤러는 메모리 매핑 IO를 통해 주변기기에 액세스합니다. " +"micro:bit에서 LED를\n" +"켜보겠습니다." + +#: src/bare-metal/microcontrollers/mmio.md:6 +msgid "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"mod interrupts;\n" +"\n" +"use core::mem::size_of;\n" +"use cortex_m_rt::entry;\n" +"\n" +"/// GPIO port 0 peripheral address\n" +"const GPIO_P0: usize = 0x5000_0000;\n" +"\n" +"// GPIO peripheral offsets\n" +"const PIN_CNF: usize = 0x700;\n" +"const OUTSET: usize = 0x508;\n" +"const OUTCLR: usize = 0x50c;\n" +"\n" +"// PIN_CNF fields\n" +"const DIR_OUTPUT: u32 = 0x1;\n" +"const INPUT_DISCONNECT: u32 = 0x1 << 1;\n" +"const PULL_DISABLED: u32 = 0x0 << 2;\n" +"const DRIVE_S0S1: u32 = 0x0 << 8;\n" +"const SENSE_DISABLED: u32 = 0x0 << 16;\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n" +" let pin_cnf_21 = (GPIO_P0 + PIN_CNF + 21 * size_of::()) as *mut " +"u32;\n" +" let pin_cnf_28 = (GPIO_P0 + PIN_CNF + 28 * size_of::()) as *mut " +"u32;\n" +" // Safe because the pointers are to valid peripheral control registers, " +"and\n" +" // no aliases exist.\n" +" unsafe {\n" +" pin_cnf_21.write_volatile(\n" +" DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | " +"SENSE_DISABLED,\n" +" );\n" +" pin_cnf_28.write_volatile(\n" +" DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | " +"SENSE_DISABLED,\n" +" );\n" +" }\n" +"\n" +" // Set pin 28 low and pin 21 high to turn the LED on.\n" +" let gpio0_outset = (GPIO_P0 + OUTSET) as *mut u32;\n" +" let gpio0_outclr = (GPIO_P0 + OUTCLR) as *mut u32;\n" +" // Safe because the pointers are to valid peripheral control registers, " +"and\n" +" // no aliases exist.\n" +" unsafe {\n" +" gpio0_outclr.write_volatile(1 << 28);\n" +" gpio0_outset.write_volatile(1 << 21);\n" +" }\n" +"\n" +" loop {}\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"mod interrupts;\n" +"\n" +"use core::mem::size_of;\n" +"use cortex_m_rt::entry;\n" +"\n" +"/// GPIO 포트 0 주변기기 주소입니다.\n" +"const GPIO_P0: usize = 0x5000_0000;\n" +"\n" +"// GPIO 주변기기 오프셋입니다.\n" +"const PIN_CNF: usize = 0x700;\n" +"const OUTSET: usize = 0x508;\n" +"const OUTCLR: usize = 0x50c;\n" +"\n" +"// PIN_CNF 필드입니다.\n" +"const DIR_OUTPUT: u32 = 0x1;\n" +"const INPUT_DISCONNECT: u32 = 0x1 << 1;\n" +"const PULL_DISABLED: u32 = 0x0 << 2;\n" +"const DRIVE_S0S1: u32 = 0x0 << 8;\n" +"const SENSE_DISABLED: u32 = 0x0 << 16;\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n" +" let pin_cnf_21 = (GPIO_P0 + PIN_CNF + 21 * size_of::()) as *mut " +"u32;\n" +" let pin_cnf_28 = (GPIO_P0 + PIN_CNF + 28 * size_of::()) as *mut " +"u32;\n" +" // Safe because the pointers are to valid peripheral control registers, " +"and\n" +" // no aliases exist.\n" +" unsafe {\n" +" pin_cnf_21.write_volatile(\n" +" DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | " +"SENSE_DISABLED,\n" +" );\n" +" pin_cnf_28.write_volatile(\n" +" DIR_OUTPUT | INPUT_DISCONNECT | PULL_DISABLED | DRIVE_S0S1 | " +"SENSE_DISABLED,\n" +" );\n" +" }\n" +"\n" +" // 핀 28을 low로, 핀 21을 high로 설정하여 LED을 켭니다.\n" +" let gpio0_outset = (GPIO_P0 + OUTSET) as *mut u32;\n" +" let gpio0_outclr = (GPIO_P0 + OUTCLR) as *mut u32;\n" +" // 포인터가 유효한 주변기기 컨트롤 레지스터에 관한 것이므로 안전하고\n" +" // 별칭이 없습니다.\n" +" unsafe {\n" +" gpio0_outclr.write_volatile(1 << 28);\n" +" gpio0_outset.write_volatile(1 << 21);\n" +" }\n" +"\n" +" loop {}\n" +"}\n" +"```" + +#: src/bare-metal/microcontrollers/mmio.md:64 +msgid "" +"* GPIO 0 pin 21 is connected to the first column of the LED matrix, and pin " +"28 to the first row." +msgstr "" +"* GPIO 0 핀 21은 LED 매트릭스의 첫 번째 열에 연결되고 핀 28은 첫 번째 행에 연" +"결됩니다." + +#: src/bare-metal/microcontrollers/mmio.md:66 +#: src/bare-metal/microcontrollers/pacs.md:59 +#: src/bare-metal/microcontrollers/hals.md:43 +#: src/bare-metal/microcontrollers/board-support.md:34 +msgid "Run the example with:" +msgstr "아래 명령어로 예제 코드를 실행하세요." + +#: src/bare-metal/microcontrollers/mmio.md:68 +msgid "" +"```sh\n" +"cargo embed --bin mmio\n" +"```" +msgstr "" +"```sh\n" +"cargo embed --bin mmio\n" +"```" + +#: src/bare-metal/microcontrollers/pacs.md:1 +msgid "# Peripheral Access Crates" +msgstr "# 주변기기 액세스 크레이트" + +#: src/bare-metal/microcontrollers/pacs.md:3 +msgid "" +"[`svd2rust`](https://crates.io/crates/svd2rust) generates mostly-safe Rust " +"wrappers for\n" +"memory-mapped peripherals from [CMSIS-SVD](https://www.keil.com/pack/doc/" +"CMSIS/SVD/html/index.html)\n" +"files." +msgstr "" +"[`svd2rust`](https://crates.io/crates/svd2rust) 크레이트를 이용하면 메모리 매핑된 " +"주변장치를 기술하는 [CMSIS-SVD](https://www." +"keil.com/pack/doc/CMSIS/SVD/html/index.html) 파일로부터\n" +"Rust 래퍼를 생성할 수 있습니다." + +#: src/bare-metal/microcontrollers/pacs.md:7 +msgid "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"use cortex_m_rt::entry;\n" +"use nrf52833_pac::Peripherals;\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" let p = Peripherals::take().unwrap();\n" +" let gpio0 = p.P0;\n" +"\n" +" // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n" +" gpio0.pin_cnf[21].write(|w| {\n" +" w.dir().output();\n" +" w.input().disconnect();\n" +" w.pull().disabled();\n" +" w.drive().s0s1();\n" +" w.sense().disabled();\n" +" w\n" +" });\n" +" gpio0.pin_cnf[28].write(|w| {\n" +" w.dir().output();\n" +" w.input().disconnect();\n" +" w.pull().disabled();\n" +" w.drive().s0s1();\n" +" w.sense().disabled();\n" +" w\n" +" });\n" +"\n" +" // Set pin 28 low and pin 21 high to turn the LED on.\n" +" gpio0.outclr.write(|w| w.pin28().clear());\n" +" gpio0.outset.write(|w| w.pin21().set());\n" +"\n" +" loop {}\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"use cortex_m_rt::entry;\n" +"use nrf52833_pac::Peripherals;\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" let p = Peripherals::take().unwrap();\n" +" let gpio0 = p.P0;\n" +"\n" +" // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n" +" gpio0.pin_cnf[21].write(|w| {\n" +" w.dir().output();\n" +" w.input().disconnect();\n" +" w.pull().disabled();\n" +" w.drive().s0s1();\n" +" w.sense().disabled();\n" +" w\n" +" });\n" +" gpio0.pin_cnf[28].write(|w| {\n" +" w.dir().output();\n" +" w.input().disconnect();\n" +" w.pull().disabled();\n" +" w.drive().s0s1();\n" +" w.sense().disabled();\n" +" w\n" +" });\n" +"\n" +" // 핀 28을 low로, 핀 21을 high로 설정하여 LED를 켭니다.\n" +" gpio0.outclr.write(|w| w.pin28().clear());\n" +" gpio0.outset.write(|w| w.pin21().set());\n" +"\n" +" loop {}\n" +"}\n" +"```" + +#: src/bare-metal/microcontrollers/pacs.md:49 +msgid "" +"* SVD (System View Description) files are XML files typically provided by " +"silicon vendors which\n" +" describe the memory map of the device.\n" +" * They are organised by peripheral, register, field and value, with names, " +"descriptions, addresses\n" +" and so on.\n" +" * SVD files are often buggy and incomplete, so there are various projects " +"which patch the\n" +" mistakes, add missing details, and publish the generated crates.\n" +"* `cortex-m-rt` provides the vector table, among other things.\n" +"* If you `cargo install cargo-binutils` then you can run\n" +" `cargo objdump --bin pac -- -d --no-show-raw-insn` to see the resulting " +"binary." +msgstr "" +"* SVD(System View Description) 파일은 일반적으로 실리콘 공급업체에서 제공하" +"는 XML 파일로,\n" +" 기기의 메모리 맵을 기술합니다.\n" +" * 주변기기, 레지스터, 필드, 값으로 구성되며 이름, 설명, 주소 등이\n" +" 포함됩니다.\n" +" * SVD 파일에는 버그가 있을 수 있고 불완전하기 때문에, 이러한 문제들을 패치하는 다양한 프로젝트들이 있습니다.\n" +"* `cortex-m-rt`는 무엇보다도 벡터 테이블을 제공합니다.\n" +"* `cargo install cargo-binutils`을 실행한 후, `cargo objdump --bin pac -- -d --no-" +"show-raw-insn`을 실행하여\n" +" 생성된 바이너리의 내용을 확인할 수 있습니다." + +#: src/bare-metal/microcontrollers/pacs.md:61 +msgid "" +"```sh\n" +"cargo embed --bin pac\n" +"```" +msgstr "" +"```sh\n" +"cargo embed --bin pac\n" +"```" + +#: src/bare-metal/microcontrollers/hals.md:1 +msgid "# HAL crates" +msgstr "# HAL 크레이트들" + +#: src/bare-metal/microcontrollers/hals.md:3 +msgid "" +"[HAL crates](https://github.com/rust-embedded/awesome-embedded-rust#hal-" +"implementation-crates) for\n" +"many microcontrollers provide wrappers around various peripherals. These " +"generally implement traits\n" +"from [`embedded-hal`](https://crates.io/crates/embedded-hal)." +msgstr "" +"다양한 주변 장치에 대한 래퍼를 제공하는 [HAL 크레이트](https://github.com/rust-embedded/" +"awesome-embedded-rust#hal-implementation-crates)들이 있습니다. 이 크레이트들은 일반적으로\n" +"[`embedded-hal`](https://crates.io/crates/embedded-hal)의 트레잇을 구현합니" +"다." + +#: src/bare-metal/microcontrollers/hals.md:7 +msgid "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"use cortex_m_rt::entry;\n" +"use nrf52833_hal::gpio::{p0, Level};\n" +"use nrf52833_hal::pac::Peripherals;\n" +"use nrf52833_hal::prelude::*;\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" let p = Peripherals::take().unwrap();\n" +"\n" +" // Create HAL wrapper for GPIO port 0.\n" +" let gpio0 = p0::Parts::new(p.P0);\n" +"\n" +" // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n" +" let mut col1 = gpio0.p0_28.into_push_pull_output(Level::High);\n" +" let mut row1 = gpio0.p0_21.into_push_pull_output(Level::Low);\n" +"\n" +" // Set pin 28 low and pin 21 high to turn the LED on.\n" +" col1.set_low().unwrap();\n" +" row1.set_high().unwrap();\n" +"\n" +" loop {}\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"use cortex_m_rt::entry;\n" +"use nrf52833_hal::gpio::{p0, Level};\n" +"use nrf52833_hal::pac::Peripherals;\n" +"use nrf52833_hal::prelude::*;\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" let p = Peripherals::take().unwrap();\n" +"\n" +" // Create HAL wrapper for GPIO port 0.\n" +" let gpio0 = p0::Parts::new(p.P0);\n" +"\n" +" // Configure GPIO 0 pins 21 and 28 as push-pull outputs.\n" +" let mut col1 = gpio0.p0_28.into_push_pull_output(Level::High);\n" +" let mut row1 = gpio0.p0_21.into_push_pull_output(Level::Low);\n" +"\n" +" // Set pin 28 low and pin 21 high to turn the LED on.\n" +" col1.set_low().unwrap();\n" +" row1.set_high().unwrap();\n" +"\n" +" loop {}\n" +"}\n" +"```" + +#: src/bare-metal/microcontrollers/hals.md:39 +msgid "" +" * `set_low` and `set_high` are methods on the `embedded_hal` `OutputPin` " +"trait.\n" +" * HAL crates exist for many Cortex-M and RISC-V devices, including various " +"STM32, GD32, nRF, NXP,\n" +" MSP430, AVR and PIC microcontrollers." +msgstr "" +" * `set_low` 및 `set_high`는 `embedded_hal` `OutputPin` 트레잇의 메서드입니" +"다.\n" +" * 다양한 STM32, GD32, nRF, NXP, MSP430, AVR, PIC 마이크로컨트롤러를 비롯한\n" +" 많은 Cortex-M 및 RISC-V 기기를 위한 HAL 크레이트가 있습니다" + +#: src/bare-metal/microcontrollers/hals.md:45 +msgid "" +"```sh\n" +"cargo embed --bin hal\n" +"```" +msgstr "" +"```sh\n" +"cargo embed --bin hal\n" +"```" + +#: src/bare-metal/microcontrollers/board-support.md:3 +msgid "" +"Board support crates provide a further level of wrapping for a specific " +"board for convenience." +msgstr "" +"보드 지원 크레이트들은, 특정 보드를 더 손쉽게 사용할 수 있게 해 주는 더 높은 수준의 추상화를 제공합니다." + +#: src/bare-metal/microcontrollers/board-support.md:5 +msgid "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"use cortex_m_rt::entry;\n" +"use microbit::hal::prelude::*;\n" +"use microbit::Board;\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" let mut board = Board::take().unwrap();\n" +"\n" +" board.display_pins.col1.set_low().unwrap();\n" +" board.display_pins.row1.set_high().unwrap();\n" +"\n" +" loop {}\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"use cortex_m_rt::entry;\n" +"use microbit::hal::prelude::*;\n" +"use microbit::Board;\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" let mut board = Board::take().unwrap();\n" +"\n" +" board.display_pins.col1.set_low().unwrap();\n" +" board.display_pins.row1.set_high().unwrap();\n" +"\n" +" loop {}\n" +"}\n" +"```" + +#: src/bare-metal/microcontrollers/board-support.md:28 +msgid "" +" * In this case the board support crate is just providing more useful names, " +"and a bit of\n" +" initialisation.\n" +" * The crate may also include drivers for some on-board devices outside of " +"the microcontroller\n" +" itself.\n" +" * `microbit-v2` includes a simple driver for the LED matrix." +msgstr "" +" * 이 경우 보드 지원 크레이트는 좀 더 직관적인 이름들과 적당한 수준의 초기화를\n" +" 제공합니다.\n" +" * 이 크레이트는 마이크로컨트롤 밖에 있는 (즉, 보드에 설치된) 장치에 대한 드라이버도\n" +" 포함할 수 있습니다.\n" +" * `microbit-v2`에는 LED 매트릭스를 위한 간단한 드라이버가 포함되어 있습니" +"다." + +#: src/bare-metal/microcontrollers/board-support.md:36 +msgid "" +"```sh\n" +"cargo embed --bin board_support\n" +"```" +msgstr "" +"```sh\n" +"cargo embed --bin board_support\n" +"```" + +#: src/bare-metal/microcontrollers/type-state.md:1 +msgid "# The type state pattern" +msgstr "# 타입 상태 패턴" + +#: src/bare-metal/microcontrollers/type-state.md:3 +msgid "" +"```rust,editable,compile_fail\n" +"#[entry]\n" +"fn main() -> ! {\n" +" let p = Peripherals::take().unwrap();\n" +" let gpio0 = p0::Parts::new(p.P0);\n" +"\n" +" let pin: P0_01 = gpio0.p0_01;\n" +"\n" +" // let gpio0_01_again = gpio0.p0_01; // Error, moved.\n" +" let pin_input: P0_01> = pin.into_floating_input();\n" +" if pin_input.is_high().unwrap() {\n" +" // ...\n" +" }\n" +" let mut pin_output: P0_01> = pin_input\n" +" .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, " +"Level::Low);\n" +" pin_output.set_high().unwrap();\n" +" // pin_input.is_high(); // Error, moved.\n" +"\n" +" let _pin2: P0_02> = gpio0\n" +" .p0_02\n" +" .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, " +"Level::Low);\n" +" let _pin3: P0_03> = gpio0.p0_03." +"into_push_pull_output(Level::Low);\n" +"\n" +" loop {}\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"#[entry]\n" +"fn main() -> ! {\n" +" let p = Peripherals::take().unwrap();\n" +" let gpio0 = p0::Parts::new(p.P0);\n" +"\n" +" let pin: P0_01 = gpio0.p0_01;\n" +"\n" +" // let gpio0_01_again = gpio0.p0_01; // Error, moved.\n" +" let pin_input: P0_01> = pin.into_floating_input();\n" +" if pin_input.is_high().unwrap() {\n" +" // ...\n" +" }\n" +" let mut pin_output: P0_01> = pin_input\n" +" .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, " +"Level::Low);\n" +" pin_output.set_high().unwrap();\n" +" // pin_input.is_high(); // 오류, 이동했습니다.\n" +"\n" +" let _pin2: P0_02> = gpio0\n" +" .p0_02\n" +" .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, " +"Level::Low);\n" +" let _pin3: P0_03> = gpio0.p0_03." +"into_push_pull_output(Level::Low);\n" +"\n" +" loop {}\n" +"}\n" +"```" + +#: src/bare-metal/microcontrollers/type-state.md:32 +msgid "" +" * Pins don't implement `Copy` or `Clone`, so only one instance of each can " +"exist. Once a pin is\n" +" moved out of the port struct nobody else can take it.\n" +" * Changing the configuration of a pin consumes the old pin instance, so you " +"can’t keep use the old\n" +" instance afterwards.\n" +" * The type of a value indicates the state that it is in: e.g. in this case, " +"the configuration state\n" +" of a GPIO pin. This encodes the state machine into the type system, and " +"ensures that you don't\n" +" try to use a pin in a certain way without properly configuring it first. " +"Illegal state\n" +" transitions are caught at compile time.\n" +" * You can call `is_high` on an input pin and `set_high` on an output pin, " +"but not vice-versa.\n" +" * Many HAL crates follow this pattern." +msgstr "" +" * 핀은 `Copy` 또는 `Clone`을 구현하지 않으므로 각각 하나의 인스턴스만 존재" +"할 수 있습니다. 핀을\n" +" 포트 구조체 밖으로 이동하면 아무도 사용할 수 없습니다.\n" +" * 핀 구성을 변경하면 이전 핀 인스턴스가 사용되므로 이후에\n" +" 이전 인스턴스를 계속 사용할 수 없습니다.\n" +" * 값 유형은 현재 상태를 나타냅니다. 예를 들어 이 경우에는\n" +" GPIO 핀의 구성 상태입니다. 이렇게 하면 상태 머신이 유형 시스템으로 인코딩" +"되며, 먼저 올바르게\n" +" 구성한 후 특정 방식으로 핀을 사용하도록 합니다. 잘못된 상태 전환은 컴파일 " +"시간에\n" +" 포착됩니다.\n" +" * 입력 핀에서 `is_high`를 호출하고 출력 핀에서 `set_high`를 호출할 수 있지" +"만 그 반대로는 안 됩니다.\n" +" * 많은 HAL 크레이트들이 이 패턴을 따릅니다." + +#: src/bare-metal/microcontrollers/embedded-hal.md:1 +msgid "# `embedded-hal`" +msgstr "# `embedded-hal`" + +#: src/bare-metal/microcontrollers/embedded-hal.md:3 +msgid "" +"The [`embedded-hal`](https://crates.io/crates/embedded-hal) crate provides a " +"number of traits\n" +"covering common microcontroller peripherals." +msgstr "" +"[`embedded-hal`](https://crates.io/crates/embedded-hal) 크레이트는 " +"다양한 마이크로컨트롤러에서 공통적으로 찾아볼 수 있는 주변기기를 추상회 하는 다양한\n" +"트레잇을 제공합니다." + +#: src/bare-metal/microcontrollers/embedded-hal.md:6 +msgid "" +" * GPIO\n" +" * ADC\n" +" * I2C, SPI, UART, CAN\n" +" * RNG\n" +" * Timers\n" +" * Watchdogs" +msgstr "" +" * GPIO\n" +" * ADC\n" +" * I2C, SPI, UART, CAN\n" +" * RNG\n" +" * 타이머\n" +" * 워치독" + +#: src/bare-metal/microcontrollers/embedded-hal.md:13 +msgid "" +"Other crates then implement\n" +"[drivers](https://github.com/rust-embedded/awesome-embedded-rust#driver-" +"crates) in terms of these\n" +"traits, e.g. an accelerometer driver might need an I2C or SPI bus " +"implementation." +msgstr "" +"그러면 다른 크레이트는 이 트레잇들을 활용하여 [드라이버](https://github.com/" +"rust-embedded/awesome-embedded-rust#driver-crates)를\n" +"구현합니다. 예를 들어 가속도계 드라이버를 구현할 떄 I2C 또는 SPI 버스 구현을\n" +"사용할 수 있습니다." + +#: src/bare-metal/microcontrollers/embedded-hal.md:19 +msgid "" +" * There are implementations for many microcontrollers, as well as other " +"platforms such as Linux on\n" +"Raspberry Pi.\n" +" * There is work in progress on an `async` version of `embedded-hal`, but it " +"isn't stable yet." +msgstr "" +" * 라스베리 파이에서 돌아가는 리눅스 같은 플랫폼 뿐만 아니라 다른 여러 마이크로컨트롤러" +"에 대한\n" +"구현이 있습니다.\n" +" * `embedded-hal`의 'async' 버전에 관한 작업이 진행 중이지만 아직 안정적이지 " +"않습니다." + +#: src/bare-metal/microcontrollers/probe-rs.md:1 +msgid "# `probe-rs`, `cargo-embed`" +msgstr "# `probe-rs`, `cargo-embed`" + +#: src/bare-metal/microcontrollers/probe-rs.md:3 +msgid "" +"[probe-rs](https://probe.rs/) is a handy toolset for embedded debugging, " +"like OpenOCD but better\n" +"integrated." +msgstr "" +"[probe-rs](https://probe.rs/)는 임베디드 시스템을 위한 도구 모임입니다. OpenOCD와 비슷하지만, " +"Rust에 더 잘 통합되어 있습니다." + +#: src/bare-metal/microcontrollers/probe-rs.md:6 +msgid "" +"* SWD and JTAG via CMSIS-DAP, ST-" +"Link and J-Link probes\n" +"* GDB stub and Microsoft DAP " +"server\n" +"* Cargo integration" +msgstr "" +"* SWD 및 JTAG(CMSIS-DAP, ST-Link, J-" +"Link 프로브를 통함)\n" +"* GDB 스텁 및 Microsoft DAP 서" +"버\n" +"* Cargo에 통합됨" + +#: src/bare-metal/microcontrollers/probe-rs.md:10 +msgid "" +"`cargo-embed` is a cargo subcommand to build and flash binaries, log\n" +"RTT output and connect GDB. It's " +"configured by an\n" +"`Embed.toml` file in your project directory." +msgstr "" +"`cargo-embed`는 cargo의 서브 커맨트로써, 바이너리를 빌드하고 플래시하며, RTT 출력을 기록하고,\n" +"GDB를 연결해 줍니다. 이 명령어의 세부 동작은 프로젝트 디렉터리의\n" +"`Embed.toml` 파일을 통해 설정합니다." + +#: src/bare-metal/microcontrollers/probe-rs.md:16 +msgid "" +"* [CMSIS-DAP](https://arm-software.github.io/CMSIS_5/DAP/html/index.html) is " +"an Arm standard\n" +" protocol over USB for an in-circuit debugger to access the CoreSight Debug " +"Access Port of various\n" +" Arm Cortex processors. It's what the on-board debugger on the BBC micro:" +"bit uses.\n" +"* ST-Link is a range of in-circuit debuggers from ST Microelectronics, J-" +"Link is a range from\n" +" SEGGER.\n" +"* The Debug Access Port is usually either a 5-pin JTAG interface or 2-pin " +"Serial Wire Debug.\n" +"* probe-rs is a library which you can integrate into your own tools if you " +"want to.\n" +"* The [Microsoft Debug Adapter Protocol](https://microsoft.github.io/debug-" +"adapter-protocol/) lets\n" +" VSCode and other IDEs debug code running on any supported " +"microcontroller.\n" +"* cargo-embed is a binary built using the probe-rs library.\n" +"* RTT (Real Time Transfers) is a mechanism to transfer data between the " +"debug host and the target\n" +" through a number of ringbuffers." +msgstr "" +"* [CMSIS-DAP](https://arm-software.github.io/CMSIS_5/DAP/html/index.html)는 " +"Arm에서 정의한 프로토콜로, USB를 통해 Arm Cortex 프로세서의 CoreSight 디버그 액세스 포트에 " +"접근할 수 있게 해 줍니다. BBC micro:bit에 있는 온보드 디버거도 이 프로토콜을 지원합니다.\n" +"* ST-Link는 ST Microelectronics사에서 만든 in-circuit 디버거들이며, J-Link는\n" +" SEGGER사의 in-circuit 디버거들입니다.\n" +"* 디버그 액세스 포트의 물리적인 구성은 일반적으로 5핀 JTAG 인터페이스 혹은, 2핀 Serial Wire Debug " +"인터페이스 입니다.\n" +"* probe-rs는 라이브러리로 구현되어 있어서, 다른 도구들에 통합되기가 쉽습니다.\n" +"* [Microsoft 디버그 어댑터 프로토콜](https://microsoft.github.io/debug-" +"adapter-protocol/)을 사용하면 VSCode나 다른 IDE 상에서 마이크로컨트롤러에서 수행중인 코드를 디버깅 할 수 있습니다.\n" +"* cargo-embed는 probe-rs 라이브러리를 사용하여 빌드된 바이너리입니다.\n" +"* RTT(Real Time Transfers)는 여러 링 버퍼를 통해 디버그 호스트와 타겟 간에\n" +" 데이터를 전송하는 메커니즘입니다." + +#: src/bare-metal/microcontrollers/debugging.md:3 +msgid "Embed.toml:" +msgstr "Embed.toml:" + +#: src/bare-metal/microcontrollers/debugging.md:5 +msgid "" +"```toml\n" +"[default.general]\n" +"chip = \"nrf52833_xxAA\"\n" +"\n" +"[debug.gdb]\n" +"enabled = true\n" +"```" +msgstr "" +"```toml\n" +"[default.general]\n" +"chip = \"nrf52833_xxAA\"\n" +"\n" +"[debug.gdb]\n" +"enabled = true\n" +"```" + +#: src/bare-metal/microcontrollers/debugging.md:13 +msgid "In one terminal under `src/bare-metal/microcontrollers/examples/`:" +msgstr "`src/bare-metal/microcontrollers/examples/` 아래 하나의 터미널에서:" + +#: src/bare-metal/microcontrollers/debugging.md:15 +msgid "" +"```sh\n" +"cargo embed --bin board_support debug\n" +"```" +msgstr "" +"```sh\n" +"cargo embed --bin board_support debug\n" +"```" + +#: src/bare-metal/microcontrollers/debugging.md:21 +msgid "" +"```sh\n" +"gdb-multiarch target/thumbv7em-none-eabihf/debug/board_support --eval-" +"command=\"target remote :1337\"\n" +"```" +msgstr "" +"```sh\n" +"gdb-multiarch target/thumbv7em-none-eabihf/debug/board_support --eval-" +"command=\"target remote :1337\"\n" +"```" + +#: src/bare-metal/microcontrollers/debugging.md:27 +msgid "In GDB, try running:" +msgstr "GDB에서 다음을 실행해 보세요." + +#: src/bare-metal/microcontrollers/debugging.md:29 +msgid "" +"```gdb\n" +"b src/bin/board_support.rs:29\n" +"b src/bin/board_support.rs:30\n" +"b src/bin/board_support.rs:32\n" +"c\n" +"c\n" +"c\n" +"```" +msgstr "" +"```gdb\n" +"b src/bin/board_support.rs:29\n" +"b src/bin/board_support.rs:30\n" +"b src/bin/board_support.rs:32\n" +"c\n" +"c\n" +"c\n" +"```" + +#: src/bare-metal/microcontrollers/other-projects.md:1 +#: src/bare-metal/aps/other-projects.md:1 +msgid "# Other projects" +msgstr "# 다른 프로젝트" + +#: src/bare-metal/microcontrollers/other-projects.md:3 +msgid "" +" * [RTIC](https://rtic.rs/)\n" +" * \"Real-Time Interrupt-driven Concurrency\"\n" +" * Shared resource management, message passing, task scheduling, timer " +"queue\n" +" * [Embassy](https://embassy.dev/)\n" +" * `async` executors with priorities, timers, networking, USB\n" +" * [TockOS](https://www.tockos.org/documentation/getting-started)\n" +" * Security-focused RTOS with preemptive scheduling and Memory Protection " +"Unit support\n" +" * [Hubris](https://hubris.oxide.computer/)\n" +" * Microkernel RTOS from Oxide Computer Company with memory protection, " +"unprivileged drivers, IPC\n" +" * [Bindings for FreeRTOS](https://github.com/lobaro/FreeRTOS-rust)\n" +" * Some platforms have `std` implementations, e.g.\n" +" [esp-idf](https://esp-rs.github.io/book/overview/using-the-standard-" +"library.html)." +msgstr "" +" * [RTIC](https://rtic.rs/)\n" +" * \"실시간 인터럽트 기반 동시 실행(Real-Time Interrupt-driven Concurrency)\"\n" +" * 공유 리소스 관리, 메시지 전달, 태스크 스케줄링, 타이머 대기열 지원\n" +" * [Embassy](https://embassy.dev/)\n" +" * 우선순위, 타이머, 네트워킹, USB가 포함된 `async` 실행자\n" +" * [TockOS](https://www.tockos.org/documentation/getting-started)\n" +" * 선점형 스케줄링 및 MMU를 지원하는, 보안에 중점을 둔 실시간 운영체제\n" +" * [Hubris](https://hubris.oxide.computer/)\n" +" * Oxide Computer Company에서 만든 마이크로커널 기반 실시간 운영체제로, 메모리 보호, 권한이 없이 수행되는 드라이버 등을 지원함.\n" +" * [FreeRTOS용 바인딩](https://github.com/lobaro/FreeRTOS-rust)\n" +" * `std`가 구현된 플랫폼도 있습니다(예: [esp-idf](https://esp-rs.github.io/book/" +"overview/using-the-standard-library.html))." + +#: src/bare-metal/microcontrollers/other-projects.md:18 +msgid "" +" * RTIC can be considered either an RTOS or a concurrency framework.\n" +" * It doesn't include any HALs.\n" +" * It uses the Cortex-M NVIC (Nested Virtual Interrupt Controller) for " +"scheduling rather than a\n" +" proper kernel.\n" +" * Cortex-M only.\n" +" * Google uses TockOS on the Haven microcontroller for Titan security keys.\n" +" * FreeRTOS is mostly written in C, but there are Rust bindings for writing " +"applications." +msgstr "" +" * RTIC는 실시간 운영체제로 볼 수도 있고, 동시성 지원을 위한 프레임워크로 볼 수도 있습니다.\n" +" * HAL을 포함하지는 않습니다.\n" +" * 스케줄링은 커널이 아니라 Cortex-M NVIC(Nested Virtual Interrupt Controller)로 구현이 됩니다.\n" +" * Cortex-M 전용입니다.\n" +" * Google에서는 Titan 보안 키에 사용되는 Haven 마이크로컨트롤러에서 TockOS를 사용합니" +"다.\n" +" * FreeRTOS는 대부분 C로 작성되지만, 애플리케이션을 Rust로 작성할 수 있도록 해 주는 Rust 바인딩이 " +"제공됩니다." + +#: src/bare-metal/aps.md:1 +msgid "# Application processors" +msgstr "# 애플리케이션 프로세서" + +#: src/bare-metal/aps.md:3 +msgid "" +"So far we've talked about microcontrollers, such as the Arm Cortex-M series. " +"Now let's try writing\n" +"something for Cortex-A. For simplicity we'll just work with QEMU's aarch64\n" +"['virt'](https://qemu-project.gitlab.io/qemu/system/arm/virt.html) board." +msgstr "" +"지금까지 Arm Cortex-M 시리즈와 같은 마이크로컨트롤러에 관해 알아봤습니다. 이" +"제\n" +"애플리케이션 프로세서인 Cortex-A를 위한 코드를 작성해 보겠습니다. 편의상 QEMU의 aarch64\n" +"['virt'](https://qemu-project.gitlab.io/qemu/system/arm/virt.html) 보드를 사" +"용합니다." + +#: src/bare-metal/aps.md:9 +msgid "" +"* Broadly speaking, microcontrollers don't have an MMU or multiple levels of " +"privilege (exception\n" +" levels on Arm CPUs, rings on x86), while application processors do.\n" +"* QEMU supports emulating various different machines or board models for " +"each architecture. The\n" +" 'virt' board doesn't correspond to any particular real hardware, but is " +"designed purely for\n" +" virtual machines." +msgstr "" +"* 일반적으로 마이크로컨트롤러에는 MMU 또는 다중 레벨 권한(Arm CPU에서는 " +"익셉션 레벨(exception level), x86에서는 링(ring))이 없습니다.\n" +"애플리케이션 프로세서는 이들을 가지고 있습니다.\n" +"* QEMU는 아키텍처별로 다양한 머신 또는 보드 모델을 에뮬레이션할 수 있습니" +"다. 'virt' 보드는\n" +"특정 실제 하드웨어를 에뮬레이션 하지 않으며, 가상 머신용으로만\n" +"설계되었습니다." + +#: src/bare-metal/aps/inline-assembly.md:1 +msgid "# Inline assembly" +msgstr "# 인라인 어셈블리" + +#: src/bare-metal/aps/inline-assembly.md:3 +msgid "" +"Sometimes we need to use assembly to do things that aren't possible with " +"Rust code. For example,\n" +"to make an HVC to tell the firmware " +"to power off the system:" +msgstr "" +"가끔 Rust 코드로는 구현이 불가능한 작업들이 있으며, 이 경우 어셈블리를 사용해야 합니다. 예" +"를 들어\n" +" 펌웨어를 향해서 시스템 전원을 끄라고 HVC를 호출하는 방법은 다음과 같습니다." + +#: src/bare-metal/aps/inline-assembly.md:6 +msgid "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"use core::arch::asm;\n" +"use core::panic::PanicInfo;\n" +"\n" +"mod exceptions;\n" +"\n" +"const PSCI_SYSTEM_OFF: u32 = 0x84000008;\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn main(_x0: u64, _x1: u64, _x2: u64, _x3: u64) {\n" +" // Safe because this only uses the declared registers and doesn't do\n" +" // anything with memory.\n" +" unsafe {\n" +" asm!(\"hvc #0\",\n" +" inout(\"w0\") PSCI_SYSTEM_OFF => _,\n" +" inout(\"w1\") 0 => _,\n" +" inout(\"w2\") 0 => _,\n" +" inout(\"w3\") 0 => _,\n" +" inout(\"w4\") 0 => _,\n" +" inout(\"w5\") 0 => _,\n" +" inout(\"w6\") 0 => _,\n" +" inout(\"w7\") 0 => _,\n" +" options(nomem, nostack)\n" +" );\n" +" }\n" +"\n" +" loop {}\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"use core::arch::asm;\n" +"use core::panic::PanicInfo;\n" +"\n" +"mod exceptions;\n" +"\n" +"const PSCI_SYSTEM_OFF: u32 = 0x84000008;\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn main(_x0: u64, _x1: u64, _x2: u64, _x3: u64) {\n" +" // Safe because this only uses the declared registers and doesn't do\n" +" // anything with memory.\n" +" unsafe {\n" +" asm!(\"hvc #0\",\n" +" inout(\"w0\") PSCI_SYSTEM_OFF => _,\n" +" inout(\"w1\") 0 => _,\n" +" inout(\"w2\") 0 => _,\n" +" inout(\"w3\") 0 => _,\n" +" inout(\"w4\") 0 => _,\n" +" inout(\"w5\") 0 => _,\n" +" inout(\"w6\") 0 => _,\n" +" inout(\"w7\") 0 => _,\n" +" options(nomem, nostack)\n" +" );\n" +" }\n" +"\n" +" loop {}\n" +"}\n" +"```" + +#: src/bare-metal/aps/inline-assembly.md:39 +msgid "" +"(If you actually want to do this, use the [`smccc`][1] crate which has " +"wrappers for all these functions.)" +msgstr "" +"실제로 이를 실행하려면 이러한 모든 함수를 위한 래퍼가 포함된 [`smccc`][1] 크" +"레이트를 사용하세요." + +#: src/bare-metal/aps/inline-assembly.md:43 +msgid "" +"* PSCI is the Arm Power State Coordination Interface, a standard set of " +"functions to manage system\n" +" and CPU power states, among other things. It is implemented by EL3 " +"firmware and hypervisors on\n" +" many systems.\n" +"* The `0 => _` syntax means initialise the register to 0 before running the " +"inline assembly code,\n" +" and ignore its contents afterwards. We need to use `inout` rather than " +"`in` because the call could\n" +" potentially clobber the contents of the registers.\n" +"* This `main` function needs to be `#[no_mangle]` and `extern \"C\"` because " +"it is called from our\n" +" entry point in `entry.S`.\n" +"* `_x0`–`_x3` are the values of registers `x0`–`x3`, which are " +"conventionally used by the bootloader\n" +" to pass things like a pointer to the device tree. According to the " +"standard aarch64 calling\n" +" convention (which is what `extern \"C\"` specifies to use), registers `x0`–" +"`x7` are used for the\n" +" first 8 arguments passed to a function, so `entry.S` doesn't need to do " +"anything special except\n" +" make sure it doesn't change these registers.\n" +"* Run the example in QEMU with `make qemu_psci` under `src/bare-metal/aps/" +"examples`." +msgstr "" +"* PSCI (Power State Coordination Interface)는 시스템 및 CPU 전원 상태를 관리하는 Arm의 표준 인터페이스입니다.\n" +" 이 인터페이스는 EL3 펌웨어와 하이" +"퍼바이저에 의해\n" +"구현됩니다.\n" +"* `0 => _` 문법은 인라인 어셈블리 코드를 실행하기 전에 레지스터를 0으로 초기" +"화하고\n" +" 그 후에는 그 레지스터의 값을 무시함을 의미합니다. 호출 시 레지스터의 값이\n" +" 덮어 써질 수 있으므로\n" +" `in` 대신 `inout`을 사용해야 합니다.\n" +"* 이 `main` 함수는 `#[no_mangle]` 및 `extern \"C\"`여야 합니다. 왜냐하면 이 함수는 Rust 코드가 아닌, " +"어셈블러로 작성된 `entry.S`에서 호출되기 때문입니다.\n" +"* `_x0`–`_x3`는 `x0`에서 `x3` 레지스터들의 값입니다. 이 레지스터들은 일반적으로 부트로더에서 " +" 디바이스 트리에 대한 포인터 등을 전달할 때 사용됩니다." +" 표준 aarch64 호출 규약(`extern " +"\"C\"`에서 사용하도록 지정)에 따라\n" +" 레지스터 `x0`에서 `x7`이 함수에 전달된 처음 8개 인수에 사용되므로\n" +" `entry.S`는 이러한 레지스터를 변경하지 않는지 확인하는 것 외에는\n" +" 특별히 할 작업이 없습니다.\n" +"* `src/bare-metal/aps/examples`에서 `make qemu_psci`를 사용하여 QEMU에서 예시" +"를 실행합니다." + +#: src/bare-metal/aps/mmio.md:1 +msgid "# Volatile memory access for MMIO" +msgstr "# MMIO를 위한 휘발성(volatile) 메모리 액세스" + +#: src/bare-metal/aps/mmio.md:3 +msgid "" +" * Use `pointer::read_volatile` and `pointer::write_volatile`.\n" +" * Never hold a reference.\n" +" * `addr_of!` lets you get fields of structs without creating an " +"intermediate reference." +msgstr "" +" * `pointer::read_volatile` 및 `pointer::write_volatile`을 사용하세요.\n" +" * 참조를 유지하지 마세요.\n" +" * `addr_of!`를 사용하면 임시 용도의 참조를 만들지 않고도 구조체 필드를 가져올 수 있" +"습니다." + +#: src/bare-metal/aps/mmio.md:9 +msgid "" +" * Volatile access: read or write operations may have side-effects, so " +"prevent the compiler or\n" +" hardware from reordering, duplicating or eliding them.\n" +" * Usually if you write and then read, e.g. via a mutable reference, the " +"compiler may assume that\n" +" the value read is the same as the value just written, and not bother " +"actually reading memory.\n" +" * Some existing crates for volatile access to hardware do hold references, " +"but this is unsound.\n" +" Whenever a reference exist, the compiler may choose to dereference it.\n" +" * Use the `addr_of!` macro to get struct field pointers from a pointer to " +"the struct." +msgstr "" +" * 휘발성(volatile) 액세스: 읽기 또는 쓰기 작업이 부수 효과(side effect)를 동반할 수 있기 때문에 컴파일러" +"나 하드웨어가\n" +" 임의로 이를 읽기 쓰기 작업의 순서를 바꾸거나, 중복해서 수행하거나 또는 제거하지 못하게 합니다.\n" +" * 일반적으로 쓰고 난 후 읽으면(예: 변경 가능한 참조를 통해) 컴파일러는\n" +" 읽은 값이 방금 쓴 값과 동일하다고 가정하고 실제로 메모리를 읽지 않을 수 " +"있습니다.\n" +" * 하드웨어에 대한 휘발성 액세스를 위한 일부 기존 크레이트는 참조를 유지하지" +"만 이는 올바른 것이 아닙니다.\n" +" 참조가 있을 때마다 컴파일러는 이를 역참조하도록 선택할 수 있습니다.\n" +" * `addr_of!` 매크로를 사용하여 구조체 포인터에서 구조체 필드 포인터를 가져옵" +"니다." + +#: src/bare-metal/aps/uart.md:1 +msgid "# Let's write a UART driver" +msgstr "# UART 드라이버 작성" + +#: src/bare-metal/aps/uart.md:3 +msgid "" +"The QEMU 'virt' machine has a [PL011][1] UART, so let's write a driver for " +"that." +msgstr "" +"QEMU의 'virt' 보드에는 [PL011][1] UART가 있으므로 이를 위한 드라이버를 작성해 " +"보겠습니다." + +#: src/bare-metal/aps/uart.md:5 +msgid "" +"```rust,editable\n" +"const FLAG_REGISTER_OFFSET: usize = 0x18;\n" +"const FR_BUSY: u8 = 1 << 3;\n" +"const FR_TXFF: u8 = 1 << 5;\n" +"\n" +"/// Minimal driver for a PL011 UART.\n" +"#[derive(Debug)]\n" +"pub struct Uart {\n" +" base_address: *mut u8,\n" +"}\n" +"\n" +"impl Uart {\n" +" /// Constructs a new instance of the UART driver for a PL011 device at " +"the\n" +" /// given base address.\n" +" ///\n" +" /// # Safety\n" +" ///\n" +" /// The given base address must point to the 8 MMIO control registers of " +"a\n" +" /// PL011 device, which must be mapped into the address space of the " +"process\n" +" /// as device memory and not have any other aliases.\n" +" pub unsafe fn new(base_address: *mut u8) -> Self {\n" +" Self { base_address }\n" +" }\n" +"\n" +" /// Writes a single byte to the UART.\n" +" pub fn write_byte(&self, byte: u8) {\n" +" // Wait until there is room in the TX buffer.\n" +" while self.read_flag_register() & FR_TXFF != 0 {}\n" +"\n" +" // Safe because we know that the base address points to the control\n" +" // registers of a PL011 device which is appropriately mapped.\n" +" unsafe {\n" +" // Write to the TX buffer.\n" +" self.base_address.write_volatile(byte);\n" +" }\n" +"\n" +" // Wait until the UART is no longer busy.\n" +" while self.read_flag_register() & FR_BUSY != 0 {}\n" +" }\n" +"\n" +" fn read_flag_register(&self) -> u8 {\n" +" // Safe because we know that the base address points to the control\n" +" // registers of a PL011 device which is appropriately mapped.\n" +" unsafe { self.base_address.add(FLAG_REGISTER_OFFSET)." +"read_volatile() }\n" +" }\n" +"}\n" +"```" +msgstr "" +"```rust,editable\n" +"const FLAG_REGISTER_OFFSET: usize = 0x18;\n" +"const FR_BUSY: u8 = 1 << 3;\n" +"const FR_TXFF: u8 = 1 << 5;\n" +"\n" +"/// PL011 UART용 최소 드라이버입니다.\n" +"#[derive(Debug)]\n" +"pub struct Uart {\n" +" base_address: *mut u8,\n" +"}\n" +"\n" +"impl Uart {\n" +" /// Constructs a new instance of the UART driver for a PL011 device at " +"the\n" +" /// given base address.\n" +" ///\n" +" /// # Safety\n" +" ///\n" +" /// The given base address must point to the 8 MMIO control registers of " +"a\n" +" /// PL011 device, which must be mapped into the address space of the " +"process\n" +" /// as device memory and not have any other aliases.\n" +" pub unsafe fn new(base_address: *mut u8) -> Self {\n" +" Self { base_address }\n" +" }\n" +"\n" +" /// UART에 한 바이트를 씁니다.\n" +" pub fn write_byte(&self, byte: u8) {\n" +" // Wait until there is room in the TX buffer.\n" +" while self.read_flag_register() & FR_TXFF != 0 {}\n" +"\n" +" // `base_address`가 PL011의 컨트롤 레지스터가 매핑된 주소를 가리키고\n" +" // 있으므로 안전합니다.\n" +" unsafe {\n" +" // Write to the TX buffer.\n" +" self.base_address.write_volatile(byte);\n" +" }\n" +"\n" +" // UART가 더 이상 사용 중이 아닐 때까지 기다립니다.\n" +" while self.read_flag_register() & FR_BUSY != 0 {}\n" +" }\n" +"\n" +" fn read_flag_register(&self) -> u8 {\n" +" // Safe because we know that the base address points to the control\n" +" // registers of a PL011 device which is appropriately mapped.\n" +" unsafe { self.base_address.add(FLAG_REGISTER_OFFSET)." +"read_volatile() }\n" +" }\n" +"}\n" +"```" + +#: src/bare-metal/aps/uart.md:55 +msgid "" +"* Note that `Uart::new` is unsafe while the other methods are safe. This is " +"because as long as the\n" +" caller of `Uart::new` guarantees that its safety requirements are met (i." +"e. that there is only\n" +" ever one instance of the driver for a given UART, and nothing else " +"aliasing its address space),\n" +" then it is always safe to call `write_byte` later because we can assume " +"the necessary\n" +" preconditions.\n" +"* We could have done it the other way around (making `new` safe but " +"`write_byte` unsafe), but that\n" +" would be much less convenient to use as every place that calls " +"`write_byte` would need to reason\n" +" about the safety\n" +"* This is a common pattern for writing safe wrappers of unsafe code: moving " +"the burden of proof for\n" +" soundness from a large number of places to a smaller number of places." +msgstr "" +"* `Uart::new`는 안전하지 않지만(usafe), 그 외 다른 메서드들은 안전한(safe) 점에 주목하세요." +"다른 메서드들이 안전할 수 있는 이유는, `Uart::new`의 안전 요구사항(즉, 지정된 UART의 드라이버 인스턴" +"스가 하나만 있으며\n" +" 주소 공간에 별칭을 지정하는 다른 항목이 없음)\n" +"이 만족되기만 하면 `write_byte`와 같은 함수를 안전하게 호출하는데 있어서 필요한 모든 전제조건이 만족되기" +" 때문입니다.\n" +"* 반대 방법으로도 실행할 수 있지만(`new`를 안전하게 만들고 `write_byte`를 안" +"전하지 않게 만듦)\n" +" 이는 `write_byte`를 호출하는 모든 위치에서 안전성에 관해 추론해야 하므로\n" +" 사용 편의성이 훨씬 떨어집니다.\n" +"* 이는 안전하지 않은 코드의 안전한 래퍼를 작성하는 일반적인 패턴입니다. 안전" +"에 관한\n" +" 증명 부담을 여러 많은 위치에서 소수의 위치로 옮기는 것입니다." + +#: src/bare-metal/aps/better-uart.md:1 +msgid "# A better UART driver" +msgstr "# 더 나은 UART 드라이버" + +#: src/bare-metal/aps/better-uart.md:3 +msgid "" +"The PL011 actually has [a bunch more registers][1], and adding offsets to " +"construct pointers to access\n" +"them is error-prone and hard to read. Plus, some of them are bit fields " +"which would be nice to\n" +"access in a structured way." +msgstr "" +"PL011에는 실제로 [훨씬 더 많은 레지스터][1]가 있으며, 이에 액세스할 포인터를 " +"구성하기 위해 오프셋을\n" +"추가하면 오류가 발생하기 쉽고 읽기 어렵습니다. 또한 그중 일부는 구조화된 방식" +"으로 액세스할 수 있는\n" +"비트 필드입니다." + +#: src/bare-metal/aps/better-uart.md:7 +msgid "" +"| Offset | Register name | Width |\n" +"| ------ | ------------- | ----- |\n" +"| 0x00 | DR | 12 |\n" +"| 0x04 | RSR | 4 |\n" +"| 0x18 | FR | 9 |\n" +"| 0x20 | ILPR | 8 |\n" +"| 0x24 | IBRD | 16 |\n" +"| 0x28 | FBRD | 6 |\n" +"| 0x2c | LCR_H | 8 |\n" +"| 0x30 | CR | 16 |\n" +"| 0x34 | IFLS | 6 |\n" +"| 0x38 | IMSC | 11 |\n" +"| 0x3c | RIS | 11 |\n" +"| 0x40 | MIS | 11 |\n" +"| 0x44 | ICR | 11 |\n" +"| 0x48 | DMACR | 3 |" +msgstr "" +"| 오프셋 | 레지스터 이름 | 너비 |\n" +"| ------ | ------------- | ----- |\n" +"| 0x00 | DR | 12 |\n" +"| 0x04 | RSR | 4 |\n" +"| 0x18 | FR | 9 |\n" +"| 0x20 | ILPR | 8 |\n" +"| 0x24 | IBRD | 16 |\n" +"| 0x28 | FBRD | 6 |\n" +"| 0x2c | LCR_H | 8 |\n" +"| 0x30 | CR | 16 |\n" +"| 0x34 | IFLS | 6 |\n" +"| 0x38 | IMSC | 11 |\n" +"| 0x3c | RIS | 11 |\n" +"| 0x40 | MIS | 11 |\n" +"| 0x44 | ICR | 11 |\n" +"| 0x48 | DMACR | 3 |" + +#: src/bare-metal/aps/better-uart.md:26 +msgid "- There are also some ID registers which have been omitted for brevity." +msgstr "- 간결성을 위해 일부 ID 레지스터는 생략되었습니다." + +#: src/bare-metal/aps/logging.md:3 +msgid "" +"It would be nice to be able to use the logging macros from the [`log`][1] " +"crate. We can do this by\n" +"implementing the `Log` trait." +msgstr "" +"[`log`][1] 크레이트의 로깅 매크로를 사용할 수 있으면 좋습니다. 이는 `Log` 트" +"레잇을\n" +"구현하면 됩니다." + +#: src/bare-metal/aps/logging.md:6 +msgid "" +"```rust,editable,compile_fail\n" +"use crate::pl011::Uart;\n" +"use core::fmt::Write;\n" +"use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};\n" +"use spin::mutex::SpinMutex;\n" +"\n" +"static LOGGER: Logger = Logger {\n" +" uart: SpinMutex::new(None),\n" +"};\n" +"\n" +"struct Logger {\n" +" uart: SpinMutex>,\n" +"}\n" +"\n" +"impl Log for Logger {\n" +" fn enabled(&self, _metadata: &Metadata) -> bool {\n" +" true\n" +" }\n" +"\n" +" fn log(&self, record: &Record) {\n" +" writeln!(\n" +" self.uart.lock().as_mut().unwrap(),\n" +" \"[{}] {}\",\n" +" record.level(),\n" +" record.args()\n" +" )\n" +" .unwrap();\n" +" }\n" +"\n" +" fn flush(&self) {}\n" +"}\n" +"\n" +"/// Initialises UART logger.\n" +"pub fn init(uart: Uart, max_level: LevelFilter) -> Result<(), " +"SetLoggerError> {\n" +" LOGGER.uart.lock().replace(uart);\n" +"\n" +" log::set_logger(&LOGGER)?;\n" +" log::set_max_level(max_level);\n" +" Ok(())\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"use crate::pl011::Uart;\n" +"use core::fmt::Write;\n" +"use log::{LevelFilter, Log, Metadata, Record, SetLoggerError};\n" +"use spin::mutex::SpinMutex;\n" +"\n" +"static LOGGER: Logger = Logger {\n" +" uart: SpinMutex::new(None),\n" +"};\n" +"\n" +"struct Logger {\n" +" uart: SpinMutex>,\n" +"}\n" +"\n" +"impl Log for Logger {\n" +" fn enabled(&self, _metadata: &Metadata) -> bool {\n" +" true\n" +" }\n" +"\n" +" fn log(&self, record: &Record) {\n" +" writeln!(\n" +" self.uart.lock().as_mut().unwrap(),\n" +" \"[{}] {}\",\n" +" record.level(),\n" +" record.args()\n" +" )\n" +" .unwrap();\n" +" }\n" +"\n" +" fn flush(&self) {}\n" +"}\n" +"\n" +"/// UART 로거를 초기화합니다.\n" +"pub fn init(uart: Uart, max_level: LevelFilter) -> Result<(), " +"SetLoggerError> {\n" +" LOGGER.uart.lock().replace(uart);\n" +"\n" +" log::set_logger(&LOGGER)?;\n" +" log::set_max_level(max_level);\n" +" Ok(())\n" +"}\n" +"```" + +#: src/bare-metal/aps/logging.md:50 +msgid "" +"* The unwrap in `log` is safe because we initialise `LOGGER` before calling " +"`set_logger`." +msgstr "" +"* `log`함수 안에서 `unwrap`하는 것은 괜찮습니다.. 왜냐하면 `set_logger`를 호출하기 전에 `LOGGER`를 초" +"기화하기 때문입니다." + +#: src/bare-metal/aps/other-projects.md:3 +msgid "" +" * [oreboot](https://github.com/oreboot/oreboot)\n" +" * \"coreboot without the C\"\n" +" * Supports x86, aarch64 and RISC-V.\n" +" * Relies on LinuxBoot rather than having many drivers itself.\n" +" * [Rust RaspberryPi OS tutorial](https://github.com/rust-embedded/rust-" +"raspberrypi-OS-tutorials)\n" +" * Initialisation, UART driver, simple bootloader, JTAG, exception levels, " +"exception handling, page tables\n" +" * Not all very well written, so beware.\n" +" * [`cargo-call-stack`](https://crates.io/crates/cargo-call-stack)\n" +" * Static analysis to determine maximum stack usage." +msgstr "" +" * [oreboot](https://github.com/oreboot/oreboot)\n" +" * \"C가 없는 coreboot\"\n" +" * x86, aarch64, RISC-V를 지원합니다.\n" +" * 자체적으로 여러 드라이버를 보유하는 대신 LinuxBoot에 의존합니다.\n" +" * [Rust RaspberryPi OS tutorial](https://github.com/rust-embedded/rust-" +"raspberrypi-OS-tutorials)\n" +" * 초기화, UART 드라이버, 간단한 부트로더, JTAG, 예외 수준, 예외 처리, 페이" +"지 테이블\n" +" * 잘 작성되지 않은 것도 있으므로 주의하세요.\n" +" * [`cargo-call-stack`](https://crates.io/crates/cargo-call-stack)\n" +" * 최대 스택 사용량을 결정하는 정적 분석" + +#: src/bare-metal/useful-crates.md:1 +msgid "# Useful crates" +msgstr "# 유용한 크레이트" + +#: src/bare-metal/useful-crates.md:3 +msgid "" +"We'll go over a few crates which solve some common problems in bare-metal " +"programming." +msgstr "" +"bare-metal 프로그래밍의 몇 가지 일반적인 문제를 해결하는 크레이트를 살펴봅니" +"다." + +#: src/bare-metal/useful-crates/zerocopy.md:1 +msgid "# `zerocopy`" +msgstr "# `zerocopy`" + +#: src/bare-metal/useful-crates/zerocopy.md:3 +msgid "" +"The [`zerocopy`][1] crate (from Fuchsia) provides traits and macros for " +"safely converting between\n" +"byte sequences and other types." +msgstr "" +"Fuchsia팀이 만든 [`zerocopy`][1] 크레이트는 바이트 시퀀스를 다른 타입으로 안전하게 " +"변환하기 위한\n" +"트레잇 및 매크로를 제공합니다." + +#: src/bare-metal/useful-crates/zerocopy.md:6 +msgid "" +"```rust,editable,compile_fail\n" +"use zerocopy::AsBytes;\n" +"\n" +"#[repr(u32)]\n" +"#[derive(AsBytes, Debug, Default)]\n" +"enum RequestType {\n" +" #[default]\n" +" In = 0,\n" +" Out = 1,\n" +" Flush = 4,\n" +"}\n" +"\n" +"#[repr(C)]\n" +"#[derive(AsBytes, Debug, Default)]\n" +"struct VirtioBlockRequest {\n" +" request_type: RequestType,\n" +" reserved: u32,\n" +" sector: u64,\n" +"}\n" +"\n" +"fn main() {\n" +" let request = VirtioBlockRequest {\n" +" request_type: RequestType::Flush,\n" +" sector: 42,\n" +" ..Default::default()\n" +" };\n" +"\n" +" assert_eq!(\n" +" request.as_bytes(),\n" +" &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]\n" +" );\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"use zerocopy::AsBytes;\n" +"\n" +"#[repr(u32)]\n" +"#[derive(AsBytes, Debug, Default)]\n" +"enum RequestType {\n" +" #[default]\n" +" In = 0,\n" +" Out = 1,\n" +" Flush = 4,\n" +"}\n" +"\n" +"#[repr(C)]\n" +"#[derive(AsBytes, Debug, Default)]\n" +"struct VirtioBlockRequest {\n" +" request_type: RequestType,\n" +" reserved: u32,\n" +" sector: u64,\n" +"}\n" +"\n" +"fn main() {\n" +" let request = VirtioBlockRequest {\n" +" request_type: RequestType::Flush,\n" +" sector: 42,\n" +" ..Default::default()\n" +" };\n" +"\n" +" assert_eq!(\n" +" request.as_bytes(),\n" +" &[4, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0]\n" +" );\n" +"}\n" +"```" + +#: src/bare-metal/useful-crates/zerocopy.md:40 +msgid "" +"This is not suitable for MMIO (as it doesn't use volatile reads and writes), " +"but can be useful for\n" +"working with structures shared with hardware e.g. by DMA, or sent over some " +"external interface." +msgstr "" +"이 크레이트는 휘발성(volatile) 읽기 및 쓰기를 사용하지 않으므로 MMIO에 적합하지 않지만, 하드웨어" +"와 공유되거나(예: DMA에서)\n" +"외장 인터페이스를 통해 전송되는 구조체를 다루는 데에는 유용할 수 있습니다." + +#: src/bare-metal/useful-crates/zerocopy.md:45 +msgid "" +"* `FromBytes` can be implemented for types for which any byte pattern is " +"valid, and so can safely be\n" +" converted from an untrusted sequence of bytes.\n" +"* Attempting to derive `FromBytes` for these types would fail, because " +"`RequestType` doesn't use all\n" +" possible u32 values as discriminants, so not all byte patterns are valid.\n" +"* `zerocopy::byteorder` has types for byte-order aware numeric primitives.\n" +"* Run the example with `cargo run` under `src/bare-metal/useful-crates/" +"zerocopy-example/`. (It won't\n" +" run in the Playground because of the crate dependency.)" +msgstr "" +"* 어떤 타입이 가능한 모든 바이트 패턴들에 대해 올바른 값을 가질 때에만 , 그 타입이 `FromBytes`를 구현할 수 있습니다.\n" +" 그렇게 해서 신뢰할 수 없는 바이트 시퀀스를 안전하게 해당 타입으로 변환할 수 있습니다.\n" +"* 위 코드에서 정의한 타입에 대해 `FromBytes`를 구현하려고 하면 에러가 발생합니다. `RequestType`은 가" +"능한 모든 u32 값을\n" +" 식별자로 받아들이지 않기 때문입니다. 즉 모든 바이트 패턴이 유효한 `RequestType`값은 아" +"닙니다.\n" +"* `zerocopy::byteorder`에는 바이트 오더에 따른 서로 다른 표현 방식을 지원하는 숫자 타입을 제공합니" +"다.\n" +"* `src/bare-metal/useful-crates/zerocopy-example/`에서 `cargo run`을 사용하" +"여 예시를 실행합니다(종속성 문제로 인해\n" +" 플레이그라운드에서는 실행되지 않습니다)." + +#: src/bare-metal/useful-crates/aarch64-paging.md:1 +msgid "# `aarch64-paging`" +msgstr "# `aarch64-paging`" + +#: src/bare-metal/useful-crates/aarch64-paging.md:3 +msgid "" +"The [`aarch64-paging`][1] crate lets you create page tables according to the " +"AArch64 Virtual Memory\n" +"System Architecture." +msgstr "" +"[`aarch64-paging`][1] 크레이트를 사용하면 AArch64 가상 메모리 시스템 아키텍처" +"에 따라 페이지 테이블을\n" +"만들 수 있습니다." + +#: src/bare-metal/useful-crates/aarch64-paging.md:6 +msgid "" +"```rust,editable,compile_fail\n" +"use aarch64_paging::{\n" +" idmap::IdMap,\n" +" paging::{Attributes, MemoryRegion},\n" +"};\n" +"\n" +"const ASID: usize = 1;\n" +"const ROOT_LEVEL: usize = 1;\n" +"\n" +"// Create a new page table with identity mapping.\n" +"let mut idmap = IdMap::new(ASID, ROOT_LEVEL);\n" +"// Map a 2 MiB region of memory as read-only.\n" +"idmap.map_range(\n" +" &MemoryRegion::new(0x80200000, 0x80400000),\n" +" Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::READ_ONLY,\n" +").unwrap();\n" +"// Set `TTBR0_EL1` to activate the page table.\n" +"idmap.activate();\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"use aarch64_paging::{\n" +" idmap::IdMap,\n" +" paging::{Attributes, MemoryRegion},\n" +"};\n" +"\n" +"const ASID: usize = 1;\n" +"const ROOT_LEVEL: usize = 1;\n" +"\n" +"// 상동(identity) 매핑으로 새로운 페이지 테이블을 만듭니다.\n" +"let mut idmap = IdMap::new(ASID, ROOT_LEVEL);\n" +"// 2MiB 메모리 영역을 읽기 전용으로 매핑합니다.\n" +"idmap.map_range(\n" +" &MemoryRegion::new(0x80200000, 0x80400000),\n" +" Attributes::NORMAL | Attributes::NON_GLOBAL | Attributes::READ_ONLY,\n" +").unwrap();\n" +"// 페이지 테이블을 활성화하도록 `TTBR0_EL1`을 설정합니다.\n" +"idmap.activate();\n" +"```" + +#: src/bare-metal/useful-crates/aarch64-paging.md:28 +msgid "" +"* For now it only supports EL1, but support for other exception levels " +"should be straightforward to\n" +" add.\n" +"* This is used in Android for the [Protected VM Firmware][2].\n" +"* There's no easy way to run this example, as it needs to run on real " +"hardware or under QEMU." +msgstr "" +"* 현재는 EL1만 지원하지만 다른 익셉션 레벨(Exception Level: EL)도 어렵지 않게 추가할 수\n" +" 있습니다.\n" +"* Android에서 [보호된 VM 펌웨어][2]에 사용됩니다.\n" +"* 이 예시를 간단하게 실행하는 방법은 없습니다. 실제 하드웨어 또는 QEMU에서 실" +"행해야 하기 때문입니다." + +#: src/bare-metal/useful-crates/buddy_system_allocator.md:1 +msgid "# `buddy_system_allocator`" +msgstr "# `buddy_system_allocator`" + +#: src/bare-metal/useful-crates/buddy_system_allocator.md:3 +msgid "" +"[`buddy_system_allocator`][1] is a third-party crate implementing a basic " +"buddy system allocator.\n" +"It can be used both for [`LockedHeap`][2] implementing [`GlobalAlloc`][3] so " +"you can use the\n" +"standard `alloc` crate (as we saw [before][4]), or for allocating other " +"address space. For example,\n" +"we might want to allocate MMIO space for PCI BARs:" +msgstr "" +"[`buddy_system_allocator`][1]는 버디 시스템 할당자를 구현하는 서드 파티 " +"크레이트입니다.\n" +"이 크레이트의 [`LockedHeap`][2]은 [`GlobalAlloc`][3]를 구현합니다. 따라서 여러분은 버디 시스템 할당자를 " +"'alloc' 크레이트를 통해서 사용할 수 있습니다([이전][4]에 확인함).\n" +"또는 다른 주소 공간을 할당하는 데 사용할 수 있습니다. 예를 들어\n" +"PCI BAR에 MMIO 공간을 할당할 수 있습니다." + +#: src/bare-metal/useful-crates/buddy_system_allocator.md:8 +msgid "" +"```rust,editable,compile_fail\n" +"use buddy_system_allocator::FrameAllocator;\n" +"use core::alloc::Layout;\n" +"\n" +"fn main() {\n" +" let mut allocator = FrameAllocator::<32>::new();\n" +" allocator.add_frame(0x200_0000, 0x400_0000);\n" +"\n" +" let layout = Layout::from_size_align(0x100, 0x100).unwrap();\n" +" let bar = allocator\n" +" .alloc_aligned(layout)\n" +" .expect(\"Failed to allocate 0x100 byte MMIO region\");\n" +" println!(\"Allocated 0x100 byte MMIO region at {:#x}\", bar);\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"use buddy_system_allocator::FrameAllocator;\n" +"use core::alloc::Layout;\n" +"\n" +"fn main() {\n" +" let mut allocator = FrameAllocator::<32>::new();\n" +" allocator.add_frame(0x200_0000, 0x400_0000);\n" +"\n" +" let layout = Layout::from_size_align(0x100, 0x100).unwrap();\n" +" let bar = allocator\n" +" .alloc_aligned(layout)\n" +" .expect(\"Failed to allocate 0x100 byte MMIO region\");\n" +" println!(\"Allocated 0x100 byte MMIO region at {:#x}\", bar);\n" +"}\n" +"```" + +#: src/bare-metal/useful-crates/buddy_system_allocator.md:26 +msgid "" +"* PCI BARs always have alignment equal to their size.\n" +"* Run the example with `cargo run` under `src/bare-metal/useful-crates/" +"allocator-example/`. (It won't\n" +" run in the Playground because of the crate dependency.)" +msgstr "" +"* PCI BAR는 BAR영역의 크기에 맞추어 정렬됩니다.\n" +"* `src/bare-metal/useful-crates/allocator-example/`에서 `cargo run`을 사용하" +"여 예시를 실행합니다(종속성 문제로 인해\n" +" 플레이그라운드에서는 실행되지 않습니다)." + +#: src/bare-metal/useful-crates/tinyvec.md:1 +msgid "# `tinyvec`" +msgstr "# `tinyvec`" + +#: src/bare-metal/useful-crates/tinyvec.md:3 +msgid "" +"Sometimes you want something which can be resized like a `Vec`, but without " +"heap allocation.\n" +"[`tinyvec`][1] provides this: a vector backed by an array or slice, which " +"could be statically\n" +"allocated or on the stack, which keeps track of how many elements are used " +"and panics if you try to\n" +"use more than are allocated." +msgstr "" +"힙에 메모리 할당하지 않고 크기 조절이 가능한 컨테이너(예: `Vec` 같은)가 필요할 때가 있습니다.\n" +"[`tinyvec`][1]을 사용하면 됩니다. `tinyvec`에서 벡터는 배열 또는 슬라이스로부터 생성이 되며, " +"이들은 정적으로 할당되었거나 스택에 할당되어 있을 수 있습니다." +"`tinyvec`은 현재 벡터 안에 얼마나 많은 엘리먼트들이 존재하는 지를 추적하고 있으며, 할당된 양보다 더 많이 사용하려고 하면\n" +"패닉을 발생시킵니다." + +#: src/bare-metal/useful-crates/tinyvec.md:8 +msgid "" +"```rust,editable,compile_fail\n" +"use tinyvec::{array_vec, ArrayVec};\n" +"\n" +"fn main() {\n" +" let mut numbers: ArrayVec<[u32; 5]> = array_vec!(42, 66);\n" +" println!(\"{numbers:?}\");\n" +" numbers.push(7);\n" +" println!(\"{numbers:?}\");\n" +" numbers.remove(1);\n" +" println!(\"{numbers:?}\");\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"use tinyvec::{array_vec, ArrayVec};\n" +"\n" +"fn main() {\n" +" let mut numbers: ArrayVec<[u32; 5]> = array_vec!(42, 66);\n" +" println!(\"{numbers:?}\");\n" +" numbers.push(7);\n" +" println!(\"{numbers:?}\");\n" +" numbers.remove(1);\n" +" println!(\"{numbers:?}\");\n" +"}\n" +"```" + +#: src/bare-metal/useful-crates/tinyvec.md:23 +msgid "" +"* `tinyvec` requires that the element type implement `Default` for " +"initialisation.\n" +"* The Rust Playground includes `tinyvec`, so this example will run fine " +"inline." +msgstr "" +"* `tinyvec`를 사용하려면 엘리먼트의 타입이 `Default`를 통해 초기화 될 수 있어야 합니" +"다.\n" +"* Rust 플레이그라운드에는 `tinyvec`가 포함되어 있으므로 이 예시는 인라인으로 " +"실행됩니다." + +#: src/bare-metal/useful-crates/spin.md:3 +msgid "" +"`std::sync::Mutex` and the other synchronisation primitives from `std::sync` " +"are not available in\n" +"`core` or `alloc`. How can we manage synchronisation or interior mutability, " +"such as for sharing\n" +"state between different CPUs?" +msgstr "" +"`std::sync::Mutex` 및 `std::sync`의 기타 동기화 프리미티브는 `core` 또는 " +"`alloc`에서\n" +"사용할 수 없습니다. 그러면 어떻게 동기화 또는 interior mutability와 같은 기능이 필요할 경우 어떻게 해야 할까요? " + +#: src/bare-metal/useful-crates/spin.md:7 +msgid "" +"The [`spin`][1] crate provides spinlock-based equivalents of many of these " +"primitives." +msgstr "" +"[`spin`][1] 크레이트는 이러한 동기화 프리미티브들을 스핀록으로 구현하고 있습니다." + +#: src/bare-metal/useful-crates/spin.md:9 +msgid "" +"```rust,editable,compile_fail\n" +"use spin::mutex::SpinMutex;\n" +"\n" +"static counter: SpinMutex = SpinMutex::new(0);\n" +"\n" +"fn main() {\n" +" println!(\"count: {}\", counter.lock());\n" +" *counter.lock() += 2;\n" +" println!(\"count: {}\", counter.lock());\n" +"}\n" +"```" +msgstr "" +"```rust,editable,compile_fail\n" +"use spin::mutex::SpinMutex;\n" +"\n" +"static counter: SpinMutex = SpinMutex::new(0);\n" +"\n" +"fn main() {\n" +" println!(\"count: {}\", counter.lock());\n" +" *counter.lock() += 2;\n" +" println!(\"count: {}\", counter.lock());\n" +"}\n" +"```" + +#: src/bare-metal/useful-crates/spin.md:23 +msgid "" +"* Be careful to avoid deadlock if you take locks in interrupt handlers.\n" +"* `spin` also has a ticket lock mutex implementation; equivalents of " +"`RwLock`, `Barrier` and `Once`\n" +" from `std::sync`; and `Lazy` for lazy initialisation.\n" +"* The [`once_cell`][2] crate also has some useful types for late " +"initialisation with a slightly\n" +" different approach to `spin::once::Once`.\n" +"* The Rust Playground includes `spin`, so this example will run fine inline." +msgstr "" +"* 인터럽트 핸들러에서 락을 걸 경우, 교착 상태가 발생하지 않도록 주의하세" +"요.\n" +"* `spin`에는 티켓 잠금 뮤텍스 구현도 있습니다. `std::sync`의 `RwLock`, " +"`Barrier`, `Once` 에 해당하는 것들이 제공되며, \n" +" 지연된 초기화를 위한 `Lazy`에 해당하는 것도 제공됩니다.\n" +"* [`once_cell`][2] 크레이트에는 지연된 초기화를 위한 몇 가지 유용한 타입이 있는" +"데\n" +" `spin::once::Once`와는 약간 다른 접근 방식을 사용합니다.\n" +"* Rust 플레이그라운드에는 `spin`이 포함되어 있으므로 이 예시는 인라인으로 실" +"행됩니다." + +#: src/bare-metal/android.md:3 +msgid "" +"To build a bare-metal Rust binary in AOSP, you need to use a " +"`rust_ffi_static` Soong rule to build\n" +"your Rust code, then a `cc_binary` with a linker script to produce the " +"binary itself, and then a\n" +"`raw_binary` to convert the ELF to a raw binary ready to be run." +msgstr "" +"AOSP에서 bare-metal Rust 바이너리를 빌드하려면 `rust_ffi_static` " +"을 사용하여 Rust 코드를\n" +"빌드하고, 링커 스크립트가 포함된 `cc_binary`를 사용하여 ELF 바이너리를 생성" +"하고, `raw_binary`를 사용해\n" +"ELF를 곧바로 수행될 수 있는 원시(raw) 바이너리로 변환합니다." + +#: src/bare-metal/android.md:7 +msgid "" +"```soong\n" +"rust_ffi_static {\n" +" name: \"libvmbase_example\",\n" +" defaults: [\"vmbase_ffi_defaults\"],\n" +" crate_name: \"vmbase_example\",\n" +" srcs: [\"src/main.rs\"],\n" +" rustlibs: [\n" +" \"libvmbase\",\n" +" ],\n" +"}\n" +"\n" +"cc_binary {\n" +" name: \"vmbase_example\",\n" +" defaults: [\"vmbase_elf_defaults\"],\n" +" srcs: [\n" +" \"idmap.S\",\n" +" ],\n" +" static_libs: [\n" +" \"libvmbase_example\",\n" +" ],\n" +" linker_scripts: [\n" +" \"image.ld\",\n" +" \":vmbase_sections\",\n" +" ],\n" +"}\n" +"\n" +"raw_binary {\n" +" name: \"vmbase_example_bin\",\n" +" stem: \"vmbase_example.bin\",\n" +" src: \":vmbase_example\",\n" +" enabled: false,\n" +" target: {\n" +" android_arm64: {\n" +" enabled: true,\n" +" },\n" +" },\n" +"}\n" +"```" +msgstr "" +"```soong\n" +"rust_ffi_static {\n" +" name: \"libvmbase_example\",\n" +" defaults: [\"vmbase_ffi_defaults\"],\n" +" crate_name: \"vmbase_example\",\n" +" srcs: [\"src/main.rs\"],\n" +" rustlibs: [\n" +" \"libvmbase\",\n" +" ],\n" +"}\n" +"\n" +"cc_binary {\n" +" name: \"vmbase_example\",\n" +" defaults: [\"vmbase_elf_defaults\"],\n" +" srcs: [\n" +" \"idmap.S\",\n" +" ],\n" +" static_libs: [\n" +" \"libvmbase_example\",\n" +" ],\n" +" linker_scripts: [\n" +" \"image.ld\",\n" +" \":vmbase_sections\",\n" +" ],\n" +"}\n" +"\n" +"raw_binary {\n" +" name: \"vmbase_example_bin\",\n" +" stem: \"vmbase_example.bin\",\n" +" src: \":vmbase_example\",\n" +" enabled: false,\n" +" target: {\n" +" android_arm64: {\n" +" enabled: true,\n" +" },\n" +" },\n" +"}\n" +"```" + +#: src/bare-metal/android/vmbase.md:1 +msgid "# vmbase" +msgstr "# vmbase" + +#: src/bare-metal/android/vmbase.md:3 +msgid "" +"For VMs running under crosvm on aarch64, the [vmbase][1] library provides a " +"linker script and useful\n" +"defaults for the build rules, along with an entry point, UART console " +"logging and more." +msgstr "" +"[vmbase][1] 라이브러리는, aarch64의 crosvm에서 실행되는 VM을 타겟하여, 진입점, " +"UART 콘솔 로깅, 링커 스크립트, 빌드 룰 등에 대한 기본 구현들을 제공합니다." + +#: src/bare-metal/android/vmbase.md:6 +msgid "" +"```rust,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"use vmbase::{main, println};\n" +"\n" +"main!(main);\n" +"\n" +"pub fn main(arg0: u64, arg1: u64, arg2: u64, arg3: u64) {\n" +" println!(\"Hello world\");\n" +"}\n" +"```" +msgstr "" +"```rust,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"use vmbase::{main, println};\n" +"\n" +"main!(main);\n" +"\n" +"pub fn main(arg0: u64, arg1: u64, arg2: u64, arg3: u64) {\n" +" println!(\"Hello world\");\n" +"}\n" +"```" + +#: src/bare-metal/android/vmbase.md:21 +msgid "" +"* The `main!` macro marks your main function, to be called from the `vmbase` " +"entry point.\n" +"* The `vmbase` entry point handles console initialisation, and issues a " +"PSCI_SYSTEM_OFF to shutdown\n" +" the VM if your main function returns." +msgstr "" +"* `main!` 매크로는 `vmbase` 진입점에서 호출될 main 함수를 표시합니다.\n" +"* `vmbase`가 제공하는 진입점은 콘솔을 초기화 하며, main 함수가 리턴하면 " +" PSCI_SYSTEM_OFF 메시지를 PSCI를 통해 보내어서 VM을 종료시킵니다." + #: src/thanks.md:1 msgid "# Thanks!" msgstr "# 감사인사"