diff --git a/po/es.po b/po/es.po index de81fcd692d2..c6db51da3399 100644 --- a/po/es.po +++ b/po/es.po @@ -13214,9 +13214,8 @@ msgid "" msgstr "" #: src/bare-metal.md:1 -#, fuzzy msgid "Welcome to Bare Metal Rust" -msgstr "Bienvenido a Comprehensive Rust 🦀" +msgstr "Te damos la bienvenida a Bare Metal Rust" #: src/bare-metal.md:3 msgid "" @@ -13225,29 +13224,35 @@ msgid "" "Comprehensive Rust course), and ideally also have some experience with bare-" "metal programming in some other language such as C." msgstr "" +"Este es un curso independiente de un día sobre Rust bare-metal, dirigido a " +"personas que están familiarizadas con los conceptos básicos de Rust (tal vez " +"después de completar el curso Comprehensive Rust). Lo ideal sería que " +"también tuvieran experiencia con la programación bare-metal en otros " +"lenguajes, como C." #: src/bare-metal.md:7 msgid "" "Today we will talk about 'bare-metal' Rust: running Rust code without an OS " "underneath us. This will be divided into several parts:" msgstr "" +"Hoy vamos a hablar de Rust \"bare-metal\": ejecutar código de Rust sin un " +"sistema operativo. Se dividirá en varias partes:" #: src/bare-metal.md:10 -#, fuzzy msgid "What is `no_std` Rust?" -msgstr "¿Qué es Rust?" +msgstr "¿Qué es `no_std` en Rust?" #: src/bare-metal.md:11 msgid "Writing firmware for microcontrollers." -msgstr "" +msgstr "Escribir firmware para microcontroladores." #: src/bare-metal.md:12 msgid "Writing bootloader / kernel code for application processors." -msgstr "" +msgstr "Escribir código bootloader o kernel para procesadores de aplicaciones." #: src/bare-metal.md:13 msgid "Some useful crates for bare-metal Rust development." -msgstr "" +msgstr "Algunos crates útiles para el desarrollo de Rust bare-metal." #: src/bare-metal.md:15 msgid "" @@ -13257,11 +13262,18 @@ msgid "" "with some LEDs and buttons, an I2C-connected accelerometer and compass, and " "an on-board SWD debugger." msgstr "" +"En la parte del curso dedicada a los microcontroladores, utilizaremos la " +"versión 2 de [BBC micro:bit](https://microbit.org/) como ejemplo. Es una " +"[placa de desarrollo](https://tech.microbit.org/hardware/) basada en el " +"microcontrolador Nordic nRF51822 con algunos LED y botones, un acelerómetro " +"y una brújula conectados mediante I2C y un depurador SWD integrado." #: src/bare-metal.md:20 msgid "" "To get started, install some tools we'll need later. On gLinux or Debian:" msgstr "" +"Para empezar, instala algunas de las herramientas que necesitarás más " +"adelante. En gLinux o Debian:" #: src/bare-metal.md:22 msgid "" @@ -13274,11 +13286,20 @@ msgid "" "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 "" +"Permite a los usuarios del grupo `plugdev` acceder al programador micro:bit:" #: src/bare-metal.md:32 msgid "" @@ -13289,10 +13310,16 @@ msgid "" "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 "" +msgstr "En MacOS:" #: src/bare-metal.md:40 msgid "" @@ -13306,119 +13333,127 @@ msgid "" "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 "" +msgstr "`no_std`" #: src/bare-metal/no_std.md:7 msgid "`core`" -msgstr "" +msgstr "`core`" #: src/bare-metal/no_std.md:12 src/bare-metal/alloc.md:1 msgid "`alloc`" -msgstr "" +msgstr "`alloc`" #: src/bare-metal/no_std.md:17 msgid "`std`" -msgstr "" +msgstr "`std`" #: src/bare-metal/no_std.md:24 msgid "Slices, `&str`, `CStr`" -msgstr "" +msgstr "Slices, `&str`, `CStr`" #: src/bare-metal/no_std.md:25 msgid "`NonZeroU8`..." -msgstr "" +msgstr "`NonZeroU8`..." #: src/bare-metal/no_std.md:26 -#, fuzzy msgid "`Option`, `Result`" -msgstr "Option y Result" +msgstr "`Option`, `Result`" #: src/bare-metal/no_std.md:27 msgid "`Display`, `Debug`, `write!`..." -msgstr "" +msgstr "`Display`, `Debug`, `write!`..." #: src/bare-metal/no_std.md:29 msgid "`panic!`, `assert_eq!`..." -msgstr "" +msgstr "`panic!`, `assert_eq!`..." #: src/bare-metal/no_std.md:30 msgid "`NonNull` and all the usual pointer-related functions" -msgstr "" +msgstr "`NonNull` y todas las funciones relacionadas con punteros habituales" #: src/bare-metal/no_std.md:31 msgid "`Future` and `async`/`await`" -msgstr "" +msgstr "`Future` and `async`/`await`" #: src/bare-metal/no_std.md:32 msgid "`fence`, `AtomicBool`, `AtomicPtr`, `AtomicU32`..." -msgstr "" +msgstr "`fence`, `AtomicBool`, `AtomicPtr`, `AtomicU32`..." #: src/bare-metal/no_std.md:33 msgid "`Duration`" -msgstr "" +msgstr "`Duration`" #: src/bare-metal/no_std.md:38 msgid "`Box`, `Cow`, `Arc`, `Rc`" -msgstr "" +msgstr "`Box`, `Cow`, `Arc`, `Rc`" #: src/bare-metal/no_std.md:39 msgid "`Vec`, `BinaryHeap`, `BtreeMap`, `LinkedList`, `VecDeque`" -msgstr "" +msgstr "`Vec`, `BinaryHeap`, `BtreeMap`, `LinkedList`, `VecDeque`" #: src/bare-metal/no_std.md:40 msgid "`String`, `CString`, `format!`" -msgstr "" +msgstr "`String`, `CString`, `format!`" #: src/bare-metal/no_std.md:45 msgid "`Error`" -msgstr "" +msgstr "`Error`" #: src/bare-metal/no_std.md:47 msgid "`Mutex`, `Condvar`, `Barrier`, `Once`, `RwLock`, `mpsc`" -msgstr "" +msgstr "`Mutex`, `Condvar`, `Barrier`, `Once`, `RwLock`, `mpsc`" #: src/bare-metal/no_std.md:48 msgid "`File` and the rest of `fs`" -msgstr "" +msgstr "`File` y el resto de `fs`" #: src/bare-metal/no_std.md:49 msgid "`println!`, `Read`, `Write`, `Stdin`, `Stdout` and the rest of `io`" -msgstr "" +msgstr "`println!`, `Read`, `Write`, `Stdin`, `Stdout` y el resto de `io`" #: src/bare-metal/no_std.md:50 msgid "`Path`, `OsString`" -msgstr "" +msgstr "`Path`, `OsString`" #: src/bare-metal/no_std.md:51 msgid "`net`" -msgstr "" +msgstr "`net`" #: src/bare-metal/no_std.md:52 msgid "`Command`, `Child`, `ExitCode`" -msgstr "" +msgstr "`Command`, `Child`, `ExitCode`" #: src/bare-metal/no_std.md:53 msgid "`spawn`, `sleep` and the rest of `thread`" -msgstr "" +msgstr "`spawn`, `sleep` y el resto de `thread`" #: src/bare-metal/no_std.md:54 msgid "`SystemTime`, `Instant`" -msgstr "" +msgstr "`SystemTime`, `Instant`" #: src/bare-metal/no_std.md:62 msgid "`HashMap` depends on RNG." -msgstr "" +msgstr "`HashMap` depende de RNG." #: src/bare-metal/no_std.md:63 msgid "`std` re-exports the contents of both `core` and `alloc`." -msgstr "" +msgstr "`std` vuelve a exportar el contenido de `core` y `alloc`." #: src/bare-metal/minimal.md:1 msgid "A minimal `no_std` program" -msgstr "" +msgstr "Un programa `no_std` mínimo" #: src/bare-metal/minimal.md:3 msgid "" @@ -13434,24 +13469,39 @@ msgid "" "}\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." -msgstr "" +msgstr "Se compilará en un binario vacío." #: src/bare-metal/minimal.md:18 msgid "`std` provides a panic handler; without it we must provide our own." msgstr "" +"`std` proporciona un controlador de pánico; sin no hay, debemos proporcionar " +"uno nuestro." #: src/bare-metal/minimal.md:19 msgid "It can also be provided by another crate, such as `panic-halt`." -msgstr "" +msgstr "También puede proporcionarlo otro crate, como `panic-halt`." #: src/bare-metal/minimal.md:20 msgid "" "Depending on the target, you may need to compile with `panic = \"abort\"` to " "avoid an error about `eh_personality`." msgstr "" +"Dependiendo del objetivo, es posible que tengas que compilar con `panic = " +"\"abort\"` para evitar un error sobre `eh_personality`." #: src/bare-metal/minimal.md:22 msgid "" @@ -13459,12 +13509,19 @@ msgid "" "define your own entry point. This will typically involve a linker script and " "some assembly code to set things up ready for Rust code to run." msgstr "" +"Ten en cuenta que no hay `main` ni ningún otro punto de entrada; depende de " +"ti definir un punto de entrada propio. Esto suele implicar una secuencia de " +"comandos de enlazador y algún código de ensamblado de forma que todo esté " +"preparado para que se ejecute el código de Rust." #: src/bare-metal/alloc.md:3 msgid "" "To use `alloc` you must implement a [global (heap) allocator](https://doc." "rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html)." msgstr "" +"Para utilizar `alloc`, debes implementar un \\[asignador global (de " +"montículo)\\][global (heap) allocator](https://doc.rust-lang.org/stable/std/" +"alloc/trait.GlobalAlloc.html)." #: src/bare-metal/alloc.md:6 msgid "" @@ -13500,6 +13557,37 @@ msgid "" "}\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" +" // Ahora podemos hacer cosas que requieran asignación de montículo.\n" +" let mut v = Vec::new();\n" +" v.push(\"A string\".to_string());\n" +"}\n" +"```" #: src/bare-metal/alloc.md:39 msgid "" @@ -13507,12 +13595,17 @@ msgid "" "system allocator. Other crates are available, or you can write your own or " "hook into your existing allocator." msgstr "" +"`buddy_system_allocator` es un crate de terceros que implementa un asignador " +"básico del sistema buddy. Hay otros crates disponibles, pero también puedes " +"escribir el tuyo propio o conectarte a tu asignador." #: src/bare-metal/alloc.md:41 msgid "" "The const parameter of `LockedHeap` is the max order of the allocator; i.e. " "in this case it can allocate regions of up to 2\\*\\*32 bytes." msgstr "" +"El parámetro const de `LockedHeap` es el orden máximo del asignador. Es " +"decir, en este caso, puede asignar regiones de hasta 2\\*\\*32 bytes." #: src/bare-metal/alloc.md:43 msgid "" @@ -13520,22 +13613,31 @@ msgid "" "exactly one global allocator defined in your binary. Usually this is done in " "the top-level binary crate." msgstr "" +"Si algún crate del árbol de dependencias depende de `alloc`, debes tener " +"exactamente un asignador global definido en el binario. Esto se suele hacer " +"en el crate binario de nivel superior." #: src/bare-metal/alloc.md:45 msgid "" "`extern crate panic_halt as _` is necessary to ensure that the `panic_halt` " "crate is linked in so we get its panic handler." msgstr "" +"`extern crate panic_halt as _` es necesario para asegurar que el crate " +"`panic_halt` esté vinculado y así podamos obtener su controlador de pánico." #: src/bare-metal/alloc.md:47 msgid "This example will build but not run, as it doesn't have an entry point." msgstr "" +"Este ejemplo se compilará pero no se ejecutará, ya que no cuenta con un " +"punto de entrada." #: src/bare-metal/microcontrollers.md:3 msgid "" "The `cortex_m_rt` crate provides (among other things) a reset handler for " "Cortex M microcontrollers." msgstr "" +"El crate `cortex_m_rt` proporciona (entre otras cosas) un controlador de " +"reinicio para microcontroladores Cortex M." #: src/bare-metal/microcontrollers.md:5 msgid "" @@ -13555,28 +13657,50 @@ msgid "" "}\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 "" +"A continuación, veremos cómo se accede a los periféricos con niveles de " +"abstracción cada vez mayores." #: src/bare-metal/microcontrollers.md:25 msgid "" "The `cortex_m_rt::entry` macro requires that the function have type `fn() -" "> !`, because returning to the reset handler doesn't make sense." msgstr "" +"La macro `cortex_m_rt::entry` requiere que la función tenga el tipo `fn() -" +"> !`, ya que no tiene sentido devolver resultados al controlador de reinicio." #: src/bare-metal/microcontrollers.md:27 msgid "Run the example with `cargo embed --bin minimal`" -msgstr "" +msgstr "Ejecuta el ejemplo con `cargo embed --bin minimal`." #: 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 micro:bit:" msgstr "" +"La mayoría de los microcontroladores acceden a los periféricos a través de E/" +"S asignada a la memoria. Vamos a probar a encender un LED en nuestro micro:" +"bit:" #: src/bare-metal/microcontrollers/mmio.md:6 msgid "" @@ -13642,19 +13766,82 @@ msgid "" "}\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 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" +"```" #: 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 "" +"El pin 21 de GPIO 0 está conectado a la primera columna de la matriz de LED " +"y el pin 28 a la primera fila." #: 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 "" +msgstr "Ejecuta el ejemplo con:" #: src/bare-metal/microcontrollers/mmio.md:68 msgid "" @@ -13662,10 +13849,13 @@ msgid "" "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 "" +msgstr "Crates de acceso periférico" #: src/bare-metal/microcontrollers/pacs.md:3 msgid "" @@ -13673,6 +13863,10 @@ msgid "" "wrappers for memory-mapped peripherals from [CMSIS-SVD](https://www.keil.com/" "pack/doc/CMSIS/SVD/html/index.html) files." msgstr "" +"[`svd2rust`](https://crates.io/crates/svd2rust) genera, en su gran mayoría, " +"envoltorios seguros de Rust para periféricos asignados a la memoria a partir " +"de archivos [CMSIS-SVD](https://www.keil.com/pack/doc/CMSIS/SVD/html/index." +"html)." #: src/bare-metal/microcontrollers/pacs.md:7 msgid "" @@ -13716,18 +13910,62 @@ msgid "" "}\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" +" // 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" +"```" #: src/bare-metal/microcontrollers/pacs.md:49 msgid "" "SVD (System View Description) files are XML files typically provided by " "silicon vendors which describe the memory map of the device." msgstr "" +"Los archivos SVD (System View Description) son archivos XML que suelen " +"proporcionar los proveedores de silicio y que describen el mapa de memoria " +"del dispositivo." #: src/bare-metal/microcontrollers/pacs.md:51 msgid "" "They are organised by peripheral, register, field and value, with names, " "descriptions, addresses and so on." msgstr "" +"Se organizan por periférico, registro, campo y valor, con nombres, " +"descripciones y direcciones, etc." #: src/bare-metal/microcontrollers/pacs.md:53 msgid "" @@ -13735,16 +13973,21 @@ msgid "" "which patch the mistakes, add missing details, and publish the generated " "crates." msgstr "" +"Los archivos SVD suelen tener errores y estar incompletos, por lo que " +"existen varios proyectos que aplican parches a los errores, añaden detalles " +"que faltan y publican los crates generados." #: src/bare-metal/microcontrollers/pacs.md:55 msgid "`cortex-m-rt` provides the vector table, among other things." -msgstr "" +msgstr "`cortex-m-rt` proporciona la tabla de vectores, entre otras cosas." #: src/bare-metal/microcontrollers/pacs.md:56 msgid "" "If you `cargo install cargo-binutils` then you can run `cargo objdump --bin " "pac -- -d --no-show-raw-insn` to see the resulting binary." msgstr "" +"Si instalas `cargo install cargo-binutils` puedes ejecutar `cargo objdump --" +"bin pac -- -d --no-show-raw-insn` para ver el binario resultante." #: src/bare-metal/microcontrollers/pacs.md:61 msgid "" @@ -13752,10 +13995,13 @@ msgid "" "cargo embed --bin pac\n" "```" msgstr "" +"```sh\n" +"cargo embed --bin pac\n" +"```" #: src/bare-metal/microcontrollers/hals.md:1 msgid "HAL crates" -msgstr "" +msgstr "Crates HAL" #: src/bare-metal/microcontrollers/hals.md:3 msgid "" @@ -13764,6 +14010,10 @@ msgid "" "various peripherals. These generally implement traits from [`embedded-hal`]" "(https://crates.io/crates/embedded-hal)." msgstr "" +"[Los crates HAL](https://github.com/rust-embedded/awesome-embedded-rust#hal-" +"implementation-crates) de muchos microcontroladores incluyen envoltorios " +"alrededor de varios periféricos. Por lo general, implementan traits de " +"[`embedded-hal`](https://crates.io/crates/embedded-hal)." #: src/bare-metal/microcontrollers/hals.md:7 msgid "" @@ -13797,34 +14047,71 @@ msgid "" "}\n" "```" msgstr "" - -#: src/bare-metal/microcontrollers/hals.md:39 -msgid "" -"`set_low` and `set_high` are methods on the `embedded_hal` `OutputPin` trait." -msgstr "" - -#: src/bare-metal/microcontrollers/hals.md:40 -msgid "" -"HAL crates exist for many Cortex-M and RISC-V devices, including various " -"STM32, GD32, nRF, NXP, MSP430, AVR and PIC microcontrollers." -msgstr "" - -#: src/bare-metal/microcontrollers/hals.md:45 -msgid "" -"```sh\n" -"cargo embed --bin hal\n" -"```" -msgstr "" - -#: src/bare-metal/microcontrollers/board-support.md:1 -msgid "Board support crates" -msgstr "" - -#: src/bare-metal/microcontrollers/board-support.md:3 -msgid "" -"Board support crates provide a further level of wrapping for a specific " +"```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." +msgstr "" +"`set_low` y `set_high` son métodos del trait `OutputPin` de `embedded_hal`." + +#: src/bare-metal/microcontrollers/hals.md:40 +msgid "" +"HAL crates exist for many Cortex-M and RISC-V devices, including various " +"STM32, GD32, nRF, NXP, MSP430, AVR and PIC microcontrollers." +msgstr "" +"Hay crates HAL para muchos dispositivos Cortex-M y RISC-V, incluidos varios " +"microcontroladores STM32, GD32, nRF, NXP, MSP430, AVR y PIC." + +#: 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:1 +msgid "Board support crates" +msgstr "Crates de compatibilidad de placa" + +#: 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 "" +"Los crates de compatibilidad de placa proporcionan un nivel adicional de " +"envoltorio a una placa específica para mayor comodidad." #: src/bare-metal/microcontrollers/board-support.md:5 msgid "" @@ -13849,22 +14136,46 @@ msgid "" "}\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 initialisation." msgstr "" +"En este caso, el crate de compatibilidad de placa proporciona solo nombres " +"más útiles y un poco de inicialización." #: src/bare-metal/microcontrollers/board-support.md:30 msgid "" "The crate may also include drivers for some on-board devices outside of the " "microcontroller itself." msgstr "" +"El crate también puede incluir controladores para algunos dispositivos " +"integrados fuera del propio microcontrolador ." #: src/bare-metal/microcontrollers/board-support.md:32 msgid "`microbit-v2` includes a simple driver for the LED matrix." -msgstr "" +msgstr "`microbit-v2` incluye un controlador sencillo para la matriz de LED." #: src/bare-metal/microcontrollers/board-support.md:36 msgid "" @@ -13872,10 +14183,13 @@ msgid "" "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 "" +msgstr "El patrón de tipo de estado" #: src/bare-metal/microcontrollers/type-state.md:3 msgid "" @@ -13909,18 +14223,52 @@ msgid "" "}\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(); // 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" +"```" #: 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 moved out of the port struct nobody else can take it." msgstr "" +"Los pines no implementan `Copy` ni `Clone`, por lo que solo puede haber una " +"instancia de cada uno. Cuando se quita un pin de la estructura del puerto, " +"nadie más puede usarlo." #: src/bare-metal/microcontrollers/type-state.md:34 msgid "" "Changing the configuration of a pin consumes the old pin instance, so you " "can’t keep use the old instance afterwards." msgstr "" +"Si cambias la configuración de un pin, se consumirá la instancia del pin " +"anterior y no podrás seguir usando la instancia previa." #: src/bare-metal/microcontrollers/type-state.md:36 msgid "" @@ -13930,50 +14278,60 @@ msgid "" "way without properly configuring it first. Illegal state transitions are " "caught at compile time." msgstr "" +"El tipo de un valor indica el estado en el que se encuentra: por ejemplo, en " +"este caso, el estado de configuración de un pin de GPIO. De esta manera, se " +"codifica la máquina de estados en el sistema de tipos, asegurando así que no " +"se use un pin de cierta forma sin antes configurarlo correctamente. Las " +"transiciones de estado ilegales se detectan durante el tiempo de compilación." #: src/bare-metal/microcontrollers/type-state.md:40 msgid "" "You can call `is_high` on an input pin and `set_high` on an output pin, but " "not vice-versa." msgstr "" +"Puedes llamar a `is_high` en un pin de entrada y a `set_high` en un pin de " +"salida, pero no al revés." #: src/bare-metal/microcontrollers/type-state.md:41 msgid "Many HAL crates follow this pattern." -msgstr "" +msgstr "Muchos crates HAL siguen este patrón." #: src/bare-metal/microcontrollers/embedded-hal.md:1 msgid "`embedded-hal`" -msgstr "" +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 covering common microcontroller peripherals." msgstr "" +"El crate [`embedded-hal`](https://crates.io/crates/embedded-hal) proporciona " +"una serie de traits que cubren los periféricos habituales de los " +"microcontroladores." #: src/bare-metal/microcontrollers/embedded-hal.md:6 msgid "GPIO" -msgstr "" +msgstr "GPIO" #: src/bare-metal/microcontrollers/embedded-hal.md:7 msgid "ADC" -msgstr "" +msgstr "ADC" #: src/bare-metal/microcontrollers/embedded-hal.md:8 msgid "I2C, SPI, UART, CAN" -msgstr "" +msgstr "I2C, SPI, UART, CAN" #: src/bare-metal/microcontrollers/embedded-hal.md:9 msgid "RNG" -msgstr "" +msgstr "RNG" #: src/bare-metal/microcontrollers/embedded-hal.md:10 msgid "Timers" -msgstr "" +msgstr "Temporizadores" #: src/bare-metal/microcontrollers/embedded-hal.md:11 msgid "Watchdogs" -msgstr "" +msgstr "Watchdogs" #: src/bare-metal/microcontrollers/embedded-hal.md:13 msgid "" @@ -13981,67 +14339,80 @@ msgid "" "awesome-embedded-rust#driver-crates) in terms of these traits, e.g. an " "accelerometer driver might need an I2C or SPI bus implementation." msgstr "" +"Es entonces cuando otros crates implementan \\[controladores\\][drivers]" +"(https://github.com/rust-embedded/awesome-embedded-rust#driver-crates) en " +"función de estos traits. Por ejemplo, un controlador de acelerómetro podría " +"necesitar una implementación de bus I2C o SPI." #: src/bare-metal/microcontrollers/embedded-hal.md:19 msgid "" "There are implementations for many microcontrollers, as well as other " "platforms such as Linux on Raspberry Pi." msgstr "" +"Hay implementaciones para muchos microcontroladores, así como otras " +"plataformas como Linux en Raspberry Pi." #: src/bare-metal/microcontrollers/embedded-hal.md:21 msgid "" "There is work in progress on an `async` version of `embedded-hal`, but it " "isn't stable yet." msgstr "" +"Se está trabajando en una versión `async` de `embedded-hal`, pero aún no es " +"estable." #: src/bare-metal/microcontrollers/probe-rs.md:1 msgid "`probe-rs`, `cargo-embed`" -msgstr "" +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 integrated." msgstr "" +"[probe-rs](https://probe.rs/) es un conjunto de herramientas de depuración " +"integradas muy útil, como OpenOCD, pero mejor integrado." #: src/bare-metal/microcontrollers/probe-rs.md:6 msgid "SWD" -msgstr "" +msgstr "SWD" #: src/bare-metal/microcontrollers/probe-rs.md:6 msgid " and JTAG via CMSIS-DAP, ST-Link and J-Link probes" -msgstr "" +msgstr " y JTAG a través de comprobaciones CMSIS-DAP, ST-Link y J-Link" #: src/bare-metal/microcontrollers/probe-rs.md:7 msgid "GDB stub and Microsoft " -msgstr "" +msgstr "GDB stub y el servidor " #: src/bare-metal/microcontrollers/probe-rs.md:7 msgid "DAP" -msgstr "" +msgstr "DAP" #: src/bare-metal/microcontrollers/probe-rs.md:7 -#, fuzzy msgid " server" -msgstr "servers." +msgstr " de Microsoft" #: src/bare-metal/microcontrollers/probe-rs.md:8 msgid "Cargo integration" -msgstr "" +msgstr "Integración de Cargo" #: src/bare-metal/microcontrollers/probe-rs.md:10 msgid "`cargo-embed` is a cargo subcommand to build and flash binaries, log " msgstr "" +"`cargo-embed` es un subcomando de Cargo para compilar e instalar binarios, " +"registrar salidas " #: src/bare-metal/microcontrollers/probe-rs.md:11 msgid "RTT" -msgstr "" +msgstr "TTR" #: src/bare-metal/microcontrollers/probe-rs.md:11 msgid "" " output and connect GDB. It's configured by an `Embed.toml` file in your " "project directory." msgstr "" +" y conectar GDB. Se configura mediante un archivo `Embed.toml` en el " +"directorio del proyecto." #: src/bare-metal/microcontrollers/probe-rs.md:16 msgid "" @@ -14050,24 +14421,34 @@ msgid "" "CoreSight Debug Access Port of various Arm Cortex processors. It's what the " "on-board debugger on the BBC micro:bit uses." msgstr "" +"[CMSIS-DAP](https://arm-software.github.io/CMSIS_5/DAP/html/index.html) es " +"un protocolo estándar de Arm mediante USB que permite que un depurador en " +"circuito acceda al puerto de acceso de depuración CoreSight de varios " +"procesadores Cortex de Arm. Es lo que utiliza el depurador integrado en el " +"BBC micro:bit" #: src/bare-metal/microcontrollers/probe-rs.md:19 msgid "" "ST-Link is a range of in-circuit debuggers from ST Microelectronics, J-Link " "is a range from SEGGER." msgstr "" +"ST-Link es una gama de depuradores en circuito de ST Microelectronics. J-" +"Link es una gama de SEGGER." #: src/bare-metal/microcontrollers/probe-rs.md:21 msgid "" "The Debug Access Port is usually either a 5-pin JTAG interface or 2-pin " "Serial Wire Debug." msgstr "" +"El puerto de acceso de depuración suele ser una interfaz JTAG de 5 pines o " +"una SWD de 2 pines." #: src/bare-metal/microcontrollers/probe-rs.md:22 msgid "" "probe-rs is a library which you can integrate into your own tools if you " "want to." msgstr "" +"probe-rs es una biblioteca que puedes integrar en tus propias herramientas." #: src/bare-metal/microcontrollers/probe-rs.md:23 msgid "" @@ -14075,20 +14456,27 @@ msgid "" "adapter-protocol/) lets VSCode and other IDEs debug code running on any " "supported microcontroller." msgstr "" +"\\[El protocolo de adaptador de depuración de Microsoft\\][Microsoft Debug " +"Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/) " +"permite que VSCode y otros IDEs depuren el código que se ejecuta en " +"cualquier microcontrolador compatible." #: src/bare-metal/microcontrollers/probe-rs.md:25 msgid "cargo-embed is a binary built using the probe-rs library." -msgstr "" +msgstr "cargo-embed es un binario compilado con la biblioteca probe-rs." #: src/bare-metal/microcontrollers/probe-rs.md:26 msgid "" "RTT (Real Time Transfers) is a mechanism to transfer data between the debug " "host and the target through a number of ringbuffers." msgstr "" +"TTR (transferencias en tiempo real) es un mecanismo para transferir datos " +"entre el host de depuración y el objetivo a través de una serie de búferes " +"circulares." #: src/bare-metal/microcontrollers/debugging.md:3 msgid "Embed.toml:" -msgstr "" +msgstr "Embed.toml:" #: src/bare-metal/microcontrollers/debugging.md:5 msgid "" @@ -14100,10 +14488,17 @@ msgid "" "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 "" +msgstr "En un terminal en `src/bare-metal/microcontrollers/examples/`:" #: src/bare-metal/microcontrollers/debugging.md:15 msgid "" @@ -14111,10 +14506,13 @@ msgid "" "cargo embed --bin board_support debug\n" "```" msgstr "" +"```sh\n" +"cargo embed --bin board_support debug\n" +"```" #: src/bare-metal/microcontrollers/debugging.md:19 msgid "In another terminal in the same directory:" -msgstr "" +msgstr "En otro terminal del mismo directorio:" #: src/bare-metal/microcontrollers/debugging.md:21 msgid "" @@ -14123,10 +14521,14 @@ msgid "" "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 "" +msgstr "En GDB, prueba a ejecutar:" #: src/bare-metal/microcontrollers/debugging.md:29 msgid "" @@ -14139,98 +14541,123 @@ msgid "" "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 -#, fuzzy msgid "Other projects" -msgstr "Otros Recursos" +msgstr "Otros proyectos" #: src/bare-metal/microcontrollers/other-projects.md:3 msgid "[RTIC](https://rtic.rs/)" -msgstr "" +msgstr "[RTIC](https://rtic.rs/)" #: src/bare-metal/microcontrollers/other-projects.md:4 msgid "\"Real-Time Interrupt-driven Concurrency\"" -msgstr "" +msgstr "\"Concurrencia en tiempo real basada en interrupciones\"" #: src/bare-metal/microcontrollers/other-projects.md:5 msgid "" "Shared resource management, message passing, task scheduling, timer queue" msgstr "" +"Gestión de recursos compartidos, envío de mensajes, programación de tareas, " +"cola del temporizador, etc." #: src/bare-metal/microcontrollers/other-projects.md:6 msgid "[Embassy](https://embassy.dev/)" -msgstr "" +msgstr "[Embassy](https://embassy.dev/)" #: src/bare-metal/microcontrollers/other-projects.md:7 msgid "`async` executors with priorities, timers, networking, USB" -msgstr "" +msgstr "Ejecutores `async` con prioridades, temporizadores, redes, USB, etc." #: src/bare-metal/microcontrollers/other-projects.md:8 msgid "[TockOS](https://www.tockos.org/documentation/getting-started)" -msgstr "" +msgstr "[TockOS](https://www.tockos.org/documentation/getting-started)" #: src/bare-metal/microcontrollers/other-projects.md:9 msgid "" "Security-focused RTOS with preemptive scheduling and Memory Protection Unit " "support" msgstr "" +"RTOS centrado en la seguridad con programación interrumpible y " +"compatibilidad con la unidad de protección de memoria." #: src/bare-metal/microcontrollers/other-projects.md:10 msgid "[Hubris](https://hubris.oxide.computer/)" -msgstr "" +msgstr "[Hubris](https://hubris.oxide.computer/)" #: src/bare-metal/microcontrollers/other-projects.md:11 msgid "" "Microkernel RTOS from Oxide Computer Company with memory protection, " "unprivileged drivers, IPC" msgstr "" +"RTOS de microkernel de Oxide Computer Company con protección de memoria, " +"controladores sin privilegios, IPC, etc." #: src/bare-metal/microcontrollers/other-projects.md:12 msgid "[Bindings for FreeRTOS](https://github.com/lobaro/FreeRTOS-rust)" msgstr "" +"\\[Enlaces para FreeRTOS\\][Bindings for FreeRTOS](https://github.com/lobaro/" +"FreeRTOS-rust)" #: src/bare-metal/microcontrollers/other-projects.md:13 msgid "" "Some platforms have `std` implementations, e.g. [esp-idf](https://esp-rs." "github.io/book/overview/using-the-standard-library.html)." msgstr "" +"Algunas plataformas tienen implementaciones `std`, como [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." -msgstr "" +msgstr "RTIC se puede considerar un RTOS o un framework de concurrencia." #: src/bare-metal/microcontrollers/other-projects.md:19 msgid "It doesn't include any HALs." -msgstr "" +msgstr "No incluye ningún HAL." #: src/bare-metal/microcontrollers/other-projects.md:20 msgid "" "It uses the Cortex-M NVIC (Nested Virtual Interrupt Controller) for " "scheduling rather than a proper kernel." msgstr "" +"Usa el NVIC (controlador de interrupción virtual anidado) Cortex‐M para la " +"programación en lugar de un kernel propio." #: src/bare-metal/microcontrollers/other-projects.md:22 msgid "Cortex-M only." -msgstr "" +msgstr "Solo Cortex-M." #: src/bare-metal/microcontrollers/other-projects.md:23 msgid "" "Google uses TockOS on the Haven microcontroller for Titan security keys." msgstr "" +"Google utiliza TockOS en el microcontrolador Haven para las llaves de " +"seguridad Titan." #: src/bare-metal/microcontrollers/other-projects.md:24 msgid "" "FreeRTOS is mostly written in C, but there are Rust bindings for writing " "applications." msgstr "" +"FreeRTOS está escrito principalmente en C, pero hay enlaces de Rust para " +"aplicaciones de escritura." #: src/exercises/bare-metal/morning.md:3 msgid "" "We will read the direction from an I2C compass, and log the readings to a " "serial port." msgstr "" +"Leeremos la dirección desde una brújula I2C, y registraremos las lecturas en " +"un puerto serie." #: src/exercises/bare-metal/compass.md:3 msgid "" @@ -14238,10 +14665,13 @@ msgid "" "serial port. If you have time, try displaying it on the LEDs somehow too, or " "use the buttons somehow." msgstr "" +"Leeremos la dirección desde una brújula I2C, y registraremos las lecturas en " +"un puerto serie. Si tienes tiempo, prueba a mostrarlo también en los LED o " +"usa los botones de alguna forma." #: src/exercises/bare-metal/compass.md:6 msgid "Hints:" -msgstr "" +msgstr "Sugerencias:" #: src/exercises/bare-metal/compass.md:8 msgid "" @@ -14250,16 +14680,23 @@ msgid "" "microbit/) crates, as well as the [micro:bit hardware](https://tech.microbit." "org/hardware/)." msgstr "" +"Consulta la documentación sobre los crates [`lsm303agr`](https://docs.rs/" +"lsm303agr/latest/lsm303agr/) y [`microbit-v2`](https://docs.rs/microbit-v2/" +"latest/microbit/), así como [el hardware de micro:bit](https://tech.microbit." +"org/hardware/)." #: src/exercises/bare-metal/compass.md:11 msgid "" "The LSM303AGR Inertial Measurement Unit is connected to the internal I2C bus." msgstr "" +"La unidad de medición inercial LSM303AGR está conectada al bus I2C interno." #: src/exercises/bare-metal/compass.md:12 msgid "" "TWI is another name for I2C, so the I2C master peripheral is called TWIM." msgstr "" +"TWI es otro nombre para I2C, por lo que el periférico I2C maestro se llama " +"TWIM." #: src/exercises/bare-metal/compass.md:13 msgid "" @@ -14267,12 +14704,19 @@ msgid "" "blocking::i2c::WriteRead` trait. The [`microbit::hal::Twim`](https://docs.rs/" "microbit-v2/latest/microbit/hal/struct.Twim.html) struct implements this." msgstr "" +"El controlador LSM303AGR necesita algo que implemente el trait " +"`embedded_hal::blocking::i2c::WriteRead`. La estructura [`microbit::hal::" +"Twim`](https://docs.rs/microbit-v2/latest/microbit/hal/struct.Twim.html) " +"implementa esto." #: src/exercises/bare-metal/compass.md:17 msgid "" "You have a [`microbit::Board`](https://docs.rs/microbit-v2/latest/microbit/" "struct.Board.html) struct with fields for the various pins and peripherals." msgstr "" +"Tienes una estructura [`microbit::Board`](https://docs.rs/microbit-v2/latest/" +"microbit/struct.Board.html) con campos para los distintos pines y " +"periféricos." #: src/exercises/bare-metal/compass.md:19 msgid "" @@ -14280,16 +14724,21 @@ msgid "" "com/pdf/nRF52833_PS_v1.5.pdf) if you want, but it shouldn't be necessary for " "this exercise." msgstr "" +"También puedes consultar la \\[hoja de datos nRF52833\\][nRF52833 datasheet]" +"(https://infocenter.nordicsemi.com/pdf/nRF52833_PS_v1.5.pdf) si quieres, " +"pero no debería ser necesario para este ejercicio." #: src/exercises/bare-metal/compass.md:23 msgid "" "Download the [exercise template](../../comprehensive-rust-exercises.zip) and " "look in the `compass` directory for the following files." msgstr "" +"Descarga la [plantilla de ejercicio](../../comprehensive-rust-exercises.zip) " +"y busca los siguientes archivos en el directorio `compass`." #: src/exercises/bare-metal/compass.md:26 src/exercises/bare-metal/rtc.md:19 msgid "`src/main.rs`:" -msgstr "" +msgstr "`src/main.rs`:" #: src/exercises/bare-metal/compass.md:30 msgid "" @@ -14327,10 +14776,43 @@ msgid "" "}\n" "```" msgstr "" +"```rust,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"extern crate panic_halt as _;\n" +"\n" +"use core::fmt::Write;\n" +"use cortex_m_rt::entry;\n" +"use microbit::{hal::uarte::{Baudrate, Parity, Uarte}, Board};\n" +"\n" +"#[entry]\n" +"fn main() -> ! {\n" +" let board = Board::take().unwrap();\n" +"\n" +" // Configure serial port.\n" +" let mut serial = Uarte::new(\n" +" board.UARTE0,\n" +" board.uart.into(),\n" +" Parity::EXCLUDED,\n" +" Baudrate::BAUD115200,\n" +" );\n" +"\n" +" // Set up the I2C controller and Inertial Measurement Unit.\n" +" // TODO\n" +"\n" +" writeln!(serial, \"Ready.\").unwrap();\n" +"\n" +" loop {\n" +" // Read compass data and log it to the serial port.\n" +" // TODO\n" +" }\n" +"}\n" +"```" #: src/exercises/bare-metal/compass.md:64 src/exercises/bare-metal/rtc.md:385 msgid "`Cargo.toml` (you shouldn't need to change this):" -msgstr "" +msgstr "`Cargo.toml` (no debería ser necesario cambiarlo):" #: src/exercises/bare-metal/compass.md:68 msgid "" @@ -14351,10 +14833,26 @@ msgid "" "panic-halt = \"0.2.0\"\n" "```" msgstr "" +"```toml\n" +"[workspace]\n" +"\n" +"[package]\n" +"name = \"compass\"\n" +"version = \"0.1.0\"\n" +"edition = \"2021\"\n" +"publish = false\n" +"\n" +"[dependencies]\n" +"cortex-m-rt = \"0.7.3\"\n" +"embedded-hal = \"0.2.6\"\n" +"lsm303agr = \"0.2.2\"\n" +"microbit-v2 = \"0.13.0\"\n" +"panic-halt = \"0.2.0\"\n" +"```" #: src/exercises/bare-metal/compass.md:85 msgid "`Embed.toml` (you shouldn't need to change this):" -msgstr "" +msgstr "`Embed.toml` (no debería ser necesario cambiarlo):" #: src/exercises/bare-metal/compass.md:89 msgid "" @@ -14369,10 +14867,20 @@ msgid "" "halt_afterwards = true\n" "```" msgstr "" +"```toml\n" +"[default.general]\n" +"chip = \"nrf52833_xxAA\"\n" +"\n" +"[debug.gdb]\n" +"enabled = true\n" +"\n" +"[debug.reset]\n" +"halt_afterwards = true\n" +"```" #: src/exercises/bare-metal/compass.md:100 src/exercises/bare-metal/rtc.md:985 msgid "`.cargo/config.toml` (you shouldn't need to change this):" -msgstr "" +msgstr "`.cargo/config.toml` (no debería ser necesario cambiarlo):" #: src/exercises/bare-metal/compass.md:104 msgid "" @@ -14384,10 +14892,17 @@ msgid "" "rustflags = [\"-C\", \"link-arg=-Tlink.x\"]\n" "```" msgstr "" +"```toml\n" +"[build]\n" +"target = \"thumbv7em-none-eabihf\" # Cortex-M4F\n" +"\n" +"[target.'cfg(all(target_arch = \"arm\", target_os = \"none\"))']\n" +"rustflags = [\"-C\", \"link-arg=-Tlink.x\"]\n" +"```" #: src/exercises/bare-metal/compass.md:112 msgid "See the serial output on Linux with:" -msgstr "" +msgstr "Consulta la salida de serie en Linux con:" #: src/exercises/bare-metal/compass.md:114 msgid "" @@ -14395,11 +14910,16 @@ msgid "" "picocom --baud 115200 --imap lfcrlf /dev/ttyACM0\n" "```" msgstr "" +"```sh\n" +"picocom --baud 115200 --imap lfcrlf /dev/ttyACM0\n" +"```" #: src/exercises/bare-metal/compass.md:118 msgid "" "Or on Mac OS something like (the device name may be slightly different):" msgstr "" +"En Mac OS debería ser algo como lo siguiente (el nombre del dispositivo " +"puede ser algo diferente):" #: src/exercises/bare-metal/compass.md:120 msgid "" @@ -14407,14 +14927,17 @@ msgid "" "picocom --baud 115200 --imap lfcrlf /dev/tty.usbmodem14502\n" "```" msgstr "" +"```sh\n" +"picocom --baud 115200 --imap lfcrlf /dev/tty.usbmodem14502\n" +"```" #: src/exercises/bare-metal/compass.md:124 msgid "Use Ctrl+A Ctrl+Q to quit picocom." -msgstr "" +msgstr "Pulsa Ctrl+A Ctrl+Q para salir de Picocom." #: src/bare-metal/aps.md:1 msgid "Application processors" -msgstr "" +msgstr "Procesadores de aplicaciones" #: src/bare-metal/aps.md:3 msgid "" @@ -14423,6 +14946,10 @@ msgid "" "with QEMU's aarch64 ['virt'](https://qemu-project.gitlab.io/qemu/system/arm/" "virt.html) board." msgstr "" +"Hasta ahora hemos hablado de microcontroladores, como la serie Cortex‐M de " +"Arm. Ahora vamos a probar a escribir algo para Cortex-A. Para simplificar, " +"solo trabajaremos con la placa ['virt'](https://qemu-project.gitlab.io/qemu/" +"system/arm/virt.html) aarch64 de QEMU." #: src/bare-metal/aps.md:9 msgid "" @@ -14430,6 +14957,9 @@ msgid "" "privilege (exception levels on Arm CPUs, rings on x86), while application " "processors do." msgstr "" +"En términos generales, los microcontroladores no tienen un MMU ni varios " +"niveles de privilegio (niveles de excepción en las CPU de Arm, anillos en " +"x86), mientras que los procesadores de aplicaciones sí los tienen." #: src/bare-metal/aps.md:11 msgid "" @@ -14437,11 +14967,16 @@ msgid "" "architecture. The 'virt' board doesn't correspond to any particular real " "hardware, but is designed purely for virtual machines." msgstr "" +"QEMU permite emular varias máquinas o modelos de placa diferentes para cada " +"arquitectura. La placa \"virt\" no se corresponde con ningún hardware real " +"concreto, pero está diseñada exclusivamente para máquinas virtuales." #: src/bare-metal/aps/entry-point.md:3 msgid "" "Before we can start running Rust code, we need to do some initialisation." msgstr "" +"Antes de que podamos empezar a ejecutar código de Rust, tenemos que hacer " +"alguna inicialización." #: src/bare-metal/aps/entry-point.md:5 msgid "" @@ -14518,33 +15053,116 @@ msgid "" " b 2b\n" "```" msgstr "" - -#: src/bare-metal/aps/entry-point.md:77 -msgid "" -"This is the same as it would be for C: initialising the processor state, " -"zeroing the BSS, and setting up the stack pointer." -msgstr "" - -#: src/bare-metal/aps/entry-point.md:79 -msgid "" +"```armasm\n" +".section .init.entry, \"ax\"\n" +".global entry\n" +"entry:\n" +" /*\n" +" * Load and apply the memory management configuration, ready to enable " +"MMU and\n" +" * caches.\n" +" */\n" +" adrp x30, idmap\n" +" msr ttbr0_el1, x30\n" +"\n" +" mov_i x30, .Lmairval\n" +" msr mair_el1, x30\n" +"\n" +" mov_i x30, .Ltcrval\n" +" /* Copy the supported PA range into TCR_EL1.IPS. */\n" +" mrs x29, id_aa64mmfr0_el1\n" +" bfi x30, x29, #32, #4\n" +"\n" +" msr tcr_el1, x30\n" +"\n" +" mov_i x30, .Lsctlrval\n" +"\n" +" /*\n" +" * Ensure everything before this point has completed, then invalidate " +"any\n" +" * potentially stale local TLB entries before they start being used.\n" +" */\n" +" isb\n" +" tlbi vmalle1\n" +" ic iallu\n" +" dsb nsh\n" +" isb\n" +"\n" +" /*\n" +" * Configure sctlr_el1 to enable MMU and cache and don't proceed until " +"this\n" +" * has completed.\n" +" */\n" +" msr sctlr_el1, x30\n" +" isb\n" +"\n" +" /* Disable trapping floating point access in EL1. */\n" +" mrs x30, cpacr_el1\n" +" orr x30, x30, #(0x3 << 20)\n" +" msr cpacr_el1, x30\n" +" isb\n" +"\n" +" /* Zero out the bss section. */\n" +" adr_l x29, bss_begin\n" +" adr_l x30, bss_end\n" +"0: cmp x29, x30\n" +" b.hs 1f\n" +" stp xzr, xzr, [x29], #16\n" +" b 0b\n" +"\n" +"1: /* Prepare the stack. */\n" +" adr_l x30, boot_stack_end\n" +" mov sp, x30\n" +"\n" +" /* Set up exception vector. */\n" +" adr x30, vector_table_el1\n" +" msr vbar_el1, x30\n" +"\n" +" /* Call into Rust code. */\n" +" bl main\n" +"\n" +" /* Loop forever waiting for interrupts. */\n" +"2: wfi\n" +" b 2b\n" +"```" + +#: src/bare-metal/aps/entry-point.md:77 +msgid "" +"This is the same as it would be for C: initialising the processor state, " +"zeroing the BSS, and setting up the stack pointer." +msgstr "" +"Es lo mismo que en C: inicializar el estado del procesador, poner a cero el " +"BSS y configurar el puntero de la pila." + +#: src/bare-metal/aps/entry-point.md:79 +msgid "" "The BSS (block starting symbol, for historical reasons) is the part of the " "object file which containing statically allocated variables which are " "initialised to zero. They are omitted from the image, to avoid wasting space " "on zeroes. The compiler assumes that the loader will take care of zeroing " "them." msgstr "" +"El BSS (símbolo de inicio del bloque, por motivos históricos) es la parte " +"del objeto que contiene variables asignadas de forma estática que se " +"inicializan a cero. Se omiten en la imagen para evitar malgastar espacio con " +"ceros. El compilador asume que el cargador se encargará de ponerlos a cero." #: src/bare-metal/aps/entry-point.md:83 msgid "" "The BSS may already be zeroed, depending on how memory is initialised and " "the image is loaded, but we zero it to be sure." msgstr "" +"Es posible que el BSS ya esté a cero, dependiendo de cómo se inicialice la " +"memoria y cómo se cargue la imagen, aunque se pone igualmente a cero para " +"estar seguros." #: src/bare-metal/aps/entry-point.md:85 msgid "" "We need to enable the MMU and cache before reading or writing any memory. If " "we don't:" msgstr "" +"Necesitamos habilitar la MMU y la caché antes de leer o escribir memoria. Si " +"no lo hacemos, sucederá lo siguiente:" #: src/bare-metal/aps/entry-point.md:86 msgid "" @@ -14553,6 +15171,10 @@ msgid "" "generating unaligned accesses, so it should be fine in this case, but this " "is not necessarily the case in general." msgstr "" +"Los accesos no alineados fallarán. Compilamos el código Rust para el " +"objetivo `aarch64-unknown-none`, que define `+strict-align` para evitar que " +"el compilador genere accesos no alineados. En este caso debería estar bien, " +"pero no tiene por qué ser así en general." #: src/bare-metal/aps/entry-point.md:89 msgid "" @@ -14564,6 +15186,14 @@ msgid "" "is cleaned or the VM enables the cache. (Cache is keyed by physical address, " "not VA or IPA.)" msgstr "" +"Si se estuviera ejecutando en una máquina virtual, podría provocar problemas " +"de coherencia en la caché. El problema es que la máquina virtual accede a la " +"memoria directamente con la caché inhabilitada, mientras que el host cuenta " +"con alias que se pueden almacenar en caché en la misma memoria. Incluso si " +"el host no accede explícitamente a la memoria, los accesos especulativos " +"pueden provocar que se llene la caché, haciendo que los cambios de uno u " +"otro se pierdan cuando se borre la caché o cuando la máquina virtual la " +"habilite. (La caché está codificada por dirección física, no por VA ni IPA)." #: src/bare-metal/aps/entry-point.md:94 msgid "" @@ -14572,12 +15202,18 @@ msgid "" "for DRAM, and another 1 GiB higher up for more devices. This matches the " "memory layout that QEMU uses." msgstr "" +"Para simplificar, solo se utiliza una tabla de páginas codificada (consulta " +"`idmap.S`) que mapea la identidad del primer GiB de espacio de direcciones " +"para dispositivos, el siguiente GiB para DRAM y otro GiB más para más " +"dispositivos. Esto coincide con la disposición de memoria que utiliza QEMU." #: src/bare-metal/aps/entry-point.md:97 msgid "" "We also set up the exception vector (`vbar_el1`), which we'll see more about " "later." msgstr "" +"También configuramos el vector de excepción (`vbar_el1`), del que veremos " +"más contenido en próximas dipositivas." #: src/bare-metal/aps/entry-point.md:98 msgid "" @@ -14585,24 +15221,29 @@ msgid "" "(EL1). If you need to run at a different exception level you'll need to " "modify `entry.S` accordingly." msgstr "" +"Todos los ejemplos de esta tarde se ejecutarán en el nivel de excepción 1 " +"(EL1). Si necesitas ejecutar en un nivel de excepción diferente, deberás " +"modificar `entry.S` según corresponda." #: src/bare-metal/aps/inline-assembly.md:1 msgid "Inline assembly" -msgstr "" +msgstr "Ensamblaje integrado" #: 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, to make an " msgstr "" +"A veces necesitamos usar el ensamblador para hacer cosas que no son posibles " +"con código Rust. Por ejemplo, hacer un " #: src/bare-metal/aps/inline-assembly.md:4 msgid "HVC" -msgstr "" +msgstr "HVC" #: src/bare-metal/aps/inline-assembly.md:4 msgid " to tell the firmware to power off the system:" -msgstr "" +msgstr " para decirle al firmware que apague el sistema:" #: src/bare-metal/aps/inline-assembly.md:6 msgid "" @@ -14639,12 +15280,46 @@ msgid "" "}\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`](https://crates.io/crates/" -"smccc) crate which has wrappers for all these functions.)" +"(If you actually want to do this, use the \\[`smccc`\\]\\[1\\] crate which " +"has wrappers for all these functions.)" msgstr "" +"(Si realmente quieres hacer esto, utiliza el crate \\[`smccc`\\]\\[1\\] que " +"tiene envoltorios para todas estas funciones)." #: src/bare-metal/aps/inline-assembly.md:43 msgid "" @@ -14652,6 +15327,10 @@ msgid "" "functions to manage system and CPU power states, among other things. It is " "implemented by EL3 firmware and hypervisors on many systems." msgstr "" +"PSCI es la interfaz de coordinación de estado de alimentación de Arm, un " +"conjunto estándar de funciones para gestionar los estados de alimentación " +"del sistema y de la CPU, entre otras cosas. Lo implementan el firmware EL3 y " +"los hipervisores en muchos sistemas." #: src/bare-metal/aps/inline-assembly.md:46 msgid "" @@ -14660,12 +15339,18 @@ msgid "" "`inout` rather than `in` because the call could potentially clobber the " "contents of the registers." msgstr "" +"La sintaxis `0 => _` significa inicializar el registro a 0 antes de ejecutar " +"el código de ensamblaje integrado e ignorar su contenido después. " +"Necesitamos utilizar `inout` en lugar de `in` porque la llamada podría " +"alterar el contenido de los registros." #: src/bare-metal/aps/inline-assembly.md:49 msgid "" "This `main` function needs to be `#[no_mangle]` and `extern \"C\"` because " "it is called from our entry point in `entry.S`." msgstr "" +"Esta función `main` debe ser `#[no_mangle]` y `extern \"C\"`, ya que se " +"llama desde nuestro punto de entrada en `entry.S`." #: src/bare-metal/aps/inline-assembly.md:51 msgid "" @@ -14676,36 +15361,50 @@ msgid "" "arguments passed to a function, so `entry.S` doesn't need to do anything " "special except make sure it doesn't change these registers." msgstr "" +"`_x0`–`_x3` son los valores de los registros `x0`–`x3`, que el bootloader " +"utiliza habitualmente para pasar elementos al árbol de dispositivos, como un " +"puntero. De acuerdo con la convención de llamadas estándar de aarch64 (que " +"es lo que `extern \"C\"` usa), los registros `x0`–`x7` se utilizan para los " +"primeros ocho argumentos que se pasan a una función, de modo que `entry.S` " +"no tiene que hacer nada especial, salvo asegurarse de que no cambia estos " +"registros." #: src/bare-metal/aps/inline-assembly.md:56 msgid "" "Run the example in QEMU with `make qemu_psci` under `src/bare-metal/aps/" "examples`." msgstr "" +"Ejecuta el ejemplo en QEMU con `make qemu_psci` en `src/bare-metal/aps/" +"examples`." #: src/bare-metal/aps/mmio.md:1 msgid "Volatile memory access for MMIO" -msgstr "" +msgstr "Acceso a la memoria volátil para MMIO" #: src/bare-metal/aps/mmio.md:3 msgid "Use `pointer::read_volatile` and `pointer::write_volatile`." -msgstr "" +msgstr "Se puede usar `pointer::read_volatile` y `pointer::write_volatile`." #: src/bare-metal/aps/mmio.md:4 msgid "Never hold a reference." -msgstr "" +msgstr "Nunca retengas una referencia." #: src/bare-metal/aps/mmio.md:5 msgid "" "`addr_of!` lets you get fields of structs without creating an intermediate " "reference." msgstr "" +"`addr_of!` permite obtener campos de estructuras sin crear una referencia " +"intermedia." #: src/bare-metal/aps/mmio.md:9 msgid "" "Volatile access: read or write operations may have side-effects, so prevent " "the compiler or hardware from reordering, duplicating or eliding them." msgstr "" +"Acceso volátil: las operaciones de lectura o escritura pueden tener efectos " +"secundarios, por lo que se debe evitar que el compilador o el hardware las " +"reordene, duplique u omita." #: src/bare-metal/aps/mmio.md:11 msgid "" @@ -14713,6 +15412,10 @@ msgid "" "compiler may assume that the value read is the same as the value just " "written, and not bother actually reading memory." msgstr "" +"Normalmente, si escribes y luego lees (por ejemplo, a través de una " +"referencia mutable), el compilador puede suponer que el valor leído es el " +"mismo que el que se acaba de escribir, sin molestarse si quiera en leer " +"realmente la memoria." #: src/bare-metal/aps/mmio.md:13 msgid "" @@ -14720,22 +15423,29 @@ msgid "" "this is unsound. Whenever a reference exist, the compiler may choose to " "dereference it." msgstr "" +"Algunos crates para el acceso volátil al hardware sí mantienen referencias, " +"aunque no es seguro. Siempre que exista una referencia, el compilador puede " +"desreferenciarla." #: src/bare-metal/aps/mmio.md:15 msgid "" "Use the `addr_of!` macro to get struct field pointers from a pointer to the " "struct." msgstr "" +"Utiliza la macro `addr_of!` para obtener punteros de campos de estructuras a " +"partir de un puntero en la estructura." #: src/bare-metal/aps/uart.md:1 msgid "Let's write a UART driver" -msgstr "" +msgstr "Vamos a escribir un controlador de UART" #: src/bare-metal/aps/uart.md:3 msgid "" -"The QEMU 'virt' machine has a [PL011](https://developer.arm.com/" -"documentation/ddi0183/g) UART, so let's write a driver for that." +"The QEMU 'virt' machine has a \\[PL011\\]\\[1\\] UART, so let's write a " +"driver for that." msgstr "" +"La máquina \"virt\" de QEMU tiene una UART \\[PL011\\]\\[1\\], así que vamos " +"a escribir un controlador para ella." #: src/bare-metal/aps/uart.md:5 msgid "" @@ -14791,6 +15501,57 @@ msgid "" "}\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" +"/// 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" +"```" #: src/bare-metal/aps/uart.md:55 msgid "" @@ -14801,6 +15562,13 @@ msgid "" "it is always safe to call `write_byte` later because we can assume the " "necessary preconditions." msgstr "" +"Ten en cuenta que `Uart::new` no es seguro, mientras que los otros métodos " +"sí lo son. Esto se debe a que mientras que el llamador de `Uart::new` " +"asegure que se cumplan sus requisitos de seguridad (es decir, que solo haya " +"una instancia del controlador para una UART determinada y que nada más " +"asigne alias a su espacio de direcciones), siempre es más seguro llamar a " +"`write_byte` más adelante, ya que podemos asumir\\ las condiciones previas " +"necesarias." #: src/bare-metal/aps/uart.md:60 msgid "" @@ -14808,6 +15576,9 @@ msgid "" "`write_byte` unsafe), but that would be much less convenient to use as every " "place that calls `write_byte` would need to reason about the safety" msgstr "" +"Podríamos haberlo hecho al revés (haciendo que `new` fuese seguro y " +"`write_byte` no seguro), pero\\sería mucho menos cómodo de usar, ya que cada " +"lugar que llamase a `write_byte` tendría que pensar en la seguridad" #: src/bare-metal/aps/uart.md:63 msgid "" @@ -14815,16 +15586,21 @@ msgid "" "the burden of proof for soundness from a large number of places to a smaller " "number of places." msgstr "" +"Este es un patrón común para escribir envoltorios seguros de código " +"inseguro: mover la carga de la prueba de seguridad de un gran número de " +"lugares a otro más pequeño." #: src/bare-metal/aps/uart/traits.md:1 msgid "More traits" -msgstr "" +msgstr "Más traits" #: src/bare-metal/aps/uart/traits.md:3 msgid "" "We derived the `Debug` trait. It would be useful to implement a few more " "traits too." msgstr "" +"Hemos derivado el trait `Debug`. También sería útil implementar algunos " +"traits más." #: src/bare-metal/aps/uart/traits.md:5 msgid "" @@ -14845,198 +15621,223 @@ msgid "" "unsafe impl Send for Uart {}\n" "```" msgstr "" +"```rust,editable,compile_fail\n" +"use core::fmt::{self, Write};\n" +"\n" +"impl Write for Uart {\n" +" fn write_str(&mut self, s: &str) -> fmt::Result {\n" +" for c in s.as_bytes() {\n" +" self.write_byte(*c);\n" +" }\n" +" Ok(())\n" +" }\n" +"}\n" +"\n" +"// Safe because it just contains a pointer to device memory, which can be\n" +"// accessed from any context.\n" +"unsafe impl Send for Uart {}\n" +"```" #: src/bare-metal/aps/uart/traits.md:24 msgid "" "Implementing `Write` lets us use the `write!` and `writeln!` macros with our " "`Uart` type." msgstr "" +"Implementar `Write` nos permite utilizar las macros `write!` y `writeln!` " +"con nuestro tipo `Uart`." #: src/bare-metal/aps/uart/traits.md:25 msgid "" "Run the example in QEMU with `make qemu_minimal` under `src/bare-metal/aps/" "examples`." msgstr "" +"Ejecuta el ejemplo en QEMU con `make qemu_minimal` en `src/bare-metal/aps/" +"examples`." #: src/bare-metal/aps/better-uart.md:1 msgid "A better UART driver" -msgstr "" +msgstr "Un controlador UART mejor" #: src/bare-metal/aps/better-uart.md:3 msgid "" -"The PL011 actually has [a bunch more registers](https://developer.arm.com/" -"documentation/ddi0183/g/programmers-model/summary-of-registers), and adding " +"The PL011 actually has \\[a bunch more registers\\]\\[1\\], and adding " "offsets to construct pointers to access them is error-prone and hard to " "read. Plus, some of them are bit fields which would be nice to access in a " "structured way." msgstr "" +"En realidad, PL011 tiene \\[muchos registros más\\]\\[1\\], por lo que " +"añadir desplazamientos para crear punteros que les permita acceder a ellos " +"da lugar a errores y dificulta la lectura. Además, algunos de ellos son " +"campos de bits a los que estaría bien acceder de forma estructurada." #: src/bare-metal/aps/better-uart.md:7 msgid "Offset" -msgstr "" +msgstr "Desplazamiento" #: src/bare-metal/aps/better-uart.md:7 msgid "Register name" -msgstr "" +msgstr "Nombre de registro" #: src/bare-metal/aps/better-uart.md:7 msgid "Width" -msgstr "" +msgstr "Ancho" #: src/bare-metal/aps/better-uart.md:9 msgid "0x00" -msgstr "" +msgstr "0x00" #: src/bare-metal/aps/better-uart.md:9 msgid "DR" -msgstr "" +msgstr "DR" #: src/bare-metal/aps/better-uart.md:9 msgid "12" -msgstr "" +msgstr "12" #: src/bare-metal/aps/better-uart.md:10 msgid "0x04" -msgstr "" +msgstr "0x04" #: src/bare-metal/aps/better-uart.md:10 msgid "RSR" -msgstr "" +msgstr "RSR" #: src/bare-metal/aps/better-uart.md:10 msgid "4" -msgstr "" +msgstr "4" #: src/bare-metal/aps/better-uart.md:11 msgid "0x18" -msgstr "" +msgstr "0x18" #: src/bare-metal/aps/better-uart.md:11 msgid "FR" -msgstr "" +msgstr "FR" #: src/bare-metal/aps/better-uart.md:11 msgid "9" -msgstr "" +msgstr "9" #: src/bare-metal/aps/better-uart.md:12 msgid "0x20" -msgstr "" +msgstr "0x20" #: src/bare-metal/aps/better-uart.md:12 msgid "ILPR" -msgstr "" +msgstr "ILPR" #: src/bare-metal/aps/better-uart.md:12 src/bare-metal/aps/better-uart.md:15 msgid "8" -msgstr "" +msgstr "8" #: src/bare-metal/aps/better-uart.md:13 msgid "0x24" -msgstr "" +msgstr "0x24" #: src/bare-metal/aps/better-uart.md:13 msgid "IBRD" -msgstr "" +msgstr "IBRD" #: src/bare-metal/aps/better-uart.md:13 src/bare-metal/aps/better-uart.md:16 msgid "16" -msgstr "" +msgstr "16" #: src/bare-metal/aps/better-uart.md:14 msgid "0x28" -msgstr "" +msgstr "0x28" #: src/bare-metal/aps/better-uart.md:14 msgid "FBRD" -msgstr "" +msgstr "FBRD" #: src/bare-metal/aps/better-uart.md:14 src/bare-metal/aps/better-uart.md:17 msgid "6" -msgstr "" +msgstr "6" #: src/bare-metal/aps/better-uart.md:15 msgid "0x2c" -msgstr "" +msgstr "0x2c" #: src/bare-metal/aps/better-uart.md:15 msgid "LCR_H" -msgstr "" +msgstr "LCR_H" #: src/bare-metal/aps/better-uart.md:16 msgid "0x30" -msgstr "" +msgstr "0x30" #: src/bare-metal/aps/better-uart.md:16 msgid "CR" -msgstr "" +msgstr "CR" #: src/bare-metal/aps/better-uart.md:17 msgid "0x34" -msgstr "" +msgstr "0x34" #: src/bare-metal/aps/better-uart.md:17 msgid "IFLS" -msgstr "" +msgstr "IFLS" #: src/bare-metal/aps/better-uart.md:18 msgid "0x38" -msgstr "" +msgstr "0x38" #: src/bare-metal/aps/better-uart.md:18 msgid "IMSC" -msgstr "" +msgstr "IMSC" #: src/bare-metal/aps/better-uart.md:18 src/bare-metal/aps/better-uart.md:19 #: src/bare-metal/aps/better-uart.md:20 src/bare-metal/aps/better-uart.md:21 msgid "11" -msgstr "" +msgstr "11" #: src/bare-metal/aps/better-uart.md:19 msgid "0x3c" -msgstr "" +msgstr "0x3c" #: src/bare-metal/aps/better-uart.md:19 msgid "RIS" -msgstr "" +msgstr "RIS" #: src/bare-metal/aps/better-uart.md:20 msgid "0x40" -msgstr "" +msgstr "0x40" #: src/bare-metal/aps/better-uart.md:20 msgid "MIS" -msgstr "" +msgstr "MIS" #: src/bare-metal/aps/better-uart.md:21 msgid "0x44" -msgstr "" +msgstr "0x44" #: src/bare-metal/aps/better-uart.md:21 msgid "ICR" -msgstr "" +msgstr "ICR" #: src/bare-metal/aps/better-uart.md:22 msgid "0x48" -msgstr "" +msgstr "0x48" #: src/bare-metal/aps/better-uart.md:22 msgid "DMACR" -msgstr "" +msgstr "DMACR" #: src/bare-metal/aps/better-uart.md:22 msgid "3" -msgstr "" +msgstr "3" #: src/bare-metal/aps/better-uart.md:26 msgid "There are also some ID registers which have been omitted for brevity." -msgstr "" +msgstr "También hay algunos registros de ID que se han omitido para abreviar." #: src/bare-metal/aps/better-uart/bitflags.md:3 msgid "" "The [`bitflags`](https://crates.io/crates/bitflags) crate is useful for " "working with bitflags." msgstr "" +"El crate [`bitflags`](https://crates.io/crates/bitflags) resulta útil para " +"trabajar con bitflags." #: src/bare-metal/aps/better-uart/bitflags.md:5 msgid "" @@ -15070,32 +15871,65 @@ msgid "" "}\n" "```" msgstr "" - -#: src/bare-metal/aps/better-uart/bitflags.md:37 -msgid "" -"The `bitflags!` macro creates a newtype something like `Flags(u16)`, along " -"with a bunch of method implementations to get and set flags." -msgstr "" - -#: src/bare-metal/aps/better-uart/registers.md:1 -msgid "Multiple registers" -msgstr "" - -#: src/bare-metal/aps/better-uart/registers.md:3 -msgid "" -"We can use a struct to represent the memory layout of the UART's registers." -msgstr "" - -#: src/bare-metal/aps/better-uart/registers.md:5 -msgid "" "```rust,editable,compile_fail\n" -"#[repr(C, align(4))]\n" -"struct Registers {\n" -" dr: u16,\n" -" _reserved0: [u8; 2],\n" -" rsr: ReceiveStatus,\n" -" _reserved1: [u8; 19],\n" -" fr: Flags,\n" +"use bitflags::bitflags;\n" +"\n" +"bitflags! {\n" +" /// Flags from the UART flag register.\n" +" #[repr(transparent)]\n" +" #[derive(Copy, Clone, Debug, Eq, PartialEq)]\n" +" struct Flags: u16 {\n" +" /// Clear to send.\n" +" const CTS = 1 << 0;\n" +" /// Data set ready.\n" +" const DSR = 1 << 1;\n" +" /// Data carrier detect.\n" +" const DCD = 1 << 2;\n" +" /// UART busy transmitting data.\n" +" const BUSY = 1 << 3;\n" +" /// Receive FIFO is empty.\n" +" const RXFE = 1 << 4;\n" +" /// Transmit FIFO is full.\n" +" const TXFF = 1 << 5;\n" +" /// Receive FIFO is full.\n" +" const RXFF = 1 << 6;\n" +" /// Transmit FIFO is empty.\n" +" const TXFE = 1 << 7;\n" +" /// Ring indicator.\n" +" const RI = 1 << 8;\n" +" }\n" +"}\n" +"```" + +#: src/bare-metal/aps/better-uart/bitflags.md:37 +msgid "" +"The `bitflags!` macro creates a newtype something like `Flags(u16)`, along " +"with a bunch of method implementations to get and set flags." +msgstr "" +"La macro `bitflags!` crea un newtype, como `Flags(u16)`, junto con un montón " +"de implementaciones de métodos para obtener y definir banderas." + +#: src/bare-metal/aps/better-uart/registers.md:1 +msgid "Multiple registers" +msgstr "Varios registros" + +#: src/bare-metal/aps/better-uart/registers.md:3 +msgid "" +"We can use a struct to represent the memory layout of the UART's registers." +msgstr "" +"Podemos utilizar una estructura para representar la disposición de la " +"memoria de los registros de UART." + +#: src/bare-metal/aps/better-uart/registers.md:5 +msgid "" +"```rust,editable,compile_fail\n" +"#[repr(C, align(4))]\n" +"struct Registers {\n" +" dr: u16,\n" +" _reserved0: [u8; 2],\n" +" rsr: ReceiveStatus,\n" +" _reserved1: [u8; 19],\n" +" fr: Flags,\n" " _reserved2: [u8; 6],\n" " ilpr: u8,\n" " _reserved3: [u8; 3],\n" @@ -15122,6 +15956,39 @@ msgid "" "}\n" "```" msgstr "" +"```rust,editable,compile_fail\n" +"#[repr(C, align(4))]\n" +"struct Registers {\n" +" dr: u16,\n" +" _reserved0: [u8; 2],\n" +" rsr: ReceiveStatus,\n" +" _reserved1: [u8; 19],\n" +" fr: Flags,\n" +" _reserved2: [u8; 6],\n" +" ilpr: u8,\n" +" _reserved3: [u8; 3],\n" +" ibrd: u16,\n" +" _reserved4: [u8; 2],\n" +" fbrd: u8,\n" +" _reserved5: [u8; 3],\n" +" lcr_h: u8,\n" +" _reserved6: [u8; 3],\n" +" cr: u16,\n" +" _reserved7: [u8; 3],\n" +" ifls: u8,\n" +" _reserved8: [u8; 3],\n" +" imsc: u16,\n" +" _reserved9: [u8; 2],\n" +" ris: u16,\n" +" _reserved10: [u8; 2],\n" +" mis: u16,\n" +" _reserved11: [u8; 2],\n" +" icr: u16,\n" +" _reserved12: [u8; 2],\n" +" dmacr: u8,\n" +" _reserved13: [u8; 3],\n" +"}\n" +"```" #: src/bare-metal/aps/better-uart/registers.md:41 msgid "" @@ -15131,10 +15998,18 @@ msgid "" "predictable layout, as default Rust representation allows the compiler to " "(among other things) reorder fields however it sees fit." msgstr "" +"[`#[repr(C)]`](https://doc.rust-lang.org/reference/type-layout.html#the-c-" +"representation) indica al compilador que ordene los campos de la estructura " +"siguiendo las mismas reglas que en C. Esto es necesario para que nuestra " +"estructura tenga un diseño predecible, ya que la representación " +"predeterminada de Rust permite que el compilador (entre otras cosas) " +"reordene los campos como crea conveniente." #: src/bare-metal/aps/better-uart/driver.md:3 msgid "Now let's use the new `Registers` struct in our driver." msgstr "" +"Ahora vamos a utilizar la nueva estructura de `Registers` en nuestro " +"controlador." #: src/bare-metal/aps/better-uart/driver.md:5 msgid "" @@ -15200,24 +16075,89 @@ msgid "" "}\n" "```" msgstr "" +"```rust,editable,compile_fail\n" +"/// Driver for a PL011 UART.\n" +"#[derive(Debug)]\n" +"pub struct Uart {\n" +" registers: *mut Registers,\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 u32) -> Self {\n" +" Self {\n" +" registers: base_address as *mut Registers,\n" +" }\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().contains(Flags::TXFF) {}\n" +"\n" +" // Safe because we know that self.registers points to the control\n" +" // registers of a PL011 device which is appropriately mapped.\n" +" unsafe {\n" +" // Write to the TX buffer.\n" +" addr_of_mut!((*self.registers).dr).write_volatile(byte.into());\n" +" }\n" +"\n" +" // Wait until the UART is no longer busy.\n" +" while self.read_flag_register().contains(Flags::BUSY) {}\n" +" }\n" +"\n" +" /// Reads and returns a pending byte, or `None` if nothing has been " +"received.\n" +" pub fn read_byte(&self) -> Option {\n" +" if self.read_flag_register().contains(Flags::RXFE) {\n" +" None\n" +" } else {\n" +" let data = unsafe { addr_of!((*self.registers).dr)." +"read_volatile() };\n" +" // TODO: Check for error conditions in bits 8-11.\n" +" Some(data as u8)\n" +" }\n" +" }\n" +"\n" +" fn read_flag_register(&self) -> Flags {\n" +" // Safe because we know that self.registers points to the control\n" +" // registers of a PL011 device which is appropriately mapped.\n" +" unsafe { addr_of!((*self.registers).fr).read_volatile() }\n" +" }\n" +"}\n" +"```" #: src/bare-metal/aps/better-uart/driver.md:64 msgid "" "Note the use of `addr_of!` / `addr_of_mut!` to get pointers to individual " "fields without creating an intermediate reference, which would be unsound." msgstr "" +"Fíjate en el uso de `addr_of!` y `addr_of_mut!` para llevar punteros a " +"campos individuales sin crear una referencia intermedia. Sería una acción " +"insegura." #: src/bare-metal/aps/better-uart/using.md:1 #: src/bare-metal/aps/logging/using.md:1 -#, fuzzy msgid "Using it" -msgstr "Usando Cargo" +msgstr "Uso" #: src/bare-metal/aps/better-uart/using.md:3 msgid "" "Let's write a small program using our driver to write to the serial console, " "and echo incoming bytes." msgstr "" +"Vamos a crear un pequeño programa con nuestro controlador para escribir en " +"la consola serie y compartir los bytes entrantes." #: src/bare-metal/aps/better-uart/using.md:6 msgid "" @@ -15265,6 +16205,49 @@ msgid "" "}\n" "```" msgstr "" +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"mod exceptions;\n" +"mod pl011;\n" +"\n" +"use crate::pl011::Uart;\n" +"use core::fmt::Write;\n" +"use core::panic::PanicInfo;\n" +"use log::error;\n" +"use smccc::psci::system_off;\n" +"use smccc::Hvc;\n" +"\n" +"/// Base address of the primary PL011 UART.\n" +"const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {\n" +" // Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 " +"device,\n" +" // and nothing else accesses that address range.\n" +" let mut uart = unsafe { Uart::new(PL011_BASE_ADDRESS) };\n" +"\n" +" writeln!(uart, \"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\").unwrap();\n" +"\n" +" loop {\n" +" if let Some(byte) = uart.read_byte() {\n" +" uart.write_byte(byte);\n" +" match byte {\n" +" b'\\r' => {\n" +" uart.write_byte(b'\\n');\n" +" }\n" +" b'q' => break,\n" +" _ => {}\n" +" }\n" +" }\n" +" }\n" +"\n" +" writeln!(uart, \"Bye!\").unwrap();\n" +" system_off::().unwrap();\n" +"}\n" +"```" #: src/bare-metal/aps/better-uart/using.md:51 msgid "" @@ -15272,18 +16255,23 @@ msgid "" "function is called from our entry point code in `entry.S`. See the speaker " "notes there for details." msgstr "" +"Al igual que en el ejemplo de [ensamblaje integrado](../inline-assembly.md), " +"esta función `main` se llama desde nuestro código de punto de entrada en " +"`entry.S`. Consulta las notas del orador para obtener más información." #: src/bare-metal/aps/better-uart/using.md:53 msgid "" "Run the example in QEMU with `make qemu` under `src/bare-metal/aps/examples`." msgstr "" +"Ejecuta el ejemplo en QEMU con `make qemu` en `src/bare-metal/aps/examples`." #: src/bare-metal/aps/logging.md:3 msgid "" -"It would be nice to be able to use the logging macros from the [`log`]" -"(https://crates.io/crates/log) crate. We can do this by implementing the " -"`Log` trait." +"It would be nice to be able to use the logging macros from the " +"\\[`log`\\]\\[1\\] crate. We can do this by implementing the `Log` trait." msgstr "" +"Estaría bien poder utilizar las macros de registro del crate " +"\\[`log`\\]\\[1\\]. Podemos hacerlo implementando el trait `Log`." #: src/bare-metal/aps/logging.md:6 msgid "" @@ -15330,16 +16318,60 @@ msgid "" "}\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" +"/// 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" +"```" #: src/bare-metal/aps/logging.md:50 msgid "" "The unwrap in `log` is safe because we initialise `LOGGER` before calling " "`set_logger`." msgstr "" +"La desenvoltura en `log` es segura porque inicializamos `LOGGER` antes de " +"llamar a `set_logger`." #: src/bare-metal/aps/logging/using.md:3 msgid "We need to initialise the logger before we use it." -msgstr "" +msgstr "Debemos inicializar el registrador antes de utilizarlo." #: src/bare-metal/aps/logging/using.md:5 msgid "" @@ -15383,26 +16415,74 @@ msgid "" "}\n" "```" msgstr "" - -#: src/bare-metal/aps/logging/using.md:46 -msgid "Note that our panic handler can now log details of panics." -msgstr "" - -#: src/bare-metal/aps/logging/using.md:47 -msgid "" -"Run the example in QEMU with `make qemu_logger` under `src/bare-metal/aps/" -"examples`." -msgstr "" - -#: src/bare-metal/aps/exceptions.md:3 -msgid "" -"AArch64 defines an exception vector table with 16 entries, for 4 types of " -"exceptions (synchronous, IRQ, FIQ, SError) from 4 states (current EL with " -"SP0, current EL with SPx, lower EL using AArch64, lower EL using AArch32). " -"We implement this in assembly to save volatile registers to the stack before " -"calling into Rust code:" -msgstr "" - +"```rust,editable,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"mod exceptions;\n" +"mod logger;\n" +"mod pl011;\n" +"\n" +"use crate::pl011::Uart;\n" +"use core::panic::PanicInfo;\n" +"use log::{error, info, LevelFilter};\n" +"use smccc::psci::system_off;\n" +"use smccc::Hvc;\n" +"\n" +"/// Base address of the primary PL011 UART.\n" +"const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {\n" +" // Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 " +"device,\n" +" // and nothing else accesses that address range.\n" +" let uart = unsafe { Uart::new(PL011_BASE_ADDRESS) };\n" +" logger::init(uart, LevelFilter::Trace).unwrap();\n" +"\n" +" info!(\"main({x0:#x}, {x1:#x}, {x2:#x}, {x3:#x})\");\n" +"\n" +" assert_eq!(x1, 42);\n" +"\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[panic_handler]\n" +"fn panic(info: &PanicInfo) -> ! {\n" +" error!(\"{info}\");\n" +" system_off::().unwrap();\n" +" loop {}\n" +"}\n" +"```" + +#: src/bare-metal/aps/logging/using.md:46 +msgid "Note that our panic handler can now log details of panics." +msgstr "" +"Ten en cuenta que nuestro controlador de pánico ahora ya puede registrar la " +"información de los pánicos." + +#: src/bare-metal/aps/logging/using.md:47 +msgid "" +"Run the example in QEMU with `make qemu_logger` under `src/bare-metal/aps/" +"examples`." +msgstr "" +"Ejecuta el ejemplo en QEMU con `make qemu_logger` en `src/bare-metal/aps/" +"examples`." + +#: src/bare-metal/aps/exceptions.md:3 +msgid "" +"AArch64 defines an exception vector table with 16 entries, for 4 types of " +"exceptions (synchronous, IRQ, FIQ, SError) from 4 states (current EL with " +"SP0, current EL with SPx, lower EL using AArch64, lower EL using AArch32). " +"We implement this in assembly to save volatile registers to the stack before " +"calling into Rust code:" +msgstr "" +"AArch64 define una tabla de vectores de excepción con 16 entradas, para 4 " +"tipos de excepciones (synchronous, IRQ, FIQ, SError) desde 4 estados (EL " +"actual con SP0, EL actual con SPx, EL inferior con AArch64 y EL inferior con " +"AArch32). Implementamos esto en el ensamblaje para guardar los registros " +"volátiles en la pila antes de llamar al código de Rust:" + #: src/bare-metal/aps/exceptions.md:8 msgid "" "```rust,editable,compile_fail\n" @@ -15459,70 +16539,153 @@ msgid "" "}\n" "```" msgstr "" +"```rust,editable,compile_fail\n" +"use log::error;\n" +"use smccc::psci::system_off;\n" +"use smccc::Hvc;\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn sync_exception_current(_elr: u64, _spsr: u64) {\n" +" error!(\"sync_exception_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn irq_current(_elr: u64, _spsr: u64) {\n" +" error!(\"irq_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn fiq_current(_elr: u64, _spsr: u64) {\n" +" error!(\"fiq_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn serr_current(_elr: u64, _spsr: u64) {\n" +" error!(\"serr_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn sync_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"sync_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn irq_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"irq_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn fiq_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"fiq_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn serr_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"serr_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"```" #: src/bare-metal/aps/exceptions.md:64 msgid "EL is exception level; all our examples this afternoon run in EL1." msgstr "" +"EL significa nivel de excepción (por sus siglas en inglés); todos nuestros " +"ejemplos de esta tarde se ejecutan en EL1." #: src/bare-metal/aps/exceptions.md:65 msgid "" "For simplicity we aren't distinguishing between SP0 and SPx for the current " "EL exceptions, or between AArch32 and AArch64 for the lower EL exceptions." msgstr "" +"Para simplificar, no distinguimos entre SP0 y SPx para las excepciones del " +"EL actual, ni entre AArch32 y AArch64 para las excepciones de EL inferiores." #: src/bare-metal/aps/exceptions.md:67 msgid "" "For this example we just log the exception and power down, as we don't " "expect any of them to actually happen." msgstr "" +"En este ejemplo, nos limitaremos a registrar la excepción y a apagarla, ya " +"que no esperamos que se produzca ninguna." #: src/bare-metal/aps/exceptions.md:69 msgid "" "We can think of exception handlers and our main execution context more or " -"less like different threads. [`Send` and `Sync`](../../concurrency/send-sync." -"md) will control what we can share between them, just like with threads. For " -"example, if we want to share some value between exception handlers and the " -"rest of the program, and it's `Send` but not `Sync`, then we'll need to wrap " -"it in something like a `Mutex` and put it in a static." -msgstr "" +"less like different threads. \\[`Send` and `Sync`\\]\\[1\\] will control " +"what we can share between them, just like with threads. For example, if we " +"want to share some value between exception handlers and the rest of the " +"program, and it's `Send` but not `Sync`, then we'll need to wrap it in " +"something like a `Mutex` and put it in a static." +msgstr "" +"Podríamos pensar en los controladores de excepciones y en nuestro contexto " +"de ejecución principal como si fueran hilos diferentes. \\[`Send` y " +"`Sync`\\]\\[1\\] controlarán lo que podemos compartir entre ellos, igual que " +"con los hilos. Por ejemplo, si queremos compartir algún valor entre los " +"controladores de excepciones y el resto del programa, y es `Send`en vez de " +"`Sync`, necesitaremos envolverlo en un `Mutex`, por ejemplo, y ponerlo en un " +"estático." #: src/bare-metal/aps/other-projects.md:3 +#, fuzzy msgid "[oreboot](https://github.com/oreboot/oreboot)" -msgstr "" +msgstr "[oreboot](https://github.com/oreboot/oreboot)" #: src/bare-metal/aps/other-projects.md:4 +#, fuzzy msgid "\"coreboot without the C\"" -msgstr "" +msgstr "\"coreboot sin la C\"." #: src/bare-metal/aps/other-projects.md:5 +#, fuzzy msgid "Supports x86, aarch64 and RISC-V." -msgstr "" +msgstr "Compatible con x86, aarch64 y RISC-V." #: src/bare-metal/aps/other-projects.md:6 +#, fuzzy msgid "Relies on LinuxBoot rather than having many drivers itself." -msgstr "" +msgstr "Depende de LinuxBoot en lugar de tener controladores propios." #: src/bare-metal/aps/other-projects.md:7 +#, fuzzy msgid "" "[Rust RaspberryPi OS tutorial](https://github.com/rust-embedded/rust-" "raspberrypi-OS-tutorials)" msgstr "" +"\\[Tutorial del SO de Rust en RaspberryPi\\][Rust RaspberryPi OS tutorial]" +"(https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials)" #: src/bare-metal/aps/other-projects.md:8 +#, fuzzy msgid "" "Initialisation, UART driver, simple bootloader, JTAG, exception levels, " "exception handling, page tables" msgstr "" +"Inicialización, controlador de UART, bootloader sencillo, JTAG, niveles de " +"excepción, gestión de excepciones, tablas de páginas, etc." #: src/bare-metal/aps/other-projects.md:10 +#, fuzzy msgid "" "Some dodginess around cache maintenance and initialisation in Rust, not " "necessarily a good example to copy for production code." msgstr "" +"Algunas dudas sobre el mantenimiento de la caché y la inicialización en " +"Rust, aunque no es precisamente un buen ejemplo para copiar en código de " +"producción." #: src/bare-metal/aps/other-projects.md:12 +#, fuzzy msgid "[`cargo-call-stack`](https://crates.io/crates/cargo-call-stack)" msgstr "" +"[`cargo-call-stack`](https://crates.io/crates/cargo-call-stack) \\*Análisis " +"estático para determinar el uso máximo de la pila." #: src/bare-metal/aps/other-projects.md:13 msgid "Static analysis to determine maximum stack usage." @@ -15533,6 +16696,9 @@ msgid "" "The RaspberryPi OS tutorial runs Rust code before the MMU and caches are " "enabled. This will read and write memory (e.g. the stack). However:" msgstr "" +"El tutorial del sistema operativo en RaspberryPi ejecuta código de Rust " +"antes de que la MMU y las cachés se habiliten. De este modo, se leerá y " +"escribirá memoria (por ejemplo, la pila). Sin embargo:" #: src/bare-metal/aps/other-projects.md:19 msgid "" @@ -15541,6 +16707,10 @@ msgid "" "generating unaligned accesses so it should be alright, but this is not " "necessarily the case in general." msgstr "" +"Sin la MMU y la caché, los accesos no alineados fallarán. Se compila con " +"`aarch64-unknown-none`, que define `+strict-align` para evitar que el " +"compilador genere accesos no alineados. Debería estar bien, pero no tiene " +"por qué ser así, en general." #: src/bare-metal/aps/other-projects.md:22 msgid "" @@ -15552,23 +16722,35 @@ msgid "" "alright in this particular case (running directly on the hardware with no " "hypervisor), but isn't a good pattern in general." msgstr "" +"Si se estuviera ejecutando en una máquina virtual, podría provocar problemas " +"de coherencia en la caché. El problema es que la máquina virtual accede a la " +"memoria directamente con la caché inhabilitada, mientras que el host cuenta " +"con alias que se pueden almacenar en caché en la misma memoria. Incluso si " +"el host no accede explícitamente a la memoria, los accesos especulativos " +"pueden provocar que se llene la caché, haciendo que los cambios de uno u " +"otro se pierdan. De nuevo, es correcto en este caso particular (si se " +"ejecuta directamente en el hardware sin hipervisor) pero, por lo general, no " +"es un buen patrón." #: 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 "" +"A continuación, repasaremos algunos crates que resuelven ciertos problemas " +"comunes en la programación bare-metal." #: src/bare-metal/useful-crates/zerocopy.md:1 msgid "`zerocopy`" -msgstr "" +msgstr "`zerocopy`" #: src/bare-metal/useful-crates/zerocopy.md:3 msgid "" -"The [`zerocopy`](https://docs.rs/zerocopy/) crate (from Fuchsia) provides " -"traits and macros for safely converting between byte sequences and other " -"types." +"The \\[`zerocopy`\\]\\[1\\] crate (from Fuchsia) provides traits and macros " +"for safely converting between byte sequences and other types." msgstr "" +"El crate \\[`zerocopy`\\]\\[1\\] (de Fuchsia) proporciona traits y macros " +"para realizar conversiones seguras entre secuencias de bytes y otros tipos." #: src/bare-metal/useful-crates/zerocopy.md:6 msgid "" @@ -15606,6 +16788,39 @@ msgid "" "}\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 "" @@ -15613,12 +16828,19 @@ msgid "" "but can be useful for working with structures shared with hardware e.g. by " "DMA, or sent over some external interface." msgstr "" +"No es adecuado para MMIO (ya que no utiliza lecturas y escrituras " +"volátiles), pero puede ser útil para trabajar con estructuras compartidas " +"con hardware (por ejemplo, mediante DMA) o enviadas a través de alguna " +"interfaz externa." #: 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 converted from an untrusted sequence of bytes." msgstr "" +"`FromBytes` se puede implementar en tipos en los que cualquier patrón de " +"bytes es válido, por lo que se puede convertir de forma segura a partir de " +"una secuencia de bytes que no es fiable." #: src/bare-metal/useful-crates/zerocopy.md:47 msgid "" @@ -15626,11 +16848,16 @@ msgid "" "`RequestType` doesn't use all possible u32 values as discriminants, so not " "all byte patterns are valid." msgstr "" +"Si se intenta derivar `FromBytes` para estos tipos, se produciría un error, " +"pues `RequestType` no utiliza todos los valores u32 posibles como " +"discriminantes y, por tanto, todos los patrones de bytes son válidos." #: src/bare-metal/useful-crates/zerocopy.md:49 msgid "" "`zerocopy::byteorder` has types for byte-order aware numeric primitives." msgstr "" +"`zerocopy::byteorder` tiene tipos para primitivos numéricos conscientes del " +"orden de bytes." #: src/bare-metal/useful-crates/zerocopy.md:50 msgid "" @@ -15638,17 +16865,21 @@ msgid "" "zerocopy-example/`. (It won't run in the Playground because of the crate " "dependency.)" msgstr "" +"Ejecuta el ejemplo con `cargo run` en `src/bare-metal/useful-crates/zerocopy-" +"example/`. (No se ejecutará en el playground debido a la dependencia del " +"crate)." #: src/bare-metal/useful-crates/aarch64-paging.md:1 msgid "`aarch64-paging`" -msgstr "" +msgstr "`aarch64-paging`" #: src/bare-metal/useful-crates/aarch64-paging.md:3 msgid "" -"The [`aarch64-paging`](https://crates.io/crates/aarch64-paging) crate lets " -"you create page tables according to the AArch64 Virtual Memory System " -"Architecture." +"The \\[`aarch64-paging`\\]\\[1\\] crate lets you create page tables " +"according to the AArch64 Virtual Memory System Architecture." msgstr "" +"El crate \\[`aarch64-paging`\\]\\[1\\] permite crear tablas de páginas de " +"acuerdo con la arquitectura del sistema de memoria virtual AArch64." #: src/bare-metal/useful-crates/aarch64-paging.md:6 msgid "" @@ -15672,41 +16903,68 @@ msgid "" "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" +"// 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" +"```" #: 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 add." msgstr "" +"Por ahora, solo es compatible con EL1, pero debería ser sencillo añadir " +"compatibilidad con otros niveles de excepción." #: src/bare-metal/useful-crates/aarch64-paging.md:30 -msgid "" -"This is used in Android for the [Protected VM Firmware](https://cs.android." -"com/android/platform/superproject/+/master:packages/modules/Virtualization/" -"pvmfw/)." +msgid "This is used in Android for the \\[Protected VM Firmware\\]\\[2\\]." msgstr "" +"Se utiliza en Android para el \\[firmware de máquina virtual " +"protegida\\]\\[2\\]." #: src/bare-metal/useful-crates/aarch64-paging.md:31 msgid "" "There's no easy way to run this example, as it needs to run on real hardware " "or under QEMU." msgstr "" +"No hay una forma sencilla de ejecutar este ejemplo, ya que debe hacerse en " +"hardware real o en QEMU." #: src/bare-metal/useful-crates/buddy_system_allocator.md:1 msgid "`buddy_system_allocator`" -msgstr "" +msgstr "`buddy_system_allocator`" #: src/bare-metal/useful-crates/buddy_system_allocator.md:3 msgid "" -"[`buddy_system_allocator`](https://crates.io/crates/buddy_system_allocator) " -"is a third-party crate implementing a basic buddy system allocator. It can " -"be used both for [`LockedHeap`](https://docs.rs/buddy_system_allocator/0.9.0/" -"buddy_system_allocator/struct.LockedHeap.html) implementing [`GlobalAlloc`]" -"(https://doc.rust-lang.org/core/alloc/trait.GlobalAlloc.html) so you can use " -"the standard `alloc` crate (as we saw [before](../alloc.md)), or for " +"\\[`buddy_system_allocator`\\]\\[1\\] is a third-party crate implementing a " +"basic buddy system allocator. It can be used both for " +"\\[`LockedHeap`\\]\\[2\\] implementing \\[`GlobalAlloc`\\]\\[3\\] so you can " +"use the standard `alloc` crate (as we saw \\[before\\]\\[4\\]), or for " "allocating other address space. For example, we might want to allocate MMIO " "space for PCI BARs:" msgstr "" +"\\[`buddy_system_allocator`\\]\\[1\\] es un crate de terceros que implementa " +"un asignador básico del sistema buddy. Se puede utilizar tanto para " +"\\[`LockedHeap`\\]\\[2\\] implementando \\[`GlobalAlloc`\\]\\[3\\], de forma " +"que puedas usar el crate `alloc` estándar (tal y como vimos " +"\\[antes\\]\\[4\\]), o para asignar otro espacio de direcciones. Por " +"ejemplo, podríamos querer asignar espacio MMIO para los registros de " +"dirección base (BAR) de PCI:" #: src/bare-metal/useful-crates/buddy_system_allocator.md:8 msgid "" @@ -15726,10 +16984,25 @@ msgid "" "}\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." -msgstr "" +msgstr "Los BAR de PCI siempre tienen una alineación igual a su tamaño." #: src/bare-metal/useful-crates/buddy_system_allocator.md:27 msgid "" @@ -15737,19 +17010,27 @@ msgid "" "allocator-example/`. (It won't run in the Playground because of the crate " "dependency.)" msgstr "" +"Ejecuta el ejemplo con `cargo run` en `src/bare-metal/useful-crates/" +"allocator-example/`. (No se ejecutará en el playground debido a la " +"dependencia del crate)." #: src/bare-metal/useful-crates/tinyvec.md:1 msgid "`tinyvec`" -msgstr "" +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. [`tinyvec`](https://crates.io/crates/tinyvec) provides " -"this: a vector backed by an array or slice, which could be statically " -"allocated or on the stack, which keeps track of how many elements are used " -"and panics if you try to use more than are allocated." +"heap allocation. \\[`tinyvec`\\]\\[1\\] provides this: a vector backed by an " +"array or slice, which could be statically allocated or on the stack, which " +"keeps track of how many elements are used and panics if you try to use more " +"than are allocated." msgstr "" +"A veces, se necesita algo que se pueda cambiar de tamaño, como `Vec`, pero " +"sin asignación de montículo. \\[`tinyvec`\\]\\[1\\] ofrece un vector " +"respaldado por un array o slice, que se podría asignar estáticamente o en la " +"pila, y que hace un seguimiento de cuántos elementos se usan, entrando en " +"pánico si intentas utilizar más elementos de los asignados." #: src/bare-metal/useful-crates/tinyvec.md:8 msgid "" @@ -15766,21 +17047,37 @@ msgid "" "}\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." msgstr "" +"`tinyvec` requiere que el tipo de elemento implemente `Default` para la " +"inicialización." #: src/bare-metal/useful-crates/tinyvec.md:24 msgid "" "The Rust Playground includes `tinyvec`, so this example will run fine inline." msgstr "" +"El playground de Rust incluye `tinyvec`, por lo que este ejemplo se " +"ejecutará bien aunque esté insertado." #: src/bare-metal/useful-crates/spin.md:1 msgid "`spin`" -msgstr "" +msgstr "`spin`" #: src/bare-metal/useful-crates/spin.md:3 msgid "" @@ -15788,12 +17085,18 @@ msgid "" "are not available in `core` or `alloc`. How can we manage synchronisation or " "interior mutability, such as for sharing state between different CPUs?" msgstr "" +"`std::sync::Mutex` y el resto de los primitivos de sincronización de `std::" +"sync` no están disponibles en `core` o `alloc`. ¿Cómo podemos gestionar la " +"sincronización o la mutabilidad interior para, por ejemplo, compartir el " +"estado entre diferentes CPUs?" #: src/bare-metal/useful-crates/spin.md:7 msgid "" -"The [`spin`](https://crates.io/crates/spin) crate provides spinlock-based " -"equivalents of many of these primitives." +"The \\[`spin`\\]\\[1\\] crate provides spinlock-based equivalents of many of " +"these primitives." msgstr "" +"El crate \\[`spin`\\]\\[1\\] proporciona equivalentes basados en spinlocks " +"de muchos de estos primitivos." #: src/bare-metal/useful-crates/spin.md:9 msgid "" @@ -15809,28 +17112,48 @@ msgid "" "}\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." msgstr "" +"Intenta evitar interbloqueos si usas bloqueos en los controladores de las " +"interrupciones." #: src/bare-metal/useful-crates/spin.md:24 msgid "" "`spin` also has a ticket lock mutex implementation; equivalents of `RwLock`, " "`Barrier` and `Once` from `std::sync`; and `Lazy` for lazy initialisation." msgstr "" +"`spin` también cuenta con una implementación de exclusión mutua de bloqueo " +"de tickets; equivalentes de `RwLock`, `Barrier` y `Once` de `std::sync`, y " +"`Lazy` para inicialización perezosa" #: src/bare-metal/useful-crates/spin.md:26 msgid "" -"The [`once_cell`](https://crates.io/crates/once_cell) crate also has some " -"useful types for late initialisation with a slightly different approach to " -"`spin::once::Once`." +"The \\[`once_cell`\\]\\[2\\] crate also has some useful types for late " +"initialisation with a slightly different approach to `spin::once::Once`." msgstr "" +"El crate \\[`once_cell`\\]\\[2\\] también tiene algunos tipos útiles de " +"inicialización tardía con un enfoque ligeramente distinto al de `spin::once::" +"Once`." #: src/bare-metal/useful-crates/spin.md:28 msgid "" "The Rust Playground includes `spin`, so this example will run fine inline." msgstr "" +"El playground de Rust incluye `spin`, por lo que este ejemplo se ejecutará " +"bien aunque está insertado." #: src/bare-metal/android.md:3 msgid "" @@ -15839,6 +17162,11 @@ msgid "" "with a linker script to produce the binary itself, and then a `raw_binary` " "to convert the ELF to a raw binary ready to be run." msgstr "" +"Para compilar un binario de Rust bare-metal en AOSP, tienes que usar una " +"regla `rust_ffi_static` de Soong para crear tu código Rust y, seguidamente, " +"un `cc_binary` con una secuencia de comandos de enlazador para producir el " +"binario en sí. Por último, un `raw_binary` para convertir el ELF en un " +"binario sin formato que pueda ejecutarse." #: src/bare-metal/android.md:7 msgid "" @@ -15881,94 +17209,172 @@ msgid "" "}\n" "```" msgstr "" - -#: src/bare-metal/android/vmbase.md:3 -msgid "" -"For VMs running under crosvm on aarch64, the [vmbase](https://android." -"googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/" -"master/vmbase/) library provides a linker script and useful defaults for the " -"build rules, along with an entry point, UART console logging and more." -msgstr "" - -#: 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" +"```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" -"```" -msgstr "" - -#: src/bare-metal/android/vmbase.md:21 -msgid "" -"The `main!` macro marks your main function, to be called from the `vmbase` " -"entry point." +"\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:3 +msgid "" +"For VMs running under crosvm on aarch64, the \\[vmbase\\]\\[1\\] library " +"provides a linker script and useful defaults for the build rules, along with " +"an entry point, UART console logging and more." +msgstr "" +"En el caso de las máquinas virtuales que se ejecutan con crosvm en aarch64, " +"la biblioteca \\[vmbase\\]\\[1\\] proporciona una secuencia de comandos de " +"enlazador y valores predeterminados útiles para las reglas de compilación, " +"además de un punto de entrada, registro de la consola UART y mucho más." + +#: 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." msgstr "" +"La macro `main!` indica tu función principal, que se llama desde el punto de " +"entrada `vmbase`." #: src/bare-metal/android/vmbase.md:22 msgid "" "The `vmbase` entry point handles console initialisation, and issues a " "PSCI_SYSTEM_OFF to shutdown the VM if your main function returns." msgstr "" +"El punto de entrada `vmbase` gestiona la inicialización de la consola y " +"emite PSCI_SYSTEM_OFF para apagar la máquina virtual si tu función principal " +"devuelve un resultado." #: src/exercises/bare-metal/afternoon.md:3 msgid "We will write a driver for the PL031 real-time clock device." msgstr "" +"Escribiremos un controlador para el dispositivo de reloj en tiempo real " +"PL031." #: src/exercises/bare-metal/rtc.md:1 #: src/exercises/bare-metal/solutions-afternoon.md:3 msgid "RTC driver" -msgstr "" +msgstr "Controlador RTC" #: src/exercises/bare-metal/rtc.md:3 msgid "" -"The QEMU aarch64 virt machine has a [PL031](https://developer.arm.com/" -"documentation/ddi0224/c) real-time clock at 0x9010000. For this exercise, " -"you should write a driver for it." +"The QEMU aarch64 virt machine has a \\[PL031\\]\\[1\\] real-time clock at " +"0x9010000. For this exercise, you should write a driver for it." msgstr "" +"La máquina virtual aarch64 de QEMU tiene un reloj en tiempo real " +"\\[PL031\\]\\[1\\] en 0x9010000. En este ejercicio, debes escribir un " +"controlador para el reloj." #: src/exercises/bare-metal/rtc.md:6 msgid "" "Use it to print the current time to the serial console. You can use the " -"[`chrono`](https://crates.io/crates/chrono) crate for date/time formatting." +"\\[`chrono`\\]\\[2\\] crate for date/time formatting." msgstr "" +"Úsalo para imprimir la hora en la consola serie. Puedes usar el crate " +"\\[`chrono`\\]\\[2\\] para dar formato a la fecha y la hora." #: src/exercises/bare-metal/rtc.md:8 msgid "" "Use the match register and raw interrupt status to busy-wait until a given " -"time, e.g. 3 seconds in the future. (Call [`core::hint::spin_loop`](https://" -"doc.rust-lang.org/core/hint/fn.spin_loop.html) inside the loop.)" +"time, e.g. 3 seconds in the future. (Call \\[`core::hint::" +"spin_loop`\\]\\[3\\] inside the loop.)" msgstr "" +"Utiliza el registro de coincidencias y el estado de interrupción sin formato " +"para esperar hasta un momento dado, por ejemplo, un adelanto de 3 segundos. " +"(Llama a \\[`core::hint::spin_loop`\\]\\[3\\] dentro d+el bucle)." #: src/exercises/bare-metal/rtc.md:10 msgid "" "_Extension if you have time:_ Enable and handle the interrupt generated by " -"the RTC match. You can use the driver provided in the [`arm-gic`](https://" -"docs.rs/arm-gic/) crate to configure the Arm Generic Interrupt Controller." +"the RTC match. You can use the driver provided in the \\[`arm-gic`\\]\\[4\\] " +"crate to configure the Arm Generic Interrupt Controller." msgstr "" +"_Ampliación si hay tiempo:_ habilita y gestiona la interrupción que genera " +"la coincidencia de RTC. Puedes usar el controlador que se proporciona con el " +"crate \\[`arm-gic`\\]\\[4\\] para configurar el controlador de " +"interrupciones genérico (GIC) de Arm." #: src/exercises/bare-metal/rtc.md:12 msgid "Use the RTC interrupt, which is wired to the GIC as `IntId::spi(2)`." msgstr "" +"Utiliza la interrupción de RTC, que está conectada al GIC como `IntId::" +"spi(2)`." #: src/exercises/bare-metal/rtc.md:13 msgid "" "Once the interrupt is enabled, you can put the core to sleep via `arm_gic::" "wfi()`, which will cause the core to sleep until it receives an interrupt." msgstr "" +"Después de habilitar la interrupción, puedes poner el núcleo en suspensión " +"mediante `arm_gic::wfi()`, lo que hará que entre en suspensión hasta que " +"reciba una interrupción." #: src/exercises/bare-metal/rtc.md:16 msgid "" "Download the [exercise template](../../comprehensive-rust-exercises.zip) and " "look in the `rtc` directory for the following files." msgstr "" +"Descarga la [plantilla de ejercicio](../../comprehensive-rust-exercises.zip) " +"y busca en el directorio `rtc` los siguientes archivos." #: src/exercises/bare-metal/rtc.md:23 msgid "" @@ -16027,12 +17433,68 @@ msgid "" "}\n" "```" msgstr "" +"```rust,compile_fail\n" +"#![no_main]\n" +"#![no_std]\n" +"\n" +"mod exceptions;\n" +"mod logger;\n" +"mod pl011;\n" +"\n" +"use crate::pl011::Uart;\n" +"use arm_gic::gicv3::GicV3;\n" +"use core::panic::PanicInfo;\n" +"use log::{error, info, trace, LevelFilter};\n" +"use smccc::psci::system_off;\n" +"use smccc::Hvc;\n" +"\n" +"/// Base addresses of the GICv3.\n" +"const GICD_BASE_ADDRESS: *mut u64 = 0x800_0000 as _;\n" +"const GICR_BASE_ADDRESS: *mut u64 = 0x80A_0000 as _;\n" +"\n" +"/// Base address of the primary PL011 UART.\n" +"const PL011_BASE_ADDRESS: *mut u32 = 0x900_0000 as _;\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {\n" +" // Safe because `PL011_BASE_ADDRESS` is the base address of a PL011 " +"device,\n" +" // and nothing else accesses that address range.\n" +" let uart = unsafe { Uart::new(PL011_BASE_ADDRESS) };\n" +" logger::init(uart, LevelFilter::Trace).unwrap();\n" +"\n" +" info!(\"main({:#x}, {:#x}, {:#x}, {:#x})\", x0, x1, x2, x3);\n" +"\n" +" // Safe because `GICD_BASE_ADDRESS` and `GICR_BASE_ADDRESS` are the " +"base\n" +" // addresses of a GICv3 distributor and redistributor respectively, and\n" +" // nothing else accesses those address ranges.\n" +" let mut gic = unsafe { GicV3::new(GICD_BASE_ADDRESS, " +"GICR_BASE_ADDRESS) };\n" +" gic.setup();\n" +"\n" +" // TODO: Create instance of RTC driver and print current time.\n" +"\n" +" // TODO: Wait for 3 seconds.\n" +"\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[panic_handler]\n" +"fn panic(info: &PanicInfo) -> ! {\n" +" error!(\"{info}\");\n" +" system_off::().unwrap();\n" +" loop {}\n" +"}\n" +"```" #: src/exercises/bare-metal/rtc.md:75 msgid "" "`src/exceptions.rs` (you should only need to change this for the 3rd part of " "the exercise):" msgstr "" +"`src/exceptions.rs` (solo se debería cambiar esto en la tercera parte del " +"ejercicio):" #: src/exercises/bare-metal/rtc.md:79 msgid "" @@ -16107,10 +17569,80 @@ msgid "" "}\n" "```" msgstr "" +"```rust,compile_fail\n" +"// Copyright 2023 Google LLC\n" +"//\n" +"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" +"// you may not use this file except in compliance with the License.\n" +"// You may obtain a copy of the License at\n" +"//\n" +"// http://www.apache.org/licenses/LICENSE-2.0\n" +"//\n" +"// Unless required by applicable law or agreed to in writing, software\n" +"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" +"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +"// See the License for the specific language governing permissions and\n" +"// limitations under the License.\n" +"\n" +"use arm_gic::gicv3::GicV3;\n" +"use log::{error, info, trace};\n" +"use smccc::psci::system_off;\n" +"use smccc::Hvc;\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn sync_exception_current(_elr: u64, _spsr: u64) {\n" +" error!(\"sync_exception_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn irq_current(_elr: u64, _spsr: u64) {\n" +" trace!(\"irq_current\");\n" +" let intid = GicV3::get_and_acknowledge_interrupt().expect(\"No pending " +"interrupt\");\n" +" info!(\"IRQ {intid:?}\");\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn fiq_current(_elr: u64, _spsr: u64) {\n" +" error!(\"fiq_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn serr_current(_elr: u64, _spsr: u64) {\n" +" error!(\"serr_current\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn sync_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"sync_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn irq_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"irq_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn fiq_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"fiq_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"\n" +"#[no_mangle]\n" +"extern \"C\" fn serr_lower(_elr: u64, _spsr: u64) {\n" +" error!(\"serr_lower\");\n" +" system_off::().unwrap();\n" +"}\n" +"```" #: src/exercises/bare-metal/rtc.md:149 msgid "`src/logger.rs` (you shouldn't need to change this):" -msgstr "" +msgstr "`src/logger.rs` (no debería ser necesario cambiarlo):" #: src/exercises/bare-metal/rtc.md:153 msgid "" @@ -16172,10 +17704,67 @@ msgid "" "}\n" "```" msgstr "" +"```rust,compile_fail\n" +"// Copyright 2023 Google LLC\n" +"//\n" +"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" +"// you may not use this file except in compliance with the License.\n" +"// You may obtain a copy of the License at\n" +"//\n" +"// http://www.apache.org/licenses/LICENSE-2.0\n" +"//\n" +"// Unless required by applicable law or agreed to in writing, software\n" +"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" +"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +"// See the License for the specific language governing permissions and\n" +"// limitations under the License.\n" +"\n" +"// ANCHOR: main\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" +"```" #: src/exercises/bare-metal/rtc.md:210 msgid "`src/pl011.rs` (you shouldn't need to change this):" -msgstr "" +msgstr "`src/pl011.rs` (no debería ser necesario cambiarlo):" #: src/exercises/bare-metal/rtc.md:214 msgid "" @@ -16355,13 +17944,188 @@ msgid "" "unsafe impl Send for Uart {}\n" "```" msgstr "" - -#: src/exercises/bare-metal/rtc.md:389 -msgid "" -"```toml\n" -"[workspace]\n" -"\n" -"[package]\n" +"```rust,compile_fail\n" +"// Copyright 2023 Google LLC\n" +"//\n" +"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" +"// you may not use this file except in compliance with the License.\n" +"// You may obtain a copy of the License at\n" +"//\n" +"// http://www.apache.org/licenses/LICENSE-2.0\n" +"//\n" +"// Unless required by applicable law or agreed to in writing, software\n" +"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" +"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +"// See the License for the specific language governing permissions and\n" +"// limitations under the License.\n" +"\n" +"#![allow(unused)]\n" +"\n" +"use core::fmt::{self, Write};\n" +"use core::ptr::{addr_of, addr_of_mut};\n" +"\n" +"// ANCHOR: Flags\n" +"use bitflags::bitflags;\n" +"\n" +"bitflags! {\n" +" /// Flags from the UART flag register.\n" +" #[repr(transparent)]\n" +" #[derive(Copy, Clone, Debug, Eq, PartialEq)]\n" +" struct Flags: u16 {\n" +" /// Clear to send.\n" +" const CTS = 1 << 0;\n" +" /// Data set ready.\n" +" const DSR = 1 << 1;\n" +" /// Data carrier detect.\n" +" const DCD = 1 << 2;\n" +" /// UART busy transmitting data.\n" +" const BUSY = 1 << 3;\n" +" /// Receive FIFO is empty.\n" +" const RXFE = 1 << 4;\n" +" /// Transmit FIFO is full.\n" +" const TXFF = 1 << 5;\n" +" /// Receive FIFO is full.\n" +" const RXFF = 1 << 6;\n" +" /// Transmit FIFO is empty.\n" +" const TXFE = 1 << 7;\n" +" /// Ring indicator.\n" +" const RI = 1 << 8;\n" +" }\n" +"}\n" +"// ANCHOR_END: Flags\n" +"\n" +"bitflags! {\n" +" /// Flags from the UART Receive Status Register / Error Clear Register.\n" +" #[repr(transparent)]\n" +" #[derive(Copy, Clone, Debug, Eq, PartialEq)]\n" +" struct ReceiveStatus: u16 {\n" +" /// Framing error.\n" +" const FE = 1 << 0;\n" +" /// Parity error.\n" +" const PE = 1 << 1;\n" +" /// Break error.\n" +" const BE = 1 << 2;\n" +" /// Overrun error.\n" +" const OE = 1 << 3;\n" +" }\n" +"}\n" +"\n" +"// ANCHOR: Registers\n" +"#[repr(C, align(4))]\n" +"struct Registers {\n" +" dr: u16,\n" +" _reserved0: [u8; 2],\n" +" rsr: ReceiveStatus,\n" +" _reserved1: [u8; 19],\n" +" fr: Flags,\n" +" _reserved2: [u8; 6],\n" +" ilpr: u8,\n" +" _reserved3: [u8; 3],\n" +" ibrd: u16,\n" +" _reserved4: [u8; 2],\n" +" fbrd: u8,\n" +" _reserved5: [u8; 3],\n" +" lcr_h: u8,\n" +" _reserved6: [u8; 3],\n" +" cr: u16,\n" +" _reserved7: [u8; 3],\n" +" ifls: u8,\n" +" _reserved8: [u8; 3],\n" +" imsc: u16,\n" +" _reserved9: [u8; 2],\n" +" ris: u16,\n" +" _reserved10: [u8; 2],\n" +" mis: u16,\n" +" _reserved11: [u8; 2],\n" +" icr: u16,\n" +" _reserved12: [u8; 2],\n" +" dmacr: u8,\n" +" _reserved13: [u8; 3],\n" +"}\n" +"// ANCHOR_END: Registers\n" +"\n" +"// ANCHOR: Uart\n" +"/// Driver for a PL011 UART.\n" +"#[derive(Debug)]\n" +"pub struct Uart {\n" +" registers: *mut Registers,\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 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 u32) -> Self {\n" +" Self {\n" +" registers: base_address as *mut Registers,\n" +" }\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().contains(Flags::TXFF) {}\n" +"\n" +" // Safe because we know that self.registers points to the control\n" +" // registers of a PL011 device which is appropriately mapped.\n" +" unsafe {\n" +" // Write to the TX buffer.\n" +" addr_of_mut!((*self.registers).dr).write_volatile(byte.into());\n" +" }\n" +"\n" +" // Wait until the UART is no longer busy.\n" +" while self.read_flag_register().contains(Flags::BUSY) {}\n" +" }\n" +"\n" +" /// Reads and returns a pending byte, or `None` if nothing has been " +"received.\n" +" pub fn read_byte(&self) -> Option {\n" +" if self.read_flag_register().contains(Flags::RXFE) {\n" +" None\n" +" } else {\n" +" let data = unsafe { addr_of!((*self.registers).dr)." +"read_volatile() };\n" +" // TODO: Check for error conditions in bits 8-11.\n" +" Some(data as u8)\n" +" }\n" +" }\n" +"\n" +" fn read_flag_register(&self) -> Flags {\n" +" // Safe because we know that self.registers points to the control\n" +" // registers of a PL011 device which is appropriately mapped.\n" +" unsafe { addr_of!((*self.registers).fr).read_volatile() }\n" +" }\n" +"}\n" +"// ANCHOR_END: Uart\n" +"\n" +"impl Write for Uart {\n" +" fn write_str(&mut self, s: &str) -> fmt::Result {\n" +" for c in s.as_bytes() {\n" +" self.write_byte(*c);\n" +" }\n" +" Ok(())\n" +" }\n" +"}\n" +"\n" +"// Safe because it just contains a pointer to device memory, which can be\n" +"// accessed from any context.\n" +"unsafe impl Send for Uart {}\n" +"```" + +#: src/exercises/bare-metal/rtc.md:389 +msgid "" +"```toml\n" +"[workspace]\n" +"\n" +"[package]\n" "name = \"rtc\"\n" "version = \"0.1.0\"\n" "edition = \"2021\"\n" @@ -16379,10 +18143,30 @@ msgid "" "cc = \"1.0.73\"\n" "```" msgstr "" +"```toml\n" +"[workspace]\n" +"\n" +"[package]\n" +"name = \"rtc\"\n" +"version = \"0.1.0\"\n" +"edition = \"2021\"\n" +"publish = false\n" +"\n" +"[dependencies]\n" +"arm-gic = \"0.1.0\"\n" +"bitflags = \"2.0.0\"\n" +"chrono = { version = \"0.4.24\", default-features = false }\n" +"log = \"0.4.17\"\n" +"smccc = \"0.1.1\"\n" +"spin = \"0.9.8\"\n" +"\n" +"[build-dependencies]\n" +"cc = \"1.0.73\"\n" +"```" #: src/exercises/bare-metal/rtc.md:410 msgid "`build.rs` (you shouldn't need to change this):" -msgstr "" +msgstr "`build.rs` (no debería ser necesario cambiarlo):" #: src/exercises/bare-metal/rtc.md:414 msgid "" @@ -16418,10 +18202,41 @@ msgid "" "}\n" "```" msgstr "" +"```rust,compile_fail\n" +"// Copyright 2023 Google LLC\n" +"//\n" +"// Licensed under the Apache License, Version 2.0 (the \"License\");\n" +"// you may not use this file except in compliance with the License.\n" +"// You may obtain a copy of the License at\n" +"//\n" +"// http://www.apache.org/licenses/LICENSE-2.0\n" +"//\n" +"// Unless required by applicable law or agreed to in writing, software\n" +"// distributed under the License is distributed on an \"AS IS\" BASIS,\n" +"// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +"// See the License for the specific language governing permissions and\n" +"// limitations under the License.\n" +"\n" +"use cc::Build;\n" +"use std::env;\n" +"\n" +"fn main() {\n" +" #[cfg(target_os = \"linux\")]\n" +" env::set_var(\"CROSS_COMPILE\", \"aarch64-linux-gnu\");\n" +" #[cfg(not(target_os = \"linux\"))]\n" +" env::set_var(\"CROSS_COMPILE\", \"aarch64-none-elf\");\n" +"\n" +" Build::new()\n" +" .file(\"entry.S\")\n" +" .file(\"exceptions.S\")\n" +" .file(\"idmap.S\")\n" +" .compile(\"empty\")\n" +"}\n" +"```" #: src/exercises/bare-metal/rtc.md:446 msgid "`entry.S` (you shouldn't need to change this):" -msgstr "" +msgstr "`entry.S` (no debería ser necesario cambiarlo):" #: src/exercises/bare-metal/rtc.md:450 msgid "" @@ -16554,43 +18369,392 @@ msgid "" "\tmsr sctlr_el1, x30\n" "\tisb\n" "\n" -"\t/* Disable trapping floating point access in EL1. */\n" -"\tmrs x30, cpacr_el1\n" -"\torr x30, x30, #(0x3 << 20)\n" -"\tmsr cpacr_el1, x30\n" -"\tisb\n" +"\t/* Disable trapping floating point access in EL1. */\n" +"\tmrs x30, cpacr_el1\n" +"\torr x30, x30, #(0x3 << 20)\n" +"\tmsr cpacr_el1, x30\n" +"\tisb\n" +"\n" +"\t/* Zero out the bss section. */\n" +"\tadr_l x29, bss_begin\n" +"\tadr_l x30, bss_end\n" +"0:\tcmp x29, x30\n" +"\tb.hs 1f\n" +"\tstp xzr, xzr, [x29], #16\n" +"\tb 0b\n" +"\n" +"1:\t/* Prepare the stack. */\n" +"\tadr_l x30, boot_stack_end\n" +"\tmov sp, x30\n" +"\n" +"\t/* Set up exception vector. */\n" +"\tadr x30, vector_table_el1\n" +"\tmsr vbar_el1, x30\n" +"\n" +"\t/* Call into Rust code. */\n" +"\tbl main\n" +"\n" +"\t/* Loop forever waiting for interrupts. */\n" +"2:\twfi\n" +"\tb 2b\n" +"```" +msgstr "" +"```armasm\n" +"/*\n" +" * Copyright 2023 Google LLC\n" +" *\n" +" * Licensed under the Apache License, Version 2.0 (the \"License\");\n" +" * you may not use this file except in compliance with the License.\n" +" * You may obtain a copy of the License at\n" +" *\n" +" * https://www.apache.org/licenses/LICENSE-2.0\n" +" *\n" +" * Unless required by applicable law or agreed to in writing, software\n" +" * distributed under the License is distributed on an \"AS IS\" BASIS,\n" +" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +" * See the License for the specific language governing permissions and\n" +" * limitations under the License.\n" +" */\n" +"\n" +".macro adr_l, reg:req, sym:req\n" +"\tadrp \\reg, \\sym\n" +"\tadd \\reg, \\reg, :lo12:\\sym\n" +".endm\n" +"\n" +".macro mov_i, reg:req, imm:req\n" +"\tmovz \\reg, :abs_g3:\\imm\n" +"\tmovk \\reg, :abs_g2_nc:\\imm\n" +"\tmovk \\reg, :abs_g1_nc:\\imm\n" +"\tmovk \\reg, :abs_g0_nc:\\imm\n" +".endm\n" +"\n" +".set .L_MAIR_DEV_nGnRE,\t0x04\n" +".set .L_MAIR_MEM_WBWA,\t0xff\n" +".set .Lmairval, .L_MAIR_DEV_nGnRE | (.L_MAIR_MEM_WBWA << 8)\n" +"\n" +"/* 4 KiB granule size for TTBR0_EL1. */\n" +".set .L_TCR_TG0_4KB, 0x0 << 14\n" +"/* 4 KiB granule size for TTBR1_EL1. */\n" +".set .L_TCR_TG1_4KB, 0x2 << 30\n" +"/* Disable translation table walk for TTBR1_EL1, generating a translation " +"fault instead. */\n" +".set .L_TCR_EPD1, 0x1 << 23\n" +"/* Translation table walks for TTBR0_EL1 are inner sharable. */\n" +".set .L_TCR_SH_INNER, 0x3 << 12\n" +"/*\n" +" * Translation table walks for TTBR0_EL1 are outer write-back read-allocate " +"write-allocate\n" +" * cacheable.\n" +" */\n" +".set .L_TCR_RGN_OWB, 0x1 << 10\n" +"/*\n" +" * Translation table walks for TTBR0_EL1 are inner write-back read-allocate " +"write-allocate\n" +" * cacheable.\n" +" */\n" +".set .L_TCR_RGN_IWB, 0x1 << 8\n" +"/* Size offset for TTBR0_EL1 is 2**39 bytes (512 GiB). */\n" +".set .L_TCR_T0SZ_512, 64 - 39\n" +".set .Ltcrval, .L_TCR_TG0_4KB | .L_TCR_TG1_4KB | .L_TCR_EPD1 | ." +"L_TCR_RGN_OWB\n" +".set .Ltcrval, .Ltcrval | .L_TCR_RGN_IWB | .L_TCR_SH_INNER | ." +"L_TCR_T0SZ_512\n" +"\n" +"/* Stage 1 instruction access cacheability is unaffected. */\n" +".set .L_SCTLR_ELx_I, 0x1 << 12\n" +"/* SP alignment fault if SP is not aligned to a 16 byte boundary. */\n" +".set .L_SCTLR_ELx_SA, 0x1 << 3\n" +"/* Stage 1 data access cacheability is unaffected. */\n" +".set .L_SCTLR_ELx_C, 0x1 << 2\n" +"/* EL0 and EL1 stage 1 MMU enabled. */\n" +".set .L_SCTLR_ELx_M, 0x1 << 0\n" +"/* Privileged Access Never is unchanged on taking an exception to EL1. */\n" +".set .L_SCTLR_EL1_SPAN, 0x1 << 23\n" +"/* SETEND instruction disabled at EL0 in aarch32 mode. */\n" +".set .L_SCTLR_EL1_SED, 0x1 << 8\n" +"/* Various IT instructions are disabled at EL0 in aarch32 mode. */\n" +".set .L_SCTLR_EL1_ITD, 0x1 << 7\n" +".set .L_SCTLR_EL1_RES1, (0x1 << 11) | (0x1 << 20) | (0x1 << 22) | (0x1 << " +"28) | (0x1 << 29)\n" +".set .Lsctlrval, .L_SCTLR_ELx_M | .L_SCTLR_ELx_C | .L_SCTLR_ELx_SA | ." +"L_SCTLR_EL1_ITD | .L_SCTLR_EL1_SED\n" +".set .Lsctlrval, .Lsctlrval | .L_SCTLR_ELx_I | .L_SCTLR_EL1_SPAN | ." +"L_SCTLR_EL1_RES1\n" +"\n" +"/**\n" +" * Es un punto de entrada genérico para una imagen. It carries out the " +"operations required to prepare the\n" +" * loaded image to be run. Specifically, it zeroes the bss section using " +"registers x25 and above,\n" +" * prepares the stack, enables floating point, and sets up the exception " +"vector. It preserves x0-x3\n" +" * for the Rust entry point, as these may contain boot parameters.\n" +" */\n" +".section .init.entry, \"ax\"\n" +".global entry\n" +"entry:\n" +"\t/* Load and apply the memory management configuration, ready to enable MMU " +"and caches. */\n" +"\tadrp x30, idmap\n" +"\tmsr ttbr0_el1, x30\n" +"\n" +"\tmov_i x30, .Lmairval\n" +"\tmsr mair_el1, x30\n" +"\n" +"\tmov_i x30, .Ltcrval\n" +"\t/* Copy the supported PA range into TCR_EL1.IPS. */\n" +"\tmrs x29, id_aa64mmfr0_el1\n" +"\tbfi x30, x29, #32, #4\n" +"\n" +"\tmsr tcr_el1, x30\n" +"\n" +"\tmov_i x30, .Lsctlrval\n" +"\n" +"\t/*\n" +"\t * Ensure everything before this point has completed, then invalidate any " +"potentially stale\n" +"\t * local TLB entries before they start being used.\n" +"\t */\n" +"\tisb\n" +"\ttlbi vmalle1\n" +"\tic iallu\n" +"\tdsb nsh\n" +"\tisb\n" +"\n" +"\t/*\n" +"\t * Configure sctlr_el1 to enable MMU and cache and don't proceed until " +"this has completed.\n" +"\t */\n" +"\tmsr sctlr_el1, x30\n" +"\tisb\n" +"\n" +"\t/* Disable trapping floating point access in EL1. */\n" +"\tmrs x30, cpacr_el1\n" +"\torr x30, x30, #(0x3 << 20)\n" +"\tmsr cpacr_el1, x30\n" +"\tisb\n" +"\n" +"\t/* Zero out the bss section. */\n" +"\tadr_l x29, bss_begin\n" +"\tadr_l x30, bss_end\n" +"0:\tcmp x29, x30\n" +"\tb.hs 1f\n" +"\tstp xzr, xzr, [x29], #16\n" +"\tb 0b\n" +"\n" +"1:\t/* Prepare the stack. */\n" +"\tadr_l x30, boot_stack_end\n" +"\tmov sp, x30\n" +"\n" +"\t/* Set up exception vector. */\n" +"\tadr x30, vector_table_el1\n" +"\tmsr vbar_el1, x30\n" +"\n" +"\t/* Call into Rust code. */\n" +"\tbl main\n" +"\n" +"\t/* Loop forever waiting for interrupts. */\n" +"2:\twfi\n" +"\tb 2b\n" +"```" + +#: src/exercises/bare-metal/rtc.md:595 +msgid "`exceptions.S` (you shouldn't need to change this):" +msgstr "`exceptions.S` (no debería ser necesario cambiarlo):" + +#: src/exercises/bare-metal/rtc.md:599 +msgid "" +"```armasm\n" +"/*\n" +" * Copyright 2023 Google LLC\n" +" *\n" +" * Licensed under the Apache License, Version 2.0 (the \"License\");\n" +" * you may not use this file except in compliance with the License.\n" +" * You may obtain a copy of the License at\n" +" *\n" +" * https://www.apache.org/licenses/LICENSE-2.0\n" +" *\n" +" * Unless required by applicable law or agreed to in writing, software\n" +" * distributed under the License is distributed on an \"AS IS\" BASIS,\n" +" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +" * See the License for the specific language governing permissions and\n" +" * limitations under the License.\n" +" */\n" +"\n" +"/**\n" +" * Saves the volatile registers onto the stack. This currently takes 14\n" +" * instructions, so it can be used in exception handlers with 18 " +"instructions\n" +" * left.\n" +" *\n" +" * On return, x0 and x1 are initialised to elr_el2 and spsr_el2 " +"respectively,\n" +" * which can be used as the first and second arguments of a subsequent " +"call.\n" +" */\n" +".macro save_volatile_to_stack\n" +"\t/* Reserve stack space and save registers x0-x18, x29 & x30. */\n" +"\tstp x0, x1, [sp, #-(8 * 24)]!\n" +"\tstp x2, x3, [sp, #8 * 2]\n" +"\tstp x4, x5, [sp, #8 * 4]\n" +"\tstp x6, x7, [sp, #8 * 6]\n" +"\tstp x8, x9, [sp, #8 * 8]\n" +"\tstp x10, x11, [sp, #8 * 10]\n" +"\tstp x12, x13, [sp, #8 * 12]\n" +"\tstp x14, x15, [sp, #8 * 14]\n" +"\tstp x16, x17, [sp, #8 * 16]\n" +"\tstr x18, [sp, #8 * 18]\n" +"\tstp x29, x30, [sp, #8 * 20]\n" +"\n" +"\t/*\n" +"\t * Save elr_el1 & spsr_el1. This such that we can take nested exception\n" +"\t * and still be able to unwind.\n" +"\t */\n" +"\tmrs x0, elr_el1\n" +"\tmrs x1, spsr_el1\n" +"\tstp x0, x1, [sp, #8 * 22]\n" +".endm\n" +"\n" +"/**\n" +" * Restores the volatile registers from the stack. This currently takes 14\n" +" * instructions, so it can be used in exception handlers while still leaving " +"18\n" +" * instructions left; if paired with save_volatile_to_stack, there are 4\n" +" * instructions to spare.\n" +" */\n" +".macro restore_volatile_from_stack\n" +"\t/* Restore registers x2-x18, x29 & x30. */\n" +"\tldp x2, x3, [sp, #8 * 2]\n" +"\tldp x4, x5, [sp, #8 * 4]\n" +"\tldp x6, x7, [sp, #8 * 6]\n" +"\tldp x8, x9, [sp, #8 * 8]\n" +"\tldp x10, x11, [sp, #8 * 10]\n" +"\tldp x12, x13, [sp, #8 * 12]\n" +"\tldp x14, x15, [sp, #8 * 14]\n" +"\tldp x16, x17, [sp, #8 * 16]\n" +"\tldr x18, [sp, #8 * 18]\n" +"\tldp x29, x30, [sp, #8 * 20]\n" +"\n" +"\t/* Restore registers elr_el1 & spsr_el1, using x0 & x1 as scratch. */\n" +"\tldp x0, x1, [sp, #8 * 22]\n" +"\tmsr elr_el1, x0\n" +"\tmsr spsr_el1, x1\n" +"\n" +"\t/* Restore x0 & x1, and release stack space. */\n" +"\tldp x0, x1, [sp], #8 * 24\n" +".endm\n" +"\n" +"/**\n" +" * This is a generic handler for exceptions taken at the current EL while " +"using\n" +" * SP0. It behaves similarly to the SPx case by first switching to SPx, " +"doing\n" +" * the work, then switching back to SP0 before returning.\n" +" *\n" +" * Switching to SPx and calling the Rust handler takes 16 instructions. To\n" +" * restore and return we need an additional 16 instructions, so we can " +"implement\n" +" * the whole handler within the allotted 32 instructions.\n" +" */\n" +".macro current_exception_sp0 handler:req\n" +"\tmsr spsel, #1\n" +"\tsave_volatile_to_stack\n" +"\tbl \\handler\n" +"\trestore_volatile_from_stack\n" +"\tmsr spsel, #0\n" +"\teret\n" +".endm\n" +"\n" +"/**\n" +" * This is a generic handler for exceptions taken at the current EL while " +"using\n" +" * SPx. It saves volatile registers, calls the Rust handler, restores " +"volatile\n" +" * registers, then returns.\n" +" *\n" +" * This also works for exceptions taken from EL0, if we don't care about\n" +" * non-volatile registers.\n" +" *\n" +" * Saving state and jumping to the Rust handler takes 15 instructions, and\n" +" * restoring and returning also takes 15 instructions, so we can fit the " +"whole\n" +" * handler in 30 instructions, under the limit of 32.\n" +" */\n" +".macro current_exception_spx handler:req\n" +"\tsave_volatile_to_stack\n" +"\tbl \\handler\n" +"\trestore_volatile_from_stack\n" +"\teret\n" +".endm\n" +"\n" +".section .text.vector_table_el1, \"ax\"\n" +".global vector_table_el1\n" +".balign 0x800\n" +"vector_table_el1:\n" +"sync_cur_sp0:\n" +"\tcurrent_exception_sp0 sync_exception_current\n" +"\n" +".balign 0x80\n" +"irq_cur_sp0:\n" +"\tcurrent_exception_sp0 irq_current\n" +"\n" +".balign 0x80\n" +"fiq_cur_sp0:\n" +"\tcurrent_exception_sp0 fiq_current\n" +"\n" +".balign 0x80\n" +"serr_cur_sp0:\n" +"\tcurrent_exception_sp0 serr_current\n" +"\n" +".balign 0x80\n" +"sync_cur_spx:\n" +"\tcurrent_exception_spx sync_exception_current\n" +"\n" +".balign 0x80\n" +"irq_cur_spx:\n" +"\tcurrent_exception_spx irq_current\n" +"\n" +".balign 0x80\n" +"fiq_cur_spx:\n" +"\tcurrent_exception_spx fiq_current\n" +"\n" +".balign 0x80\n" +"serr_cur_spx:\n" +"\tcurrent_exception_spx serr_current\n" +"\n" +".balign 0x80\n" +"sync_lower_64:\n" +"\tcurrent_exception_spx sync_lower\n" +"\n" +".balign 0x80\n" +"irq_lower_64:\n" +"\tcurrent_exception_spx irq_lower\n" "\n" -"\t/* Zero out the bss section. */\n" -"\tadr_l x29, bss_begin\n" -"\tadr_l x30, bss_end\n" -"0:\tcmp x29, x30\n" -"\tb.hs 1f\n" -"\tstp xzr, xzr, [x29], #16\n" -"\tb 0b\n" +".balign 0x80\n" +"fiq_lower_64:\n" +"\tcurrent_exception_spx fiq_lower\n" "\n" -"1:\t/* Prepare the stack. */\n" -"\tadr_l x30, boot_stack_end\n" -"\tmov sp, x30\n" +".balign 0x80\n" +"serr_lower_64:\n" +"\tcurrent_exception_spx serr_lower\n" "\n" -"\t/* Set up exception vector. */\n" -"\tadr x30, vector_table_el1\n" -"\tmsr vbar_el1, x30\n" +".balign 0x80\n" +"sync_lower_32:\n" +"\tcurrent_exception_spx sync_lower\n" "\n" -"\t/* Call into Rust code. */\n" -"\tbl main\n" +".balign 0x80\n" +"irq_lower_32:\n" +"\tcurrent_exception_spx irq_lower\n" "\n" -"\t/* Loop forever waiting for interrupts. */\n" -"2:\twfi\n" -"\tb 2b\n" +".balign 0x80\n" +"fiq_lower_32:\n" +"\tcurrent_exception_spx fiq_lower\n" +"\n" +".balign 0x80\n" +"serr_lower_32:\n" +"\tcurrent_exception_spx serr_lower\n" "```" msgstr "" - -#: src/exercises/bare-metal/rtc.md:595 -msgid "`exceptions.S` (you shouldn't need to change this):" -msgstr "" - -#: src/exercises/bare-metal/rtc.md:599 -msgid "" "```armasm\n" "/*\n" " * Copyright 2023 Google LLC\n" @@ -16781,11 +18945,10 @@ msgid "" "serr_lower_32:\n" "\tcurrent_exception_spx serr_lower\n" "```" -msgstr "" #: src/exercises/bare-metal/rtc.md:780 msgid "`idmap.S` (you shouldn't need to change this):" -msgstr "" +msgstr "`idmap.S` (no debería ser necesario cambiarlo):" #: src/exercises/bare-metal/rtc.md:784 msgid "" @@ -16835,10 +18998,55 @@ msgid "" "\t.fill\t\t255, 8, 0x0\t\t\t// 255 GiB of remaining VA space\n" "```" msgstr "" +"```armasm\n" +"/*\n" +" * Copyright 2023 Google LLC\n" +" *\n" +" * Licensed under the Apache License, Version 2.0 (the \"License\");\n" +" * you may not use this file except in compliance with the License.\n" +" * You may obtain a copy of the License at\n" +" *\n" +" * https://www.apache.org/licenses/LICENSE-2.0\n" +" *\n" +" * Unless required by applicable law or agreed to in writing, software\n" +" * distributed under the License is distributed on an \"AS IS\" BASIS,\n" +" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +" * See the License for the specific language governing permissions and\n" +" * limitations under the License.\n" +" */\n" +"\n" +".set .L_TT_TYPE_BLOCK, 0x1\n" +".set .L_TT_TYPE_PAGE, 0x3\n" +".set .L_TT_TYPE_TABLE, 0x3\n" +"\n" +"/* Access flag. */\n" +".set .L_TT_AF, 0x1 << 10\n" +"/* Not global. */\n" +".set .L_TT_NG, 0x1 << 11\n" +".set .L_TT_XN, 0x3 << 53\n" +"\n" +".set .L_TT_MT_DEV, 0x0 << 2\t\t\t// MAIR #0 (DEV_nGnRE)\n" +".set .L_TT_MT_MEM, (0x1 << 2) | (0x3 << 8)\t// MAIR #1 (MEM_WBWA), inner " +"shareable\n" +"\n" +".set .L_BLOCK_DEV, .L_TT_TYPE_BLOCK | .L_TT_MT_DEV | .L_TT_AF | .L_TT_XN\n" +".set .L_BLOCK_MEM, .L_TT_TYPE_BLOCK | .L_TT_MT_MEM | .L_TT_AF | .L_TT_NG\n" +"\n" +".section \".rodata.idmap\", \"a\", %progbits\n" +".global idmap\n" +".align 12\n" +"idmap:\n" +"\t/* level 1 */\n" +"\t.quad\t\t.L_BLOCK_DEV | 0x0\t\t // 1 GiB of device mappings\n" +"\t.quad\t\t.L_BLOCK_MEM | 0x40000000\t// 1 GiB of DRAM\n" +"\t.fill\t\t254, 8, 0x0\t\t\t// 254 GiB of unmapped VA space\n" +"\t.quad\t\t.L_BLOCK_DEV | 0x4000000000 // 1 GiB of device mappings\n" +"\t.fill\t\t255, 8, 0x0\t\t\t// 255 GiB of remaining VA space\n" +"```" #: src/exercises/bare-metal/rtc.md:829 msgid "`image.ld` (you shouldn't need to change this):" -msgstr "" +msgstr "`image.ld` (no debería ser necesario cambiarlo):" #: src/exercises/bare-metal/rtc.md:833 msgid "" @@ -16950,10 +19158,117 @@ msgid "" "}\n" "```" msgstr "" +"```ld\n" +"/*\n" +" * Copyright 2023 Google LLC\n" +" *\n" +" * Licensed under the Apache License, Version 2.0 (the \"License\");\n" +" * you may not use this file except in compliance with the License.\n" +" * You may obtain a copy of the License at\n" +" *\n" +" * https://www.apache.org/licenses/LICENSE-2.0\n" +" *\n" +" * Unless required by applicable law or agreed to in writing, software\n" +" * distributed under the License is distributed on an \"AS IS\" BASIS,\n" +" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +" * See the License for the specific language governing permissions and\n" +" * limitations under the License.\n" +" */\n" +"\n" +"/*\n" +" * Code will start running at this symbol which is placed at the start of " +"the\n" +" * image.\n" +" */\n" +"ENTRY(entry)\n" +"\n" +"MEMORY\n" +"{\n" +"\timage : ORIGIN = 0x40080000, LENGTH = 2M\n" +"}\n" +"\n" +"SECTIONS\n" +"{\n" +"\t/*\n" +"\t * Collect together the code.\n" +"\t */\n" +"\t.init : ALIGN(4096) {\n" +"\t\ttext_begin = .;\n" +"\t\t*(.init.entry)\n" +"\t\t*(.init.*)\n" +"\t} >image\n" +"\t.text : {\n" +"\t\t*(.text.*)\n" +"\t} >image\n" +"\ttext_end = .;\n" +"\n" +"\t/*\n" +"\t * Collect together read-only data.\n" +"\t */\n" +"\t.rodata : ALIGN(4096) {\n" +"\t\trodata_begin = .;\n" +"\t\t*(.rodata.*)\n" +"\t} >image\n" +"\t.got : {\n" +"\t\t*(.got)\n" +"\t} >image\n" +"\trodata_end = .;\n" +"\n" +"\t/*\n" +"\t * Collect together the read-write data including .bss at the end which\n" +"\t * will be zero'd by the entry code.\n" +"\t */\n" +"\t.data : ALIGN(4096) {\n" +"\t\tdata_begin = .;\n" +"\t\t*(.data.*)\n" +"\t\t/*\n" +"\t\t * The entry point code assumes that .data is a multiple of 32\n" +"\t\t * bytes long.\n" +"\t\t */\n" +"\t\t. = ALIGN(32);\n" +"\t\tdata_end = .;\n" +"\t} >image\n" +"\n" +"\t/* Everything beyond this point will not be included in the binary. */\n" +"\tbin_end = .;\n" +"\n" +"\t/* The entry point code assumes that .bss is 16-byte aligned. */\n" +"\t.bss : ALIGN(16) {\n" +"\t\tbss_begin = .;\n" +"\t\t*(.bss.*)\n" +"\t\t*(COMMON)\n" +"\t\t. = ALIGN(16);\n" +"\t\tbss_end = .;\n" +"\t} >image\n" +"\n" +"\t.stack (NOLOAD) : ALIGN(4096) {\n" +"\t\tboot_stack_begin = .;\n" +"\t\t. += 40 * 4096;\n" +"\t\t. = ALIGN(4096);\n" +"\t\tboot_stack_end = .;\n" +"\t} >image\n" +"\n" +"\t. = ALIGN(4K);\n" +"\tPROVIDE(dma_region = .);\n" +"\n" +"\t/*\n" +"\t * Remove unused sections from the image.\n" +"\t */\n" +"\t/DISCARD/ : {\n" +"\t\t/* The image loads itself so doesn't need these sections. */\n" +"\t\t*(.gnu.hash)\n" +"\t\t*(.hash)\n" +"\t\t*(.interp)\n" +"\t\t*(.eh_frame_hdr)\n" +"\t\t*(.eh_frame)\n" +"\t\t*(.note.gnu.build-id)\n" +"\t}\n" +"}\n" +"```" #: src/exercises/bare-metal/rtc.md:940 msgid "`Makefile` (you shouldn't need to change this):" -msgstr "" +msgstr "`Makefile` (no debería ser necesario cambiarlo):" #: src/exercises/bare-metal/rtc.md:944 msgid "" @@ -16999,6 +19314,47 @@ msgid "" "\trm -f *.bin\n" "```" msgstr "" +"```makefile\n" +"# Copyright 2023 Google LLC\n" +"#\n" +"# Licensed under the Apache License, Version 2.0 (the \"License\");\n" +"# you may not use this file except in compliance with the License.\n" +"# You may obtain a copy of the License at\n" +"#\n" +"# http://www.apache.org/licenses/LICENSE-2.0\n" +"#\n" +"# Unless required by applicable law or agreed to in writing, software\n" +"# distributed under the License is distributed on an \"AS IS\" BASIS,\n" +"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +"# See the License for the specific language governing permissions and\n" +"# limitations under the License.\n" +"\n" +"UNAME := $(shell uname -s)\n" +"ifeq ($(UNAME),Linux)\n" +"\tTARGET = aarch64-linux-gnu\n" +"else\n" +"\tTARGET = aarch64-none-elf\n" +"endif\n" +"OBJCOPY = $(TARGET)-objcopy\n" +"\n" +".PHONY: build qemu_minimal qemu qemu_logger\n" +"\n" +"all: rtc.bin\n" +"\n" +"build:\n" +"\tcargo build\n" +"\n" +"rtc.bin: build\n" +"\t$(OBJCOPY) -O binary target/aarch64-unknown-none/debug/rtc $@\n" +"\n" +"qemu: rtc.bin\n" +"\tqemu-system-aarch64 -machine virt,gic-version=3 -cpu max -serial mon:stdio " +"-display none -kernel $< -s\n" +"\n" +"clean:\n" +"\tcargo clean\n" +"\trm -f *.bin\n" +"```" #: src/exercises/bare-metal/rtc.md:989 msgid "" @@ -17008,10 +19364,15 @@ msgid "" "rustflags = [\"-C\", \"link-arg=-Timage.ld\"]\n" "```" msgstr "" +"```toml\n" +"[build]\n" +"target = \"aarch64-unknown-none\"\n" +"rustflags = [\"-C\", \"link-arg=-Timage.ld\"]\n" +"```" #: src/exercises/bare-metal/rtc.md:995 msgid "Run the code in QEMU with `make qemu`." -msgstr "" +msgstr "Ejecuta el código en QEMU con `make qemu`." #: src/concurrency.md:1 #, fuzzy