From dee0ee61fa8092e9e79ccff596a554a0286c3b2a Mon Sep 17 00:00:00 2001 From: TheMimiCodes Date: Sat, 1 Oct 2022 18:46:02 -0400 Subject: [PATCH 01/23] Add french translation of post 002 --- .../posts/02-minimal-rust-kernel/index.fr.md | 497 ++++++++++++++++++ 1 file changed, 497 insertions(+) create mode 100644 blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md new file mode 100644 index 00000000..ce83bb5b --- /dev/null +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -0,0 +1,497 @@ ++++ +title = "A Minimal Rust Kernel" +weight = 2 +path = "minimal-rust-kernel" +date = 2018-02-10 + +[extra] +chapter = "Bare Bones" +# Please update this when updating the translation +translation_based_on_commit = "c689ecf810f8e93f6b2fb3c4e1e8b89b8a0998eb" +# GitHub usernames of the people that translated this post +translators = ["TheMimiCodes", "maximevaillancourt"] ++++ + +In this post, we create a minimal 64-bit Rust kernel for the x86 architecture. We build upon the [freestanding Rust binary] from the previous post to create a bootable disk image that prints something to the screen. + +[freestanding Rust binary]: @/edition-2/posts/01-freestanding-rust-binary/index.md + + + +This blog is openly developed on [GitHub]. If you have any problems or questions, please open an issue there. You can also leave comments [at the bottom]. The complete source code for this post can be found in the [`post-02`][post branch] branch. + +[GitHub]: https://github.com/phil-opp/blog_os +[at the bottom]: #comments + +[post branch]: https://github.com/phil-opp/blog_os/tree/post-02 + + + +## The Boot Process +When you turn on a computer, it begins executing firmware code that is stored in motherboard [ROM]. This code performs a [power-on self-test], detects available RAM, and pre-initializes the CPU and hardware. Afterwards, it looks for a bootable disk and starts booting the operating system kernel. + +[ROM]: https://en.wikipedia.org/wiki/Read-only_memory +[power-on self-test]: https://en.wikipedia.org/wiki/Power-on_self-test + +On x86, there are two firmware standards: the “Basic Input/Output System“ (**[BIOS]**) and the newer “Unified Extensible Firmware Interface” (**[UEFI]**). The BIOS standard is old and outdated, but simple and well-supported on any x86 machine since the 1980s. UEFI, in contrast, is more modern and has much more features, but is more complex to set up (at least in my opinion). + +[BIOS]: https://en.wikipedia.org/wiki/BIOS +[UEFI]: https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface + +Currently, we only provide BIOS support, but support for UEFI is planned, too. If you'd like to help us with this, check out the [Github issue](https://github.com/phil-opp/blog_os/issues/349). + +### BIOS Boot +Almost all x86 systems have support for BIOS booting, including newer UEFI-based machines that use an emulated BIOS. This is great, because you can use the same boot logic across all machines from the last century. But this wide compatibility is at the same time the biggest disadvantage of BIOS booting, because it means that the CPU is put into a 16-bit compatibility mode called [real mode] before booting so that archaic bootloaders from the 1980s would still work. + +But let's start from the beginning: + +When you turn on a computer, it loads the BIOS from some special flash memory located on the motherboard. The BIOS runs self-test and initialization routines of the hardware, then it looks for bootable disks. If it finds one, control is transferred to its _bootloader_, which is a 512-byte portion of executable code stored at the disk's beginning. Most bootloaders are larger than 512 bytes, so bootloaders are commonly split into a small first stage, which fits into 512 bytes, and a second stage, which is subsequently loaded by the first stage. + +The bootloader has to determine the location of the kernel image on the disk and load it into memory. It also needs to switch the CPU from the 16-bit [real mode] first to the 32-bit [protected mode], and then to the 64-bit [long mode], where 64-bit registers and the complete main memory are available. Its third job is to query certain information (such as a memory map) from the BIOS and pass it to the OS kernel. + +[real mode]: https://en.wikipedia.org/wiki/Real_mode +[protected mode]: https://en.wikipedia.org/wiki/Protected_mode +[long mode]: https://en.wikipedia.org/wiki/Long_mode +[memory segmentation]: https://en.wikipedia.org/wiki/X86_memory_segmentation + +Writing a bootloader is a bit cumbersome as it requires assembly language and a lot of non insightful steps like “write this magic value to this processor register”. Therefore, we don't cover bootloader creation in this post and instead provide a tool named [bootimage] that automatically prepends a bootloader to your kernel. + +[bootimage]: https://github.com/rust-osdev/bootimage + +If you are interested in building your own bootloader: Stay tuned, a set of posts on this topic is already planned! + +#### The Multiboot Standard +To avoid that every operating system implements its own bootloader, which is only compatible with a single OS, the [Free Software Foundation] created an open bootloader standard called [Multiboot] in 1995. The standard defines an interface between the bootloader and the operating system, so that any Multiboot-compliant bootloader can load any Multiboot-compliant operating system. The reference implementation is [GNU GRUB], which is the most popular bootloader for Linux systems. + +[Free Software Foundation]: https://en.wikipedia.org/wiki/Free_Software_Foundation +[Multiboot]: https://wiki.osdev.org/Multiboot +[GNU GRUB]: https://en.wikipedia.org/wiki/GNU_GRUB + +To make a kernel Multiboot compliant, one just needs to insert a so-called [Multiboot header] at the beginning of the kernel file. This makes it very easy to boot an OS from GRUB. However, GRUB and the Multiboot standard have some problems too: + +[Multiboot header]: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#OS-image-format + +- They support only the 32-bit protected mode. This means that you still have to do the CPU configuration to switch to the 64-bit long mode. +- They are designed to make the bootloader simple instead of the kernel. For example, the kernel needs to be linked with an [adjusted default page size], because GRUB can't find the Multiboot header otherwise. Another example is that the [boot information], which is passed to the kernel, contains lots of architecture-dependent structures instead of providing clean abstractions. +- Both GRUB and the Multiboot standard are only sparsely documented. +- GRUB needs to be installed on the host system to create a bootable disk image from the kernel file. This makes development on Windows or Mac more difficult. + +[adjusted default page size]: https://wiki.osdev.org/Multiboot#Multiboot_2 +[boot information]: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format + +Because of these drawbacks, we decided to not use GRUB or the Multiboot standard. However, we plan to add Multiboot support to our [bootimage] tool, so that it's possible to load your kernel on a GRUB system too. If you're interested in writing a Multiboot compliant kernel, check out the [first edition] of this blog series. + +[first edition]: @/edition-1/_index.md + +### UEFI + +(We don't provide UEFI support at the moment, but we would love to! If you'd like to help, please tell us in the [Github issue](https://github.com/phil-opp/blog_os/issues/349).) + +## A Minimal Kernel +Now that we roughly know how a computer boots, it's time to create our own minimal kernel. Our goal is to create a disk image that prints a “Hello World!” to the screen when booted. We do this by extending the previous post's [freestanding Rust binary]. + +As you may remember, we built the freestanding binary through `cargo`, but depending on the operating system, we needed different entry point names and compile flags. That's because `cargo` builds for the _host system_ by default, i.e., the system you're running on. This isn't something we want for our kernel, because a kernel that runs on top of, e.g., Windows, does not make much sense. Instead, we want to compile for a clearly defined _target system_. + +### Installing Rust Nightly +Rust has three release channels: _stable_, _beta_, and _nightly_. The Rust Book explains the difference between these channels really well, so take a minute and [check it out](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#choo-choo-release-channels-and-riding-the-trains). For building an operating system, we will need some experimental features that are only available on the nightly channel, so we need to install a nightly version of Rust. + +To manage Rust installations, I highly recommend [rustup]. It allows you to install nightly, beta, and stable compilers side-by-side and makes it easy to update them. With rustup, you can use a nightly compiler for the current directory by running `rustup override set nightly`. Alternatively, you can add a file called `rust-toolchain` with the content `nightly` to the project's root directory. You can check that you have a nightly version installed by running `rustc --version`: The version number should contain `-nightly` at the end. + +[rustup]: https://www.rustup.rs/ + +The nightly compiler allows us to opt-in to various experimental features by using so-called _feature flags_ at the top of our file. For example, we could enable the experimental [`asm!` macro] for inline assembly by adding `#![feature(asm)]` to the top of our `main.rs`. Note that such experimental features are completely unstable, which means that future Rust versions might change or remove them without prior warning. For this reason, we will only use them if absolutely necessary. + +[`asm!` macro]: https://doc.rust-lang.org/stable/reference/inline-assembly.html + +### Target Specification +Cargo supports different target systems through the `--target` parameter. The target is described by a so-called _[target triple]_, which describes the CPU architecture, the vendor, the operating system, and the [ABI]. For example, the `x86_64-unknown-linux-gnu` target triple describes a system with an `x86_64` CPU, no clear vendor, and a Linux operating system with the GNU ABI. Rust supports [many different target triples][platform-support], including `arm-linux-androideabi` for Android or [`wasm32-unknown-unknown` for WebAssembly](https://www.hellorust.com/setup/wasm-target/). + +[target triple]: https://clang.llvm.org/docs/CrossCompilation.html#target-triple +[ABI]: https://stackoverflow.com/a/2456882 +[platform-support]: https://forge.rust-lang.org/release/platform-support.html +[custom-targets]: https://doc.rust-lang.org/nightly/rustc/targets/custom.html + +For our target system, however, we require some special configuration parameters (e.g. no underlying OS), so none of the [existing target triples][platform-support] fits. Fortunately, Rust allows us to define [our own target][custom-targets] through a JSON file. For example, a JSON file that describes the `x86_64-unknown-linux-gnu` target looks like this: + +```json +{ + "llvm-target": "x86_64-unknown-linux-gnu", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "linux", + "executables": true, + "linker-flavor": "gcc", + "pre-link-args": ["-m64"], + "morestack": false +} +``` + +Most fields are required by LLVM to generate code for that platform. For example, the [`data-layout`] field defines the size of various integer, floating point, and pointer types. Then there are fields that Rust uses for conditional compilation, such as `target-pointer-width`. The third kind of field defines how the crate should be built. For example, the `pre-link-args` field specifies arguments passed to the [linker]. + +[`data-layout`]: https://llvm.org/docs/LangRef.html#data-layout +[linker]: https://en.wikipedia.org/wiki/Linker_(computing) + +We also target `x86_64` systems with our kernel, so our target specification will look very similar to the one above. Let's start by creating an `x86_64-blog_os.json` file (choose any name you like) with the common content: + +```json +{ + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true +} +``` + +Note that we changed the OS in the `llvm-target` and the `os` field to `none`, because we will run on bare metal. + +We add the following build-related entries: + + +```json +"linker-flavor": "ld.lld", +"linker": "rust-lld", +``` + +Instead of using the platform's default linker (which might not support Linux targets), we use the cross-platform [LLD] linker that is shipped with Rust for linking our kernel. + +[LLD]: https://lld.llvm.org/ + +```json +"panic-strategy": "abort", +``` + +This setting specifies that the target doesn't support [stack unwinding] on panic, so instead the program should abort directly. This has the same effect as the `panic = "abort"` option in our Cargo.toml, so we can remove it from there. (Note that, in contrast to the Cargo.toml option, this target option also applies when we recompile the `core` library later in this post. So, even if you prefer to keep the Cargo.toml option, make sure to include this option.) + +[stack unwinding]: https://www.bogotobogo.com/cplusplus/stackunwinding.php + +```json +"disable-redzone": true, +``` + +We're writing a kernel, so we'll need to handle interrupts at some point. To do that safely, we have to disable a certain stack pointer optimization called the _“red zone”_, because it would cause stack corruption otherwise. For more information, see our separate post about [disabling the red zone]. + +[disabling the red zone]: @/edition-2/posts/02-minimal-rust-kernel/disable-red-zone/index.md + +```json +"features": "-mmx,-sse,+soft-float", +``` + +The `features` field enables/disables target features. We disable the `mmx` and `sse` features by prefixing them with a minus and enable the `soft-float` feature by prefixing it with a plus. Note that there must be no spaces between different flags, otherwise LLVM fails to interpret the features string. + +The `mmx` and `sse` features determine support for [Single Instruction Multiple Data (SIMD)] instructions, which can often speed up programs significantly. However, using the large SIMD registers in OS kernels leads to performance problems. The reason is that the kernel needs to restore all registers to their original state before continuing an interrupted program. This means that the kernel has to save the complete SIMD state to main memory on each system call or hardware interrupt. Since the SIMD state is very large (512–1600 bytes) and interrupts can occur very often, these additional save/restore operations considerably harm performance. To avoid this, we disable SIMD for our kernel (not for applications running on top!). + +[Single Instruction Multiple Data (SIMD)]: https://en.wikipedia.org/wiki/SIMD + +A problem with disabling SIMD is that floating point operations on `x86_64` require SIMD registers by default. To solve this problem, we add the `soft-float` feature, which emulates all floating point operations through software functions based on normal integers. + +For more information, see our post on [disabling SIMD](@/edition-2/posts/02-minimal-rust-kernel/disable-simd/index.md). + +#### Putting it Together +Our target specification file now looks like this: + +```json +{ + "llvm-target": "x86_64-unknown-none", + "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", + "arch": "x86_64", + "target-endian": "little", + "target-pointer-width": "64", + "target-c-int-width": "32", + "os": "none", + "executables": true, + "linker-flavor": "ld.lld", + "linker": "rust-lld", + "panic-strategy": "abort", + "disable-redzone": true, + "features": "-mmx,-sse,+soft-float" +} +``` + +### Building our Kernel +Compiling for our new target will use Linux conventions (I'm not quite sure why; I assume it's just LLVM's default). This means that we need an entry point named `_start` as described in the [previous post]: + +[previous post]: @/edition-2/posts/01-freestanding-rust-binary/index.md + +```rust +// src/main.rs + +#![no_std] // don't link the Rust standard library +#![no_main] // disable all Rust-level entry points + +use core::panic::PanicInfo; + +/// This function is called on panic. +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + loop {} +} + +#[no_mangle] // don't mangle the name of this function +pub extern "C" fn _start() -> ! { + // this function is the entry point, since the linker looks for a function + // named `_start` by default + loop {} +} +``` + +Note that the entry point needs to be called `_start` regardless of your host OS. + +We can now build the kernel for our new target by passing the name of the JSON file as `--target`: + +``` +> cargo build --target x86_64-blog_os.json + +error[E0463]: can't find crate for `core` +``` + +It fails! The error tells us that the Rust compiler no longer finds the [`core` library]. This library contains basic Rust types such as `Result`, `Option`, and iterators, and is implicitly linked to all `no_std` crates. + +[`core` library]: https://doc.rust-lang.org/nightly/core/index.html + +The problem is that the core library is distributed together with the Rust compiler as a _precompiled_ library. So it is only valid for supported host triples (e.g., `x86_64-unknown-linux-gnu`) but not for our custom target. If we want to compile code for other targets, we need to recompile `core` for these targets first. + +#### The `build-std` Option + +That's where the [`build-std` feature] of cargo comes in. It allows to recompile `core` and other standard library crates on demand, instead of using the precompiled versions shipped with the Rust installation. This feature is very new and still not finished, so it is marked as "unstable" and only available on [nightly Rust compilers]. + +[`build-std` feature]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std +[nightly Rust compilers]: #installing-rust-nightly + +To use the feature, we need to create a [cargo configuration] file at `.cargo/config.toml` with the following content: + +```toml +# in .cargo/config.toml + +[unstable] +build-std = ["core", "compiler_builtins"] +``` + +This tells cargo that it should recompile the `core` and `compiler_builtins` libraries. The latter is required because it is a dependency of `core`. In order to recompile these libraries, cargo needs access to the rust source code, which we can install with `rustup component add rust-src`. + +
+ +**Note:** The `unstable.build-std` configuration key requires at least the Rust nightly from 2020-07-15. + +
+ +After setting the `unstable.build-std` configuration key and installing the `rust-src` component, we can rerun our build command: + +``` +> cargo build --target x86_64-blog_os.json + Compiling core v0.0.0 (/…/rust/src/libcore) + Compiling rustc-std-workspace-core v1.99.0 (/…/rust/src/tools/rustc-std-workspace-core) + Compiling compiler_builtins v0.1.32 + Compiling blog_os v0.1.0 (/…/blog_os) + Finished dev [unoptimized + debuginfo] target(s) in 0.29 secs +``` + +We see that `cargo build` now recompiles the `core`, `rustc-std-workspace-core` (a dependency of `compiler_builtins`), and `compiler_builtins` libraries for our custom target. + +#### Memory-Related Intrinsics + +The Rust compiler assumes that a certain set of built-in functions is available for all systems. Most of these functions are provided by the `compiler_builtins` crate that we just recompiled. However, there are some memory-related functions in that crate that are not enabled by default because they are normally provided by the C library on the system. These functions include `memset`, which sets all bytes in a memory block to a given value, `memcpy`, which copies one memory block to another, and `memcmp`, which compares two memory blocks. While we didn't need any of these functions to compile our kernel right now, they will be required as soon as we add some more code to it (e.g. when copying structs around). + +Since we can't link to the C library of the operating system, we need an alternative way to provide these functions to the compiler. One possible approach for this could be to implement our own `memset` etc. functions and apply the `#[no_mangle]` attribute to them (to avoid the automatic renaming during compilation). However, this is dangerous since the slightest mistake in the implementation of these functions could lead to undefined behavior. For example, implementing `memcpy` with a `for` loop may result in an infinite recursion because `for` loops implicitly call the [`IntoIterator::into_iter`] trait method, which may call `memcpy` again. So it's a good idea to reuse existing, well-tested implementations instead. + +[`IntoIterator::into_iter`]: https://doc.rust-lang.org/stable/core/iter/trait.IntoIterator.html#tymethod.into_iter + +Fortunately, the `compiler_builtins` crate already contains implementations for all the needed functions, they are just disabled by default to not collide with the implementations from the C library. We can enable them by setting cargo's [`build-std-features`] flag to `["compiler-builtins-mem"]`. Like the `build-std` flag, this flag can be either passed on the command line as a `-Z` flag or configured in the `unstable` table in the `.cargo/config.toml` file. Since we always want to build with this flag, the config file option makes more sense for us: + +[`build-std-features`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std-features + +```toml +# in .cargo/config.toml + +[unstable] +build-std-features = ["compiler-builtins-mem"] +build-std = ["core", "compiler_builtins"] +``` + +(Support for the `compiler-builtins-mem` feature was only [added very recently](https://github.com/rust-lang/rust/pull/77284), so you need at least Rust nightly `2020-09-30` for it.) + +Behind the scenes, this flag enables the [`mem` feature] of the `compiler_builtins` crate. The effect of this is that the `#[no_mangle]` attribute is applied to the [`memcpy` etc. implementations] of the crate, which makes them available to the linker. + +[`mem` feature]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/Cargo.toml#L54-L55 +[`memcpy` etc. implementations]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/src/mem.rs#L12-L69 + +With this change, our kernel has valid implementations for all compiler-required functions, so it will continue to compile even if our code gets more complex. + +#### Set a Default Target + +To avoid passing the `--target` parameter on every invocation of `cargo build`, we can override the default target. To do this, we add the following to our [cargo configuration] file at `.cargo/config.toml`: + +[cargo configuration]: https://doc.rust-lang.org/cargo/reference/config.html + +```toml +# in .cargo/config.toml + +[build] +target = "x86_64-blog_os.json" +``` + +This tells `cargo` to use our `x86_64-blog_os.json` target when no explicit `--target` argument is passed. This means that we can now build our kernel with a simple `cargo build`. For more information on cargo configuration options, check out the [official documentation][cargo configuration]. + +We are now able to build our kernel for a bare metal target with a simple `cargo build`. However, our `_start` entry point, which will be called by the boot loader, is still empty. It's time that we output something to screen from it. + +### Printing to Screen +The easiest way to print text to the screen at this stage is the [VGA text buffer]. It is a special memory area mapped to the VGA hardware that contains the contents displayed on screen. It normally consists of 25 lines that each contain 80 character cells. Each character cell displays an ASCII character with some foreground and background colors. The screen output looks like this: + +[VGA text buffer]: https://en.wikipedia.org/wiki/VGA-compatible_text_mode + +![screen output for common ASCII characters](https://upload.wikimedia.org/wikipedia/commons/f/f8/Codepage-437.png) + +We will discuss the exact layout of the VGA buffer in the next post, where we write a first small driver for it. For printing “Hello World!”, we just need to know that the buffer is located at address `0xb8000` and that each character cell consists of an ASCII byte and a color byte. + +The implementation looks like this: + +```rust +static HELLO: &[u8] = b"Hello World!"; + +#[no_mangle] +pub extern "C" fn _start() -> ! { + let vga_buffer = 0xb8000 as *mut u8; + + for (i, &byte) in HELLO.iter().enumerate() { + unsafe { + *vga_buffer.offset(i as isize * 2) = byte; + *vga_buffer.offset(i as isize * 2 + 1) = 0xb; + } + } + + loop {} +} +``` + +First, we cast the integer `0xb8000` into a [raw pointer]. Then we [iterate] over the bytes of the [static] `HELLO` [byte string]. We use the [`enumerate`] method to additionally get a running variable `i`. In the body of the for loop, we use the [`offset`] method to write the string byte and the corresponding color byte (`0xb` is a light cyan). + +[iterate]: https://doc.rust-lang.org/stable/book/ch13-02-iterators.html +[static]: https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#the-static-lifetime +[`enumerate`]: https://doc.rust-lang.org/core/iter/trait.Iterator.html#method.enumerate +[byte string]: https://doc.rust-lang.org/reference/tokens.html#byte-string-literals +[raw pointer]: https://doc.rust-lang.org/stable/book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer +[`offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.offset + +Note that there's an [`unsafe`] block around all memory writes. The reason is that the Rust compiler can't prove that the raw pointers we create are valid. They could point anywhere and lead to data corruption. By putting them into an `unsafe` block, we're basically telling the compiler that we are absolutely sure that the operations are valid. Note that an `unsafe` block does not turn off Rust's safety checks. It only allows you to do [five additional things]. + +[`unsafe`]: https://doc.rust-lang.org/stable/book/ch19-01-unsafe-rust.html +[five additional things]: https://doc.rust-lang.org/stable/book/ch19-01-unsafe-rust.html#unsafe-superpowers + +I want to emphasize that **this is not the way we want to do things in Rust!** It's very easy to mess up when working with raw pointers inside unsafe blocks. For example, we could easily write beyond the buffer's end if we're not careful. + +So we want to minimize the use of `unsafe` as much as possible. Rust gives us the ability to do this by creating safe abstractions. For example, we could create a VGA buffer type that encapsulates all unsafety and ensures that it is _impossible_ to do anything wrong from the outside. This way, we would only need minimal amounts of `unsafe` code and can be sure that we don't violate [memory safety]. We will create such a safe VGA buffer abstraction in the next post. + +[memory safety]: https://en.wikipedia.org/wiki/Memory_safety + +## Running our Kernel + +Now that we have an executable that does something perceptible, it is time to run it. First, we need to turn our compiled kernel into a bootable disk image by linking it with a bootloader. Then we can run the disk image in the [QEMU] virtual machine or boot it on real hardware using a USB stick. + +### Creating a Bootimage + +To turn our compiled kernel into a bootable disk image, we need to link it with a bootloader. As we learned in the [section about booting], the bootloader is responsible for initializing the CPU and loading our kernel. + +[section about booting]: #the-boot-process + +Instead of writing our own bootloader, which is a project on its own, we use the [`bootloader`] crate. This crate implements a basic BIOS bootloader without any C dependencies, just Rust and inline assembly. To use it for booting our kernel, we need to add a dependency on it: + +[`bootloader`]: https://crates.io/crates/bootloader + +```toml +# in Cargo.toml + +[dependencies] +bootloader = "0.9.8" +``` + +Adding the bootloader as a dependency is not enough to actually create a bootable disk image. The problem is that we need to link our kernel with the bootloader after compilation, but cargo has no support for [post-build scripts]. + +[post-build scripts]: https://github.com/rust-lang/cargo/issues/545 + +To solve this problem, we created a tool named `bootimage` that first compiles the kernel and bootloader, and then links them together to create a bootable disk image. To install the tool, execute the following command in your terminal: + +``` +cargo install bootimage +``` + +For running `bootimage` and building the bootloader, you need to have the `llvm-tools-preview` rustup component installed. You can do so by executing `rustup component add llvm-tools-preview`. + +After installing `bootimage` and adding the `llvm-tools-preview` component, we can create a bootable disk image by executing: + +``` +> cargo bootimage +``` + +We see that the tool recompiles our kernel using `cargo build`, so it will automatically pick up any changes you make. Afterwards, it compiles the bootloader, which might take a while. Like all crate dependencies, it is only built once and then cached, so subsequent builds will be much faster. Finally, `bootimage` combines the bootloader and your kernel into a bootable disk image. + +After executing the command, you should see a bootable disk image named `bootimage-blog_os.bin` in your `target/x86_64-blog_os/debug` directory. You can boot it in a virtual machine or copy it to a USB drive to boot it on real hardware. (Note that this is not a CD image, which has a different format, so burning it to a CD doesn't work). + +#### How does it work? +The `bootimage` tool performs the following steps behind the scenes: + +- It compiles our kernel to an [ELF] file. +- It compiles the bootloader dependency as a standalone executable. +- It links the bytes of the kernel ELF file to the bootloader. + +[ELF]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format +[rust-osdev/bootloader]: https://github.com/rust-osdev/bootloader + +When booted, the bootloader reads and parses the appended ELF file. It then maps the program segments to virtual addresses in the page tables, zeroes the `.bss` section, and sets up a stack. Finally, it reads the entry point address (our `_start` function) and jumps to it. + +### Booting it in QEMU + +We can now boot the disk image in a virtual machine. To boot it in [QEMU], execute the following command: + +[QEMU]: https://www.qemu.org/ + +``` +> qemu-system-x86_64 -drive format=raw,file=target/x86_64-blog_os/debug/bootimage-blog_os.bin +warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5] +``` + +This opens a separate window which should look similar to this: + +![QEMU showing "Hello World!"](qemu.png) + +We see that our "Hello World!" is visible on the screen. + +### Real Machine + +It is also possible to write it to a USB stick and boot it on a real machine, **but be careful** to choose the correct device name, because **everything on that device is overwritten**: + +``` +> dd if=target/x86_64-blog_os/debug/bootimage-blog_os.bin of=/dev/sdX && sync +``` + +Where `sdX` is the device name of your USB stick. + +After writing the image to the USB stick, you can run it on real hardware by booting from it. You probably need to use a special boot menu or change the boot order in your BIOS configuration to boot from the USB stick. Note that it currently doesn't work for UEFI machines, since the `bootloader` crate has no UEFI support yet. + +### Using `cargo run` + +To make it easier to run our kernel in QEMU, we can set the `runner` configuration key for cargo: + +```toml +# in .cargo/config.toml + +[target.'cfg(target_os = "none")'] +runner = "bootimage runner" +``` + +The `target.'cfg(target_os = "none")'` table applies to all targets whose target configuration file's `"os"` field is set to `"none"`. This includes our `x86_64-blog_os.json` target. The `runner` key specifies the command that should be invoked for `cargo run`. The command is run after a successful build with the executable path passed as the first argument. See the [cargo documentation][cargo configuration] for more details. + +The `bootimage runner` command is specifically designed to be usable as a `runner` executable. It links the given executable with the project's bootloader dependency and then launches QEMU. See the [Readme of `bootimage`] for more details and possible configuration options. + +[Readme of `bootimage`]: https://github.com/rust-osdev/bootimage + +Now we can use `cargo run` to compile our kernel and boot it in QEMU. + +## What's next? + +In the next post, we will explore the VGA text buffer in more detail and write a safe interface for it. We will also add support for the `println` macro. From 20b306d7a489f0dd4865d8ddfbe9498423634a93 Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sat, 1 Oct 2022 19:21:47 -0400 Subject: [PATCH 02/23] Translate the last two paragraphs --- .../posts/02-minimal-rust-kernel/index.fr.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index ce83bb5b..722a62a0 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -473,25 +473,25 @@ Where `sdX` is the device name of your USB stick. After writing the image to the USB stick, you can run it on real hardware by booting from it. You probably need to use a special boot menu or change the boot order in your BIOS configuration to boot from the USB stick. Note that it currently doesn't work for UEFI machines, since the `bootloader` crate has no UEFI support yet. -### Using `cargo run` +### Utilisation de `cargo run` -To make it easier to run our kernel in QEMU, we can set the `runner` configuration key for cargo: +Pour faciliter l'exécution de notre noyau dans QEMU, nous pouvons définir la clé de configuration `runner` pour cargo: ```toml -# in .cargo/config.toml +# dans .cargo/config.toml [target.'cfg(target_os = "none")'] runner = "bootimage runner" ``` -The `target.'cfg(target_os = "none")'` table applies to all targets whose target configuration file's `"os"` field is set to `"none"`. This includes our `x86_64-blog_os.json` target. The `runner` key specifies the command that should be invoked for `cargo run`. The command is run after a successful build with the executable path passed as the first argument. See the [cargo documentation][cargo configuration] for more details. +La table `target.'cfg(target_os = "none")'` s'applique à toutes les cibles dont le champ `"os"` dans le fichier de configuration est défini à `"none"`. Ceci inclut notre cible `x86_64-blog_os.json`. La clé `runner` key spécifie la commande qui doit être invoquée pour `cargo run`. La commande est exécutée après une construction réussie avec le chemin de l'exécutable comme premier argument. Voir la [configuration cargo][cargo configuration] pour plus de détails. -The `bootimage runner` command is specifically designed to be usable as a `runner` executable. It links the given executable with the project's bootloader dependency and then launches QEMU. See the [Readme of `bootimage`] for more details and possible configuration options. +La commande `bootimage runner` est spécifiquement conçue pour être utilisable comme un exécutable `runner`. Elle lie l'exécutable fourni avec le bootloader duquel le projet dépend et lance ensuite QEMU. Voir le [Readme of `bootimage`][README de `bootimage`] pour plus de détails et les options de configuration possibles. [Readme of `bootimage`]: https://github.com/rust-osdev/bootimage -Now we can use `cargo run` to compile our kernel and boot it in QEMU. +Nous pouvons maintenant utiliser `cargo run` pour compiler notre noyau et le lancer dans QEMU. -## What's next? +## Et ensuite? -In the next post, we will explore the VGA text buffer in more detail and write a safe interface for it. We will also add support for the `println` macro. +Dans le prochain article, nous explorerons le tampon texte VGA plus en détails et nous écrirons une interface sécuritaire pour l'utiliser. Nous allons aussi mettre en place la macro `println`. From 7332d3d3320703d83a54d2c61f9e76f26aef8af3 Mon Sep 17 00:00:00 2001 From: TheMimiCodes Date: Sat, 1 Oct 2022 19:21:43 -0400 Subject: [PATCH 03/23] translate the first two paragraphs --- .../posts/02-minimal-rust-kernel/index.fr.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index 722a62a0..9f1d25cb 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -1,7 +1,7 @@ +++ -title = "A Minimal Rust Kernel" +title = "Un noyau Rust minimal" weight = 2 -path = "minimal-rust-kernel" +path = "fr/minimal-rust-kernel" date = 2018-02-10 [extra] @@ -12,36 +12,36 @@ translation_based_on_commit = "c689ecf810f8e93f6b2fb3c4e1e8b89b8a0998eb" translators = ["TheMimiCodes", "maximevaillancourt"] +++ -In this post, we create a minimal 64-bit Rust kernel for the x86 architecture. We build upon the [freestanding Rust binary] from the previous post to create a bootable disk image that prints something to the screen. +Dans cet article, nous créons un noyau Rust minimal 64-bit pour l'architecture x86. Nous continuons le travail fait dans l'article précédent [freestanding Rust binary] pour créer une image de disque amorçable qui imprime quelque chose à l'écran. [freestanding Rust binary]: @/edition-2/posts/01-freestanding-rust-binary/index.md -This blog is openly developed on [GitHub]. If you have any problems or questions, please open an issue there. You can also leave comments [at the bottom]. The complete source code for this post can be found in the [`post-02`][post branch] branch. +Cet article est développé ouvertement sur [GitHub]. Si vous avez des problèmes ou des questions, veuillez ouvrir une Issue sur GitHub. Vous pouvez aussi laisser un commentaire [au bas de la page]. Le code source complet pour cet article peut être trouvé dans la branche [`post-02`][post branch]. [GitHub]: https://github.com/phil-opp/blog_os -[at the bottom]: #comments +[au bas de la page]: #comments [post branch]: https://github.com/phil-opp/blog_os/tree/post-02 ## The Boot Process -When you turn on a computer, it begins executing firmware code that is stored in motherboard [ROM]. This code performs a [power-on self-test], detects available RAM, and pre-initializes the CPU and hardware. Afterwards, it looks for a bootable disk and starts booting the operating system kernel. +QUand vous ouvrez un ordinateur, il commence à exécuter le code du micrologiciel qui est enregistré dans la carte maîtresse[ROM]. Ce code performe un [power-on self-test], détecte la mémoire volatile disponible, et pré-initialise le CPU et le matériel. Par la suite, il recherche un disque amorçable et commence le processus d'amorçage du noyau du système d'exploitation. [ROM]: https://en.wikipedia.org/wiki/Read-only_memory [power-on self-test]: https://en.wikipedia.org/wiki/Power-on_self-test -On x86, there are two firmware standards: the “Basic Input/Output System“ (**[BIOS]**) and the newer “Unified Extensible Firmware Interface” (**[UEFI]**). The BIOS standard is old and outdated, but simple and well-supported on any x86 machine since the 1980s. UEFI, in contrast, is more modern and has much more features, but is more complex to set up (at least in my opinion). +Sur x86, il y a deux standards pour les micrologiciels: le “Basic Input/Output System“ (**[BIOS]**) et le nouvel “Unified Extensible Firmware Interface” (**[UEFI]**). Le BIOS standard est vieux et dépassé, mais il est simple et bien suporté sur toutes les machines x86 depuis les années 1980. Au contraire, l'UEFI, est plutôt moderne et il offre davantage de fonctionnalités, cependant, il est plus complexe à installer (du moins, selon moi). [BIOS]: https://en.wikipedia.org/wiki/BIOS [UEFI]: https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface -Currently, we only provide BIOS support, but support for UEFI is planned, too. If you'd like to help us with this, check out the [Github issue](https://github.com/phil-opp/blog_os/issues/349). +Actuellement, nous offrons seulement un support BIOS, mais nous planifions aussi du support pour l'UEFI. Si vous aimeriez nous aider avec cela, consultez [Github issue](https://github.com/phil-opp/blog_os/issues/349). ### BIOS Boot -Almost all x86 systems have support for BIOS booting, including newer UEFI-based machines that use an emulated BIOS. This is great, because you can use the same boot logic across all machines from the last century. But this wide compatibility is at the same time the biggest disadvantage of BIOS booting, because it means that the CPU is put into a 16-bit compatibility mode called [real mode] before booting so that archaic bootloaders from the 1980s would still work. +Presque tous les systèmes x86 ont des support pour amorcer le BIOS, incluant les récentes machine UEFI-based qui utilisent un BIOS émulé. C'est bien étant donné que vous pouvez utiliser la même logique d'armorçage sur toutes les machines du dernier siècle. De plus, cette grande compatibilité est à la fois le plus grand désavantage de l'amorçage BIOS. En effet, cela signifie que le CPU est mis dans un mode de compatibilité 16-bit appelé [real mode] avant l'amorçage afin que les bootloaders archaïques des années 1980 puissent encore fonctionner. But let's start from the beginning: From 5b5e72425e2020b6bd6ab14e04595a980742848f Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sat, 1 Oct 2022 19:40:46 -0400 Subject: [PATCH 04/23] Translate "Real machine" paragraph --- .../edition-2/posts/02-minimal-rust-kernel/index.fr.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index 9f1d25cb..f7f7716b 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -461,17 +461,17 @@ This opens a separate window which should look similar to this: We see that our "Hello World!" is visible on the screen. -### Real Machine +### Véritable ordinateur -It is also possible to write it to a USB stick and boot it on a real machine, **but be careful** to choose the correct device name, because **everything on that device is overwritten**: +Il est aussi possible de l'écrire sur une clé USB et de le lancer sur un véritable ordinateur, **mais soyez prudent** et choisissez le bon nom de périphérique, parce que **tout sur ce périphérique sera écrasé**: ``` > dd if=target/x86_64-blog_os/debug/bootimage-blog_os.bin of=/dev/sdX && sync ``` -Where `sdX` is the device name of your USB stick. +Où `sdX` est le nom du périphérique de votre clé USB. -After writing the image to the USB stick, you can run it on real hardware by booting from it. You probably need to use a special boot menu or change the boot order in your BIOS configuration to boot from the USB stick. Note that it currently doesn't work for UEFI machines, since the `bootloader` crate has no UEFI support yet. +Après l'écriture de l'image sur votre clé USB, vous pouvez l'exécuter sur du véritable matériel en l'amorçant à partir de la clé USB. Vous devrez probablement utiliser un menu d'amorçage spécial ou changer l'ordre d'amorçage dans votre configuration BIOS pour amorcer à partir de la clé USB. Notez que cela ne fonctionne actuellement pas avec des ordinateurs UEFI, puisque la caisse `bootloader` ne supporte pas encore UEFI. ### Utilisation de `cargo run` From ea70ed128c4336c91e8a79c841995126226c77c5 Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sat, 1 Oct 2022 19:48:16 -0400 Subject: [PATCH 05/23] Translate "Booting it in QEMU" paragraph --- .../edition-2/posts/02-minimal-rust-kernel/index.fr.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index f7f7716b..43793554 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -444,9 +444,9 @@ The `bootimage` tool performs the following steps behind the scenes: When booted, the bootloader reads and parses the appended ELF file. It then maps the program segments to virtual addresses in the page tables, zeroes the `.bss` section, and sets up a stack. Finally, it reads the entry point address (our `_start` function) and jumps to it. -### Booting it in QEMU +### Amorçage dans QEMU -We can now boot the disk image in a virtual machine. To boot it in [QEMU], execute the following command: +Nous pouvons maintenant lancer l'image disque dans une machine virtuelle. Pour la démarrer dans [QEMU], exécutez la commande suivante : [QEMU]: https://www.qemu.org/ @@ -455,15 +455,15 @@ We can now boot the disk image in a virtual machine. To boot it in [QEMU], execu warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5] ``` -This opens a separate window which should look similar to this: +Ceci ouvre une fenêtre séparée qui devrait ressembler à cela: ![QEMU showing "Hello World!"](qemu.png) -We see that our "Hello World!" is visible on the screen. +Nous voyoons que notre "Hello World!" est visible à l'écran. ### Véritable ordinateur -Il est aussi possible de l'écrire sur une clé USB et de le lancer sur un véritable ordinateur, **mais soyez prudent** et choisissez le bon nom de périphérique, parce que **tout sur ce périphérique sera écrasé**: +Il est aussi possible d'écrire l'image disque sur une clé USB et de le lancer sur un véritable ordinateur, **mais soyez prudent** et choisissez le bon nom de périphérique, parce que **tout sur ce périphérique sera écrasé**: ``` > dd if=target/x86_64-blog_os/debug/bootimage-blog_os.bin of=/dev/sdX && sync From 1030e8262188ae20ef1d5aaf796706971620056d Mon Sep 17 00:00:00 2001 From: TheMimiCodes Date: Sat, 1 Oct 2022 19:50:12 -0400 Subject: [PATCH 06/23] Translate "BIOS boot" paragraph --- .../edition-2/posts/02-minimal-rust-kernel/index.fr.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index 43793554..1f7fa828 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -43,22 +43,22 @@ Actuellement, nous offrons seulement un support BIOS, mais nous planifions aussi ### BIOS Boot Presque tous les systèmes x86 ont des support pour amorcer le BIOS, incluant les récentes machine UEFI-based qui utilisent un BIOS émulé. C'est bien étant donné que vous pouvez utiliser la même logique d'armorçage sur toutes les machines du dernier siècle. De plus, cette grande compatibilité est à la fois le plus grand désavantage de l'amorçage BIOS. En effet, cela signifie que le CPU est mis dans un mode de compatibilité 16-bit appelé [real mode] avant l'amorçage afin que les bootloaders archaïques des années 1980 puissent encore fonctionner. -But let's start from the beginning: +Commençons par le commencement: -When you turn on a computer, it loads the BIOS from some special flash memory located on the motherboard. The BIOS runs self-test and initialization routines of the hardware, then it looks for bootable disks. If it finds one, control is transferred to its _bootloader_, which is a 512-byte portion of executable code stored at the disk's beginning. Most bootloaders are larger than 512 bytes, so bootloaders are commonly split into a small first stage, which fits into 512 bytes, and a second stage, which is subsequently loaded by the first stage. +Quand vous ouvrez votre ordinateur, il charge le BIOS provenant d'un emplacement de mémoire flash spéciale localisée sur la carte maîtresse. Le BIOS exécute des tests d'auto-diagnostic et es routines d'initialisation du matériel, puis il cherche des disques amorçables. S'il en trouve un, le contrôle est transféré à its _bootloader_, qui est une portion 512-byte du code exécutable enregistré au début du disque. La pluplart des bootloaders sont plus gros que 512 bytes, alors les bootloaders sont communément séparés en deux étapes. La première étape, est de 512 bytes, et la seconde étape, est chargé subséquemment à la première étapge. -The bootloader has to determine the location of the kernel image on the disk and load it into memory. It also needs to switch the CPU from the 16-bit [real mode] first to the 32-bit [protected mode], and then to the 64-bit [long mode], where 64-bit registers and the complete main memory are available. Its third job is to query certain information (such as a memory map) from the BIOS and pass it to the OS kernel. +Le bootloader doit déterminé la localisation de l'image de noyau sur le disque et de la télécharger dans sa mémoire. Il doit aussi transformer le CPU 16-bit [real mode] en un 32-bit [protected mode], puis en un 64-bit [long mode], où les registres 64-bit et la mémoire maîtresse complète sont disponibles. Sa troisième tâche est de récupérer certaines informations (telle que les associations mémoires) du BIOS et les passer au noyau du système d'exploitation. [real mode]: https://en.wikipedia.org/wiki/Real_mode [protected mode]: https://en.wikipedia.org/wiki/Protected_mode [long mode]: https://en.wikipedia.org/wiki/Long_mode [memory segmentation]: https://en.wikipedia.org/wiki/X86_memory_segmentation -Writing a bootloader is a bit cumbersome as it requires assembly language and a lot of non insightful steps like “write this magic value to this processor register”. Therefore, we don't cover bootloader creation in this post and instead provide a tool named [bootimage] that automatically prepends a bootloader to your kernel. +Implémenter un bootloader est délicat puisque cela requiert l'écriture de code assembleur et plusieurs autres étapes particulières comme “write this magic value to this processor register”. Par conséquent, nous ne couvrons pas la création d'un bootoader dans cet article et nous fournissons plutôt un outil appelé [bootimage] qui ajoute automatiquement un bootloader à votre noyau. [bootimage]: https://github.com/rust-osdev/bootimage -If you are interested in building your own bootloader: Stay tuned, a set of posts on this topic is already planned! +Si vous êtes intéressé à créer votre propre booloader : Gardez l'oeil ouvert, plusieurs articles sur ce sujet sont déjà prévus! #### The Multiboot Standard To avoid that every operating system implements its own bootloader, which is only compatible with a single OS, the [Free Software Foundation] created an open bootloader standard called [Multiboot] in 1995. The standard defines an interface between the bootloader and the operating system, so that any Multiboot-compliant bootloader can load any Multiboot-compliant operating system. The reference implementation is [GNU GRUB], which is the most popular bootloader for Linux systems. From a95c6d1745a7d12da8faf7f398359c00b65cc050 Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sat, 1 Oct 2022 19:55:07 -0400 Subject: [PATCH 07/23] Translate "How does it work" paragraph --- .../posts/02-minimal-rust-kernel/index.fr.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index 1f7fa828..d9247840 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -432,17 +432,18 @@ We see that the tool recompiles our kernel using `cargo build`, so it will autom After executing the command, you should see a bootable disk image named `bootimage-blog_os.bin` in your `target/x86_64-blog_os/debug` directory. You can boot it in a virtual machine or copy it to a USB drive to boot it on real hardware. (Note that this is not a CD image, which has a different format, so burning it to a CD doesn't work). -#### How does it work? -The `bootimage` tool performs the following steps behind the scenes: +#### Comment cela fonctionne-t-il? -- It compiles our kernel to an [ELF] file. -- It compiles the bootloader dependency as a standalone executable. -- It links the bytes of the kernel ELF file to the bootloader. +L'outil `bootimage` effectue les étapes suivantes en arrière-plan: + +- Il compile notre noyau en un fichier [ELF]. +- Il compile notre dépendance bootloader en exécutable autonome. +- Il lie les octets du fichier ELF noyau au bootloader. [ELF]: https://en.wikipedia.org/wiki/Executable_and_Linkable_Format [rust-osdev/bootloader]: https://github.com/rust-osdev/bootloader -When booted, the bootloader reads and parses the appended ELF file. It then maps the program segments to virtual addresses in the page tables, zeroes the `.bss` section, and sets up a stack. Finally, it reads the entry point address (our `_start` function) and jumps to it. +Lorsque lancé, le bootloader lit et analyse le fichier ELF ajouté. Il associe ensuite les segments du programme aux adresses virtuelles dans les tables de pages, réinitialise la section `.bss`, puis met en place une pile. Finalement, il lit le point d'entrée (notre fonction `_start`) et s'y rend. ### Amorçage dans QEMU From f339bca0bf8f76ed0cb91c76ffd68c102cd243fe Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sat, 1 Oct 2022 20:13:31 -0400 Subject: [PATCH 08/23] Translate "Creating a bootimage" paragraph --- .../posts/02-minimal-rust-kernel/index.fr.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index d9247840..f1501c40 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -393,44 +393,44 @@ So we want to minimize the use of `unsafe` as much as possible. Rust gives us th Now that we have an executable that does something perceptible, it is time to run it. First, we need to turn our compiled kernel into a bootable disk image by linking it with a bootloader. Then we can run the disk image in the [QEMU] virtual machine or boot it on real hardware using a USB stick. -### Creating a Bootimage +### Créer une image d'amorçage -To turn our compiled kernel into a bootable disk image, we need to link it with a bootloader. As we learned in the [section about booting], the bootloader is responsible for initializing the CPU and loading our kernel. +Pour transformer notre noyau compilé en image de disque amorçable, nous devons le lier avec un bootloader. Comme nous l'avons appris dans la [section about booting][section à propos du lancement], le bootloader est responsable de lancer le CPU et de charger notre noyau. [section about booting]: #the-boot-process -Instead of writing our own bootloader, which is a project on its own, we use the [`bootloader`] crate. This crate implements a basic BIOS bootloader without any C dependencies, just Rust and inline assembly. To use it for booting our kernel, we need to add a dependency on it: +Plutôt que d'écrire notre propre bootloader, ce qui est un projet en soi, nous utilisons la caisse [`bootloader`]. Cette caisse propose un bootloader BIOS de base sans dépendance C, seulement du code Rust et de l'assembleur intégré. Pour l'utiliser pour lancer notre noyau, nous devons ajouter une dépendance pour cette caisse: [`bootloader`]: https://crates.io/crates/bootloader ```toml -# in Cargo.toml +# dans Cargo.toml [dependencies] bootloader = "0.9.8" ``` -Adding the bootloader as a dependency is not enough to actually create a bootable disk image. The problem is that we need to link our kernel with the bootloader after compilation, but cargo has no support for [post-build scripts]. +Ajouter le bootloader comme dépendance n'est pas suffisant pour réellement créer une image de disque amorçable. Le problème est que nous devons lier notre noyau avec le bootloader après la compilation, mais cargo ne supporte pas les [post-build scripts][scripts post-build]. [post-build scripts]: https://github.com/rust-lang/cargo/issues/545 -To solve this problem, we created a tool named `bootimage` that first compiles the kernel and bootloader, and then links them together to create a bootable disk image. To install the tool, execute the following command in your terminal: +Pour résoudre ce problème, nous avons créé un outil nommé `bootimage` qui compile d'abord le noyau et le bootloader, et les lie ensuite ensemble pour créer une image de disque amorçable. Pour installer cet outil, exécutez la commande suivante dans votre terminal: ``` cargo install bootimage ``` -For running `bootimage` and building the bootloader, you need to have the `llvm-tools-preview` rustup component installed. You can do so by executing `rustup component add llvm-tools-preview`. +Pour exécuter `bootimage` et construire le bootloader, vous devez avoir la composante rustup `llvm-tools-preview` installée. Vous pouvez l'installer en exécutant `rustup component add llvm-tools-preview`. -After installing `bootimage` and adding the `llvm-tools-preview` component, we can create a bootable disk image by executing: +Après avoir installé `bootimage` and ajouté la composante `llvm-tools-preview`, nous pouvons créer une image de disque amorçable en exécutant: ``` > cargo bootimage ``` -We see that the tool recompiles our kernel using `cargo build`, so it will automatically pick up any changes you make. Afterwards, it compiles the bootloader, which might take a while. Like all crate dependencies, it is only built once and then cached, so subsequent builds will be much faster. Finally, `bootimage` combines the bootloader and your kernel into a bootable disk image. +Nous voyons que l'outil recompile notre noyau en utilisant `cargo build`, alors il utilisera automatiquement tout changement que vous faites. Ensuite, il compile le bootloader, ce qui peut prendre un certain temps. Comme toutes les dépendances de caisses, il est seulement construit une fois puis il est mis en cache, donc les builds subséquentes seront beaucoup plus rapides. Enfin, `bootimage` combine le bootloader et le noyau en une image de disque amorçable. -After executing the command, you should see a bootable disk image named `bootimage-blog_os.bin` in your `target/x86_64-blog_os/debug` directory. You can boot it in a virtual machine or copy it to a USB drive to boot it on real hardware. (Note that this is not a CD image, which has a different format, so burning it to a CD doesn't work). +Après avoir exécuté la commande, vous devriez voir une image de disque amorçable nommée `bootimage-blog_os.bin` dans votre dossier `target/x86_64-blog_os/debug`. Vous pouvez la lancer dans une machine virtuelle ou la copier sur une clé USB pour la lancer sur du véritable matériel. (Notez que ceci n'est pas une image CD, qui est un format différent, donc la graver sur un CD ne fonctionne pas). #### Comment cela fonctionne-t-il? @@ -485,7 +485,7 @@ Pour faciliter l'exécution de notre noyau dans QEMU, nous pouvons définir la c runner = "bootimage runner" ``` -La table `target.'cfg(target_os = "none")'` s'applique à toutes les cibles dont le champ `"os"` dans le fichier de configuration est défini à `"none"`. Ceci inclut notre cible `x86_64-blog_os.json`. La clé `runner` key spécifie la commande qui doit être invoquée pour `cargo run`. La commande est exécutée après une construction réussie avec le chemin de l'exécutable comme premier argument. Voir la [configuration cargo][cargo configuration] pour plus de détails. +La table `target.'cfg(target_os = "none")'` s'applique à toutes les cibles dont le champ `"os"` dans le fichier de configuration est défini à `"none"`. Ceci inclut notre cible `x86_64-blog_os.json`. La clé `runner` key spécifie la commande qui doit être invoquée pour `cargo run`. La commande est exécutée après une build réussie avec le chemin de l'exécutable comme premier argument. Voir la [configuration cargo][cargo configuration] pour plus de détails. La commande `bootimage runner` est spécifiquement conçue pour être utilisable comme un exécutable `runner`. Elle lie l'exécutable fourni avec le bootloader duquel le projet dépend et lance ensuite QEMU. Voir le [Readme of `bootimage`][README de `bootimage`] pour plus de détails et les options de configuration possibles. From f0ab5e01c7a1603d0f3e831a400059bba4cf59dd Mon Sep 17 00:00:00 2001 From: TheMimiCodes Date: Sat, 1 Oct 2022 20:14:20 -0400 Subject: [PATCH 09/23] Translate "Multiboot Standard" parapgrah --- .../posts/02-minimal-rust-kernel/index.fr.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index f1501c40..ea7ac569 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -61,25 +61,25 @@ Implémenter un bootloader est délicat puisque cela requiert l'écriture de cod Si vous êtes intéressé à créer votre propre booloader : Gardez l'oeil ouvert, plusieurs articles sur ce sujet sont déjà prévus! #### The Multiboot Standard -To avoid that every operating system implements its own bootloader, which is only compatible with a single OS, the [Free Software Foundation] created an open bootloader standard called [Multiboot] in 1995. The standard defines an interface between the bootloader and the operating system, so that any Multiboot-compliant bootloader can load any Multiboot-compliant operating system. The reference implementation is [GNU GRUB], which is the most popular bootloader for Linux systems. +Pour éviter que chaque système d'opération implémente son propre bootloader, qui est seulement compatible avec un seul système d'exploitation, le [Free Software Foundation] à créé un bootloader public standard appelé [Multiboot] en 1995. Le standard défini une interface entre le bootloader et le système d'opération afin que n'importe quel Multiboot-compliant bootloader puisse charger n'importe quel système d'opérations Multiboot-compliant. La référence d'implementation est [GNU GRUB], qui est le bootloader le plus populaire pour les systèmes Linux. [Free Software Foundation]: https://en.wikipedia.org/wiki/Free_Software_Foundation [Multiboot]: https://wiki.osdev.org/Multiboot [GNU GRUB]: https://en.wikipedia.org/wiki/GNU_GRUB -To make a kernel Multiboot compliant, one just needs to insert a so-called [Multiboot header] at the beginning of the kernel file. This makes it very easy to boot an OS from GRUB. However, GRUB and the Multiboot standard have some problems too: +Pour faire un noyau conforme à la spécification Multiboot, il faut seulement inséré un [Multiboot header] au début du fichier du noyau. Cela fait en sorte que c'est très simple to boot un système d'exploitation depuis GRUB. Cependant, le GRUB et le Multiboot standard présentent aussi des problèmes : [Multiboot header]: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#OS-image-format -- They support only the 32-bit protected mode. This means that you still have to do the CPU configuration to switch to the 64-bit long mode. -- They are designed to make the bootloader simple instead of the kernel. For example, the kernel needs to be linked with an [adjusted default page size], because GRUB can't find the Multiboot header otherwise. Another example is that the [boot information], which is passed to the kernel, contains lots of architecture-dependent structures instead of providing clean abstractions. -- Both GRUB and the Multiboot standard are only sparsely documented. -- GRUB needs to be installed on the host system to create a bootable disk image from the kernel file. This makes development on Windows or Mac more difficult. +- Ils supportent seulement le mode de protection 32-bit. Cela signifie que si vous devez encore faire la configuration du CPU pour changer au 64-bit long mode. +- Ils sont désignés pour faire le bootloader simple plutôt que le noyau. Par exemple, le noyau doit être lié avec un [adjusted default page size], étant donné que le GRUB ne peut pas trouver les entêtes Multiboot autrement. Un autre exemple est que le [boot information], qui est passé au noyau, contient plusieurs structures spécifiques à l'architecture plutôt que de fournir des abstractions pures. +- GRUB et le standard Multiboot sont peu documentés. +- GRUB doit être installé sur un système hôte pour créer une image de disque amorçable depuis le fichier du noyau. Cela rend le développement sur Windows ou sur Mac plus difficile. [adjusted default page size]: https://wiki.osdev.org/Multiboot#Multiboot_2 [boot information]: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format -Because of these drawbacks, we decided to not use GRUB or the Multiboot standard. However, we plan to add Multiboot support to our [bootimage] tool, so that it's possible to load your kernel on a GRUB system too. If you're interested in writing a Multiboot compliant kernel, check out the [first edition] of this blog series. +Because of these drawbacks, nous avons décidé de ne pas utiliser GRUB ou le standard Multiboot. Cependant, nous avons planifié d'ajouter un support Multiboot à notre outil [bootimage], afin qu'il soit aussi possible de charger votre noyau sur un système GRUB. Si vous êtes interessé à écrire un noyau Multiboot conforme, consultez la [first edition] de cette série d'articles. [first edition]: @/edition-1/_index.md From 4337df62366979108332db8bb5b819a00e9aa033 Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sat, 1 Oct 2022 20:15:31 -0400 Subject: [PATCH 10/23] Translate "Running our Kernel" paragraph --- .../edition-2/posts/02-minimal-rust-kernel/index.fr.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index ea7ac569..77e798b9 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -389,9 +389,9 @@ So we want to minimize the use of `unsafe` as much as possible. Rust gives us th [memory safety]: https://en.wikipedia.org/wiki/Memory_safety -## Running our Kernel +## Exécuter notre noyau -Now that we have an executable that does something perceptible, it is time to run it. First, we need to turn our compiled kernel into a bootable disk image by linking it with a bootloader. Then we can run the disk image in the [QEMU] virtual machine or boot it on real hardware using a USB stick. +Maintenant que nous avons un exécutable qui fait quelque chose de perceptible, il est temps de l'exécuter. D'abord, nous devons transformer notre noyau compilé en une image de disque amorçable en le liant à un bootloader. Ensuite, nous pourrons exécuter l'image de disque dans une machine virtuelle [QEMU] ou l'amorcer sur du véritable matériel en utilisant une clé USB. ### Créer une image d'amorçage From 80be2f0a9e60c18332e01d61aa05ec367258b49c Mon Sep 17 00:00:00 2001 From: TheMimiCodes Date: Sat, 1 Oct 2022 20:27:55 -0400 Subject: [PATCH 11/23] Translate "a minimal kernel" paragraph --- .../edition-2/posts/02-minimal-rust-kernel/index.fr.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index 77e798b9..9ccb685f 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -79,18 +79,18 @@ Pour faire un noyau conforme à la spécification Multiboot, il faut seulement i [adjusted default page size]: https://wiki.osdev.org/Multiboot#Multiboot_2 [boot information]: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format -Because of these drawbacks, nous avons décidé de ne pas utiliser GRUB ou le standard Multiboot. Cependant, nous avons planifié d'ajouter un support Multiboot à notre outil [bootimage], afin qu'il soit aussi possible de charger votre noyau sur un système GRUB. Si vous êtes interessé à écrire un noyau Multiboot conforme, consultez la [first edition] de cette série d'articles. +En raison de ces désavantages, nous avons décidé de ne pas utiliser GRUB ou le standard Multiboot. Cependant, nous avons planifié d'ajouter un support Multiboot à notre outil [bootimage], afin qu'il soit aussi possible de charger votre noyau sur un système GRUB. Si vous êtes interessé à écrire un noyau Multiboot conforme, consultez la [first edition] de cette série d'articles. [first edition]: @/edition-1/_index.md ### UEFI -(We don't provide UEFI support at the moment, but we would love to! If you'd like to help, please tell us in the [Github issue](https://github.com/phil-opp/blog_os/issues/349).) +(Nous ne fournissons pas le support UEFI à l'heure actuelle, mais nous aimerions bien! Si vous êtes intéressé à aider, dites-le nous dans le [Github issue](https://github.com/phil-opp/blog_os/issues/349).) ## A Minimal Kernel -Now that we roughly know how a computer boots, it's time to create our own minimal kernel. Our goal is to create a disk image that prints a “Hello World!” to the screen when booted. We do this by extending the previous post's [freestanding Rust binary]. +Maintenant que nous savons à peu près comment un ordinateur démarre, c'est le temps de créer notre propre noyau minimal. Notre objectif est de créé une image de disque qui imprime “Hello World!” à l'écran lorsqu'il démarre. Nous faisons ceci en améliorant le [freestanding Rust binary][binaire Rust autonome] du dernier article. -As you may remember, we built the freestanding binary through `cargo`, but depending on the operating system, we needed different entry point names and compile flags. That's because `cargo` builds for the _host system_ by default, i.e., the system you're running on. This isn't something we want for our kernel, because a kernel that runs on top of, e.g., Windows, does not make much sense. Instead, we want to compile for a clearly defined _target system_. +Comme vous vous en rappelez peut-être, nous avons bâti un binaire autonome grâce à `cargo`, mais selon le système d'opérations, nous avions besoin de différents points d'entrée et d'options de compilation. Ceci est dû au fait que `cargo` construit pour le the _host system_ by default, i.e., le système que vous utilisez. Ce n'est pas quelque chose que nous voulons pour notre noyau, puisqu'un noyau exécute par dessus, e.g., Windows, ce qui ne fait pas de sens. À la placem nous vouons compiler pour un système cible bien défini defined _target system_. ### Installing Rust Nightly Rust has three release channels: _stable_, _beta_, and _nightly_. The Rust Book explains the difference between these channels really well, so take a minute and [check it out](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#choo-choo-release-channels-and-riding-the-trains). For building an operating system, we will need some experimental features that are only available on the nightly channel, so we need to install a nightly version of Rust. From a366cdf277d0e9edbed81538f8e3580f013e71dc Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sat, 1 Oct 2022 20:37:01 -0400 Subject: [PATCH 12/23] Translate "Printing to Screen" paragraph --- .../posts/02-minimal-rust-kernel/index.fr.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index 9ccb685f..0748345e 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -340,16 +340,16 @@ This tells `cargo` to use our `x86_64-blog_os.json` target when no explicit `--t We are now able to build our kernel for a bare metal target with a simple `cargo build`. However, our `_start` entry point, which will be called by the boot loader, is still empty. It's time that we output something to screen from it. -### Printing to Screen -The easiest way to print text to the screen at this stage is the [VGA text buffer]. It is a special memory area mapped to the VGA hardware that contains the contents displayed on screen. It normally consists of 25 lines that each contain 80 character cells. Each character cell displays an ASCII character with some foreground and background colors. The screen output looks like this: +### Imprimer à l'écran +La façon la plus facile d'imprimer à l'écran à ce stade est grâce au tampon texte VGA. C'est un emplacement mémoire spécial associé au matériel VGA qui contient le contenu affiché à l'écran. Il consiste normalement en 25 lines qui contiennent chacune 80 cellules de caractère. Chaque cellule de caractère affiche un caractère ASCII avec des couleurs d'avant-plan et d'arrière-plan. Le résultat à l'écran ressemble à ceci: [VGA text buffer]: https://en.wikipedia.org/wiki/VGA-compatible_text_mode -![screen output for common ASCII characters](https://upload.wikimedia.org/wikipedia/commons/f/f8/Codepage-437.png) +![sortie à l'écran pour des caractères ASCII ordinaires](https://upload.wikimedia.org/wikipedia/commons/f/f8/Codepage-437.png) -We will discuss the exact layout of the VGA buffer in the next post, where we write a first small driver for it. For printing “Hello World!”, we just need to know that the buffer is located at address `0xb8000` and that each character cell consists of an ASCII byte and a color byte. +Nous discuterons de la disposition exacte du tampon VGA dans le prochain article, où nous lui écrirons un premier petit pilote. Pour afficher “Hello World!”, nous devons seulement savoir que le tampon est situé à l'adresse `0xb8000` et que chaque cellule de caractère consiste en un octet ASCII et un octet de couleur. -The implementation looks like this: +L'implémentation ressemble à ceci : ```rust static HELLO: &[u8] = b"Hello World!"; @@ -369,7 +369,7 @@ pub extern "C" fn _start() -> ! { } ``` -First, we cast the integer `0xb8000` into a [raw pointer]. Then we [iterate] over the bytes of the [static] `HELLO` [byte string]. We use the [`enumerate`] method to additionally get a running variable `i`. In the body of the for loop, we use the [`offset`] method to write the string byte and the corresponding color byte (`0xb` is a light cyan). +D'abord, nous transformons l'entier `0xb8000` en un [raw pointer][pointeur brut]. Puis nous [iterate][parcourons] les octets de la [byte string][chaîne d'octets] [static][statique] `HELLO`. Nous utilisons la méthode [`enumerate`] pour aussi obtenir une variable `i`. Dans le corps de la boucle `for`, nous utilisons la méthode [`offset`] pour écrire la chaîne d'octets et l'octet de couleur correspondant(`0xb` est un cyan pâle). [iterate]: https://doc.rust-lang.org/stable/book/ch13-02-iterators.html [static]: https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#the-static-lifetime @@ -378,14 +378,14 @@ First, we cast the integer `0xb8000` into a [raw pointer]. Then we [iterate] ove [raw pointer]: https://doc.rust-lang.org/stable/book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer [`offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.offset -Note that there's an [`unsafe`] block around all memory writes. The reason is that the Rust compiler can't prove that the raw pointers we create are valid. They could point anywhere and lead to data corruption. By putting them into an `unsafe` block, we're basically telling the compiler that we are absolutely sure that the operations are valid. Note that an `unsafe` block does not turn off Rust's safety checks. It only allows you to do [five additional things]. +Noter qu'il y a un bloc [`unsafe`] qui enveloppe les écritures mémoire. La raison est que le compilateur Rust ne peut pas prouver que les pointeurs bruts que nous créons sont valides. Ils pourraient pointer n'importe où et mener à une corruption de données. En les mettant dans un bloc `unsafe`, nous disons fondamentalement au compilateur que nous sommes absolument certains que les opérations sont valides. Noter qu'un bloc `unsafe` ne désactive pas les contrôles de sécurité de Rust. Il permet seulement de faire [five additional things][cinq choses supplémentaires]. [`unsafe`]: https://doc.rust-lang.org/stable/book/ch19-01-unsafe-rust.html [five additional things]: https://doc.rust-lang.org/stable/book/ch19-01-unsafe-rust.html#unsafe-superpowers -I want to emphasize that **this is not the way we want to do things in Rust!** It's very easy to mess up when working with raw pointers inside unsafe blocks. For example, we could easily write beyond the buffer's end if we're not careful. +Je veux souligner que **ceci n'est pas la façon de faire les choses en Rust!** Il est très facile de faire un gâchis en travaillant avec des pointeurs bruts à l'intérieur de blocs `unsafe`. Par exemple, nous pourrions facilement écrire au-delà de la fin du tampon si nous ne sommes pas prudents. -So we want to minimize the use of `unsafe` as much as possible. Rust gives us the ability to do this by creating safe abstractions. For example, we could create a VGA buffer type that encapsulates all unsafety and ensures that it is _impossible_ to do anything wrong from the outside. This way, we would only need minimal amounts of `unsafe` code and can be sure that we don't violate [memory safety]. We will create such a safe VGA buffer abstraction in the next post. +Alors nous voulons minimiser l'utilisation de `unsafe` autant que possible. Rust nous offre la possibilité de faire cela en créant des abstractions sécuritaires. Par exemple, nous pourrions créer un type tampon VGA qui encapsule les risques et qui s'assure qu'il est impossible de faire quoi que ce soit d'incorrect à l'extérieur de ce type. Ainsi, nous aurions besoin de très peu de code `unsafe` and nous serions certains que nous ne violons pas la [memory safety][sécurité de mémoire]. Nous allons créer une telle abstraction de tampon VGA buffer dans le prochain article. [memory safety]: https://en.wikipedia.org/wiki/Memory_safety From 001231b53fe710d253871b80998e894514ce176e Mon Sep 17 00:00:00 2001 From: TheMimiCodes Date: Sat, 1 Oct 2022 20:39:06 -0400 Subject: [PATCH 13/23] translate "installing Rust Nightly" paragraph --- .../edition-2/posts/02-minimal-rust-kernel/index.fr.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index 0748345e..c021cfa5 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -90,12 +90,12 @@ En raison de ces désavantages, nous avons décidé de ne pas utiliser GRUB ou l ## A Minimal Kernel Maintenant que nous savons à peu près comment un ordinateur démarre, c'est le temps de créer notre propre noyau minimal. Notre objectif est de créé une image de disque qui imprime “Hello World!” à l'écran lorsqu'il démarre. Nous faisons ceci en améliorant le [freestanding Rust binary][binaire Rust autonome] du dernier article. -Comme vous vous en rappelez peut-être, nous avons bâti un binaire autonome grâce à `cargo`, mais selon le système d'opérations, nous avions besoin de différents points d'entrée et d'options de compilation. Ceci est dû au fait que `cargo` construit pour le the _host system_ by default, i.e., le système que vous utilisez. Ce n'est pas quelque chose que nous voulons pour notre noyau, puisqu'un noyau exécute par dessus, e.g., Windows, ce qui ne fait pas de sens. À la placem nous vouons compiler pour un système cible bien défini defined _target system_. +Comme vous vous en rappelez peut-être, nous avons bâti un binaire autonome grâce à `cargo`, mais selon le système d'opérations, nous avions besoin de différents points d'entrée et d'options de compilation. Ceci est dû au fait que `cargo` construit pour le the _host system_ by default, i.e., le système que vous utilisez. Ce n'est pas quelque chose que nous voulons pour notre noyau, puisqu'un noyau exécute par dessus, e.g., Windows, ce qui ne fait pas de sens. À la place, nous voulons compiler un système cible bien défini _target system_. ### Installing Rust Nightly -Rust has three release channels: _stable_, _beta_, and _nightly_. The Rust Book explains the difference between these channels really well, so take a minute and [check it out](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#choo-choo-release-channels-and-riding-the-trains). For building an operating system, we will need some experimental features that are only available on the nightly channel, so we need to install a nightly version of Rust. +Rust a trois canaux de distribution : _stable_, _beta_, et _nightly_. The Rust Book explique bien les différences entre ces canaux, alors prenez une minute et [check it out](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#choo-choo-release-channels-and-riding-the-trains). Pour construire un système d'opérations, nous aurons besoin de fonctionalités expérimentales qui sont disponibles uniquement sur le canal de distribution nocturne, alors nous devons installer une version nocturne de Rust. -To manage Rust installations, I highly recommend [rustup]. It allows you to install nightly, beta, and stable compilers side-by-side and makes it easy to update them. With rustup, you can use a nightly compiler for the current directory by running `rustup override set nightly`. Alternatively, you can add a file called `rust-toolchain` with the content `nightly` to the project's root directory. You can check that you have a nightly version installed by running `rustc --version`: The version number should contain `-nightly` at the end. +Pour gérer l'installation de Rust, je recommande fortement [rustup]. Cela vous permet d'installer la version nocturne, beta and stable compilers côte-à-côte et facilite leur mise à jour. Avec rustup, vous pouvez utiliser un canal de distribution nocturne pour les directives actuelles en excéutant `rustup override set nightly`. Par ailleurs, vous pouvez ajouter un fichier appelé `rust-toolchain` avec le contenu `nightly` au dossier racine du projet. Vous pouvez vérifier que vous avez une version nocturne installée en exécutant `rustc --version`: Le numéro de la version devrait comprendre `-nightly` à la fin. [rustup]: https://www.rustup.rs/ From 0268d6b9c69c759fcad8b5abd48b5d85119e0f1b Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sun, 2 Oct 2022 06:59:59 -0400 Subject: [PATCH 14/23] Translate "Set a Default Target" paragraph --- .../edition-2/posts/02-minimal-rust-kernel/index.fr.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index c021cfa5..f231da1b 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -323,22 +323,22 @@ Behind the scenes, this flag enables the [`mem` feature] of the `compiler_builti With this change, our kernel has valid implementations for all compiler-required functions, so it will continue to compile even if our code gets more complex. -#### Set a Default Target +#### Définir une cible par défaut -To avoid passing the `--target` parameter on every invocation of `cargo build`, we can override the default target. To do this, we add the following to our [cargo configuration] file at `.cargo/config.toml`: +Pour ne pas avoir à fournir le paramètre `--target` à chaque invocation de `cargo build`, nous pouvons définir la cible par défaut. Pour ce faire, nous ajoutons le code suivant à notre fichier de [cargo configuration][configuration Cargo] dans `.cargo/config.toml`: [cargo configuration]: https://doc.rust-lang.org/cargo/reference/config.html ```toml -# in .cargo/config.toml +# dans .cargo/config.toml [build] target = "x86_64-blog_os.json" ``` -This tells `cargo` to use our `x86_64-blog_os.json` target when no explicit `--target` argument is passed. This means that we can now build our kernel with a simple `cargo build`. For more information on cargo configuration options, check out the [official documentation][cargo configuration]. +Ceci indique à `cargo` d'utiliser notre cible `x86_64-blog_os.json` quand il n'y a pas d'argument de cible `--target` explicitement fourni. Ceci veut dire que nous pouvons maintenant construire notre noyau avec un simple `cargo build`. Pour plus d'informations sur les options de configuration cargo, jetez un coup d'oeil à la [official documentation][documentation officielle de cargo]. -We are now able to build our kernel for a bare metal target with a simple `cargo build`. However, our `_start` entry point, which will be called by the boot loader, is still empty. It's time that we output something to screen from it. +Nous pouvons maintenant construire notre noyau pour une cible "bare metal" avec un simple `cargo build`. Toutefois, notre point d'entrée `_start`, qui sera appelé par le bootloader, est encore vide. Il est temps de lui faire imprimer quelque chose à l'écran. ### Imprimer à l'écran La façon la plus facile d'imprimer à l'écran à ce stade est grâce au tampon texte VGA. C'est un emplacement mémoire spécial associé au matériel VGA qui contient le contenu affiché à l'écran. Il consiste normalement en 25 lines qui contiennent chacune 80 cellules de caractère. Chaque cellule de caractère affiche un caractère ASCII avec des couleurs d'avant-plan et d'arrière-plan. Le résultat à l'écran ressemble à ceci: From d52116d4460117a30b592c366ae6b5ca89215285 Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sun, 2 Oct 2022 07:16:10 -0400 Subject: [PATCH 15/23] Translate "Memory-Related Intrinsics" paragraph --- .../posts/02-minimal-rust-kernel/index.fr.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index f231da1b..606d37f5 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -294,34 +294,34 @@ After setting the `unstable.build-std` configuration key and installing the `rus We see that `cargo build` now recompiles the `core`, `rustc-std-workspace-core` (a dependency of `compiler_builtins`), and `compiler_builtins` libraries for our custom target. -#### Memory-Related Intrinsics +#### Détails reliés à la mémoire -The Rust compiler assumes that a certain set of built-in functions is available for all systems. Most of these functions are provided by the `compiler_builtins` crate that we just recompiled. However, there are some memory-related functions in that crate that are not enabled by default because they are normally provided by the C library on the system. These functions include `memset`, which sets all bytes in a memory block to a given value, `memcpy`, which copies one memory block to another, and `memcmp`, which compares two memory blocks. While we didn't need any of these functions to compile our kernel right now, they will be required as soon as we add some more code to it (e.g. when copying structs around). +Le compilateur Rust assume qu'un certain ensemble de fonctions intégrées sont disponibles pour tous les systèmes. La plupart de ces fonctions sont fournies par la caisse `compiler_builtins` que nous venons de recompiler. Toutefois, certaines fonctions liées à la mémoire dans cette caisse ne sont pas activées par défaut puisqu'elles sont normalement fournies par la bibliothèque C sur le système. Parmi ces fonctions, on retrouve `memset`, qui définit tous les octets dans un bloc mémoire à une certaine valeur, `memcpy`, qui copie un bloc mémoire vers un autre, et `memcmp`, qui compare deux blocs mémoire. Alors que nous n'avions pas besoin de ces fonctions pour compiler notre noyau maintenant, elles seront nécessaires aussitôt que nous lui ajouterons plus de code (par exemple, lorsque nous copierons des `struct`). -Since we can't link to the C library of the operating system, we need an alternative way to provide these functions to the compiler. One possible approach for this could be to implement our own `memset` etc. functions and apply the `#[no_mangle]` attribute to them (to avoid the automatic renaming during compilation). However, this is dangerous since the slightest mistake in the implementation of these functions could lead to undefined behavior. For example, implementing `memcpy` with a `for` loop may result in an infinite recursion because `for` loops implicitly call the [`IntoIterator::into_iter`] trait method, which may call `memcpy` again. So it's a good idea to reuse existing, well-tested implementations instead. +Puisque nous ne pouvons pas lier avec la bibliothèque C du système d'exploitation, nous avons besoin d'une méthode alternative de fournir ces fonctions au compilateur. Une approche possible pour ce faire serait d'implémenter nos propre fonctions `memset`, etc. et de leur appliquer l'attribut `#[no_mangle]` (pour prévenir le changement de nom automatique pendant la compilation). Or, ceci est dangereux puisque toute erreur dans l'implémentation pourrait mener à un comportement indéterminé. Par exemple, implémenter `memcpy` avec une boucle `for` pourrait mener à une recursion infinie puisque les boucles `for` invoquent implicitement la méthode caractéristique [`IntoIterator::into_iter`], qui pourrait invoquer `memcpy` de nouveau. C'est donc une bonne idée de plutôt réutiliser des implémentations existantes et éprouvées. [`IntoIterator::into_iter`]: https://doc.rust-lang.org/stable/core/iter/trait.IntoIterator.html#tymethod.into_iter -Fortunately, the `compiler_builtins` crate already contains implementations for all the needed functions, they are just disabled by default to not collide with the implementations from the C library. We can enable them by setting cargo's [`build-std-features`] flag to `["compiler-builtins-mem"]`. Like the `build-std` flag, this flag can be either passed on the command line as a `-Z` flag or configured in the `unstable` table in the `.cargo/config.toml` file. Since we always want to build with this flag, the config file option makes more sense for us: +Heureusement, la caisse `compiler_builtins` contient déjà des implémentations pour toutes les fonctions nécessaires, elles sont seulement désactivées par défaut pour ne pas interférer avec les implémentations de la bibliothèque C. Nous pouvons les activer en définissant le drapeau [`build-std-features`] de cargo à `["compiler-builtins-mem"]`. Comme pour le drapeau `build-std`, ce drapeau peut être soit fourni en ligne de commande comme drapeau `-Z` ou configuré dans la table `unstable` du fichier `.cargo/config.toml`. Puisque nous voulons toujours construire avec ce drapeau, l'option du fichier de configuration fait plus de sens pour nous: [`build-std-features`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std-features ```toml -# in .cargo/config.toml +# dans .cargo/config.toml [unstable] build-std-features = ["compiler-builtins-mem"] build-std = ["core", "compiler_builtins"] ``` -(Support for the `compiler-builtins-mem` feature was only [added very recently](https://github.com/rust-lang/rust/pull/77284), so you need at least Rust nightly `2020-09-30` for it.) +(Le support pour la fonctionnalité `compiler-builtins-mem` a [été ajouté assez récemment](https://github.com/rust-lang/rust/pull/77284), donc vous aurez besoin de la version nocturne `2020-09-30` de Rust ou plus récent pour l'utiliser.) -Behind the scenes, this flag enables the [`mem` feature] of the `compiler_builtins` crate. The effect of this is that the `#[no_mangle]` attribute is applied to the [`memcpy` etc. implementations] of the crate, which makes them available to the linker. +Dans les coulisses, ce drapeau active la [`mem` feature][fonctionnalité `mem`] de la caisse `compiler_builtins`. Le résultat est que l'attribut `#[no_mangle]` est appliqué aux [`memcpy` etc. implementations][implémentations `memcpy` et autres] de la caise, ce qui les rend disponible au lieur. [`mem` feature]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/Cargo.toml#L54-L55 [`memcpy` etc. implementations]: https://github.com/rust-lang/compiler-builtins/blob/eff506cd49b637f1ab5931625a33cef7e91fbbf6/src/mem.rs#L12-L69 -With this change, our kernel has valid implementations for all compiler-required functions, so it will continue to compile even if our code gets more complex. +Avec ce changement, notre noyau a des implémentations valides pour toutes les fonctions requises par le compilateur, donc il peut continuer à compiler même si notre code devient plus complexe. #### Définir une cible par défaut From 44eaeca650a72cc44a00f918be9515b6d47f09e6 Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sun, 2 Oct 2022 07:20:42 -0400 Subject: [PATCH 16/23] Finish translating "Installing Rust Nightly" paragraph --- blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index 606d37f5..70958a23 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -99,7 +99,7 @@ Pour gérer l'installation de Rust, je recommande fortement [rustup]. Cela vous [rustup]: https://www.rustup.rs/ -The nightly compiler allows us to opt-in to various experimental features by using so-called _feature flags_ at the top of our file. For example, we could enable the experimental [`asm!` macro] for inline assembly by adding `#![feature(asm)]` to the top of our `main.rs`. Note that such experimental features are completely unstable, which means that future Rust versions might change or remove them without prior warning. For this reason, we will only use them if absolutely necessary. +La version nocturne du compilateur nous permet d'activer certaines fonctionnalités expérimentales en utilisant certains _drapeaux de fonctionalité_ dans le haut de notre fichier. Par exemple, nous pourrions activer [`asm!` macro][macro expérimentale `asm!`] pour écrire du code assembleur intégré en ajoutant `#![feature(asm)]` au haut de notre `main.rs`. Noter que ces fonctionnalités expérimentales sont tout à fait instables, ce qui veut dire que des versions futures de Rust pourraient les changer ou les retirer sans préavis. Pour cette raison, nous les utiliserons seulement lorsque strictement nécessaire. [`asm!` macro]: https://doc.rust-lang.org/stable/reference/inline-assembly.html From 3f5c4046090f0e9e2b4c9ce43709b17f67462f83 Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sun, 2 Oct 2022 07:53:05 -0400 Subject: [PATCH 17/23] Translate "Target Specification" paragraph --- .../posts/02-minimal-rust-kernel/index.fr.md | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index 70958a23..0770c99b 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -103,15 +103,15 @@ La version nocturne du compilateur nous permet d'activer certaines fonctionnalit [`asm!` macro]: https://doc.rust-lang.org/stable/reference/inline-assembly.html -### Target Specification -Cargo supports different target systems through the `--target` parameter. The target is described by a so-called _[target triple]_, which describes the CPU architecture, the vendor, the operating system, and the [ABI]. For example, the `x86_64-unknown-linux-gnu` target triple describes a system with an `x86_64` CPU, no clear vendor, and a Linux operating system with the GNU ABI. Rust supports [many different target triples][platform-support], including `arm-linux-androideabi` for Android or [`wasm32-unknown-unknown` for WebAssembly](https://www.hellorust.com/setup/wasm-target/). +### Spécification de cible +Cargo supporte différent systèmes cibles avec le paramètre `--target`. La cible est définie par un soi-disant _[target triple][triplet de cible]_, qui décrit l'architecteur du processeur, le fabricant, le système d'exploitation, et l'interface binaire d'application ([ABI]). Par exemple, le triplet `x86_64-unknown-linux-gnu` décrit un système avec un processeur `x86_64`, pas de fabricant défini, et un système d'exploitation Linux avec l'interface binaire d'application GNU. Rust supporte [plusieurs différents triplets de cible][platform-support], incluant `arm-linux-androideabi` pour Android ou [`wasm32-unknown-unknown` pour WebAssembly](https://www.hellorust.com/setup/wasm-target/). [target triple]: https://clang.llvm.org/docs/CrossCompilation.html#target-triple [ABI]: https://stackoverflow.com/a/2456882 [platform-support]: https://forge.rust-lang.org/release/platform-support.html [custom-targets]: https://doc.rust-lang.org/nightly/rustc/targets/custom.html -For our target system, however, we require some special configuration parameters (e.g. no underlying OS), so none of the [existing target triples][platform-support] fits. Fortunately, Rust allows us to define [our own target][custom-targets] through a JSON file. For example, a JSON file that describes the `x86_64-unknown-linux-gnu` target looks like this: +Pour notre système cible toutefois, nous avons besoin de paramètres de configuration spéciaux (par exemple, pas de système d'explotation sous-jacent), donc aucun des [triplets de cible existants][platform-support] ne convient. Heureusement, Rust nous permet de définir [notre propre cible][custom-targets] par l'entremise d'un fichier JSON. Par exemple, un fichier JSON qui décrit une cible `x86_64-unknown-linux-gnu` ressemble à ceci: ```json { @@ -129,12 +129,12 @@ For our target system, however, we require some special configuration parameters } ``` -Most fields are required by LLVM to generate code for that platform. For example, the [`data-layout`] field defines the size of various integer, floating point, and pointer types. Then there are fields that Rust uses for conditional compilation, such as `target-pointer-width`. The third kind of field defines how the crate should be built. For example, the `pre-link-args` field specifies arguments passed to the [linker]. +La plupart des champs sont requis par LLVM pour générer le code pour cette plateforme. Par exemple, le champ [`data-layout`] définit la taille de divers types d'entiers, de nombres à virgule flottante, et de pointeurs. Puis, il y a des champs que Rust utilise pour de la compilation conditionelle, comme `target-pointer-width`. Le troisième type de champ définit comme une caisse doit être construite. Par exemple, le champ `pre-link-args` spécifie les arguments fournis au [linker][lieur]. [`data-layout`]: https://llvm.org/docs/LangRef.html#data-layout [linker]: https://en.wikipedia.org/wiki/Linker_(computing) -We also target `x86_64` systems with our kernel, so our target specification will look very similar to the one above. Let's start by creating an `x86_64-blog_os.json` file (choose any name you like) with the common content: +Nous pouvons aussi cibler les systèmes `x86_64` avec notre noyau, donc notre spécification de cible ressemblera beaucoup à celle plus haut. Commençons par créer un fichier `x86_64-blog_os.json` (utilisez le nom de votre choix) avec ce contenu commun: ```json { @@ -149,9 +149,9 @@ We also target `x86_64` systems with our kernel, so our target specification wil } ``` -Note that we changed the OS in the `llvm-target` and the `os` field to `none`, because we will run on bare metal. +Noter que nous avons changé le système d'exploitation dans le champs `llvm-target` et `os` pour `none`, puisque nous ferons l'exécution sur du "bare metal" (pas de système d'exploitation sous-jacent). -We add the following build-related entries: +Nous ajoutons ensuite les champs suivants reliés à la construction: ```json @@ -159,7 +159,7 @@ We add the following build-related entries: "linker": "rust-lld", ``` -Instead of using the platform's default linker (which might not support Linux targets), we use the cross-platform [LLD] linker that is shipped with Rust for linking our kernel. +Plutôt que d'utiliser le lieur par défaut de la plateforme (qui pourrait ne pas supporter les cibles Linux), nous utilisons le lieur multi-plateforme [LLD] qui est inclut avec Rust pour lier notre noyau. [LLD]: https://lld.llvm.org/ @@ -167,7 +167,7 @@ Instead of using the platform's default linker (which might not support Linux ta "panic-strategy": "abort", ``` -This setting specifies that the target doesn't support [stack unwinding] on panic, so instead the program should abort directly. This has the same effect as the `panic = "abort"` option in our Cargo.toml, so we can remove it from there. (Note that, in contrast to the Cargo.toml option, this target option also applies when we recompile the `core` library later in this post. So, even if you prefer to keep the Cargo.toml option, make sure to include this option.) +Ce paramètre spécifie que la cible ne permet pas le [stack unwinding][déroulement de la pile] lorsque le noyau panique, alors le système devrait plutôt s'arrêter directement. Ceci mène au même résultat que l'option `panic = "abort"` dans notre Cargo.toml, alors nous pouvons la retirer de ce fichier. (Noter que, contrairement à l'option Cargo.toml, cette option de cible s'applique aussi quand nous recompilerons la bibliothèque `core` plus loin dans cet article. Ainsi, même si vous préférez garder l'option Cargo.toml, gardez cette option.) [stack unwinding]: https://www.bogotobogo.com/cplusplus/stackunwinding.php @@ -175,7 +175,7 @@ This setting specifies that the target doesn't support [stack unwinding] on pani "disable-redzone": true, ``` -We're writing a kernel, so we'll need to handle interrupts at some point. To do that safely, we have to disable a certain stack pointer optimization called the _“red zone”_, because it would cause stack corruption otherwise. For more information, see our separate post about [disabling the red zone]. +Nous écrivons un noyau, donc nous devrons éventuellement gérer les interruptions. Pour ce faire en toute sécurité, nous devons désactiver une optimisation de pointeur de pile nommée la _“zone rouge", puisqu'elle causerait une corruption de la pile autrement. Pour plus d'informations, lire notre article séparé à propos de la [disabling the red zone][désactivation de la zone rouge]. [disabling the red zone]: @/edition-2/posts/02-minimal-rust-kernel/disable-red-zone/index.md @@ -183,15 +183,15 @@ We're writing a kernel, so we'll need to handle interrupts at some point. To do "features": "-mmx,-sse,+soft-float", ``` -The `features` field enables/disables target features. We disable the `mmx` and `sse` features by prefixing them with a minus and enable the `soft-float` feature by prefixing it with a plus. Note that there must be no spaces between different flags, otherwise LLVM fails to interpret the features string. +Le champ `features` active/désactive des fonctionalités de la cible. Nous désactivons les fonctionalités `mmx` et `sse` en les précédant d'un signe "moins" et activons la fonctionnalité `soft-float` en la précédant d'un signe "plus". Noter qu'il ne doit pas y avoir d'espace entre les différentes fonctionnalités, sinon LLVM n'arrive pas à analyser la chaîne de caractères des fonctionnalités. -The `mmx` and `sse` features determine support for [Single Instruction Multiple Data (SIMD)] instructions, which can often speed up programs significantly. However, using the large SIMD registers in OS kernels leads to performance problems. The reason is that the kernel needs to restore all registers to their original state before continuing an interrupted program. This means that the kernel has to save the complete SIMD state to main memory on each system call or hardware interrupt. Since the SIMD state is very large (512–1600 bytes) and interrupts can occur very often, these additional save/restore operations considerably harm performance. To avoid this, we disable SIMD for our kernel (not for applications running on top!). +Les fonctionnalités `mmx` et `sse` déterminent le support les instructions [Single Instruction Multiple Data (SIMD)], qui peuvent souvent significativement accélérer les programmes. Toutefois, utiliser les grands registres SIMD dans les noyaux des systèmes d'exploitation mène à des problèmes de performance. Ceci arrive puisque le noyau a besoin de restaurer tous les registres à leur état original avant de continuer un programme interrompu. Cela signifie que le noyau doit enregistrer l'état SIMD complet dans la mémoire principale à chaque appel système ou interruption matérielle. Puisque l'état SIMD est très grand (512–1600 octets) et que les interruptions peuvent survenir très fréquemment, ces opérations d'enregistrement/restauration additionnelles nuisent considérablement à la performance. Pour prévenir cela, nous désactivons SIMD pour notre noyau (pas pour les applications qui s'exécutent dessus!). [Single Instruction Multiple Data (SIMD)]: https://en.wikipedia.org/wiki/SIMD -A problem with disabling SIMD is that floating point operations on `x86_64` require SIMD registers by default. To solve this problem, we add the `soft-float` feature, which emulates all floating point operations through software functions based on normal integers. +Un problème avec la désactivation de SIMD est que les opérations sur les nombres à virgule flottante sur `x86_64` nécessitent les registres SIMD par défaut. Pour résoudre ce problème, nous ajoutons la fonctionnalité `soft-float`, qui émule toutes les opérations à virgule flottante avec des fonctions logicielles utilisant des entiers normaux. -For more information, see our post on [disabling SIMD](@/edition-2/posts/02-minimal-rust-kernel/disable-simd/index.md). +Pour plus d'informations, voir notre article sur la [désactivation de SIMD](@/edition-2/posts/02-minimal-rust-kernel/disable-simd/index.md). #### Putting it Together Our target specification file now looks like this: From 7de8c2aa37d30aebc23853b4f0b0cca143aba719 Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sun, 2 Oct 2022 08:01:31 -0400 Subject: [PATCH 18/23] Translate "Building our Kernel" section --- .../posts/02-minimal-rust-kernel/index.fr.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index 0770c99b..f7498e0d 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -214,36 +214,36 @@ Our target specification file now looks like this: } ``` -### Building our Kernel -Compiling for our new target will use Linux conventions (I'm not quite sure why; I assume it's just LLVM's default). This means that we need an entry point named `_start` as described in the [previous post]: +### Construction de notre noyau +Compiler pour notre nouvelle cible utilisera les conventions Linux (je ne suis pas trop certain pourquoi; j'assume que c'est simplement le comportement par défaut de LLVM). Cela signifie que nos avons besoin d'un point d'entrée nommé `_start` comme décrit dans le [previous post][dernier article]: [previous post]: @/edition-2/posts/01-freestanding-rust-binary/index.md ```rust // src/main.rs -#![no_std] // don't link the Rust standard library -#![no_main] // disable all Rust-level entry points +#![no_std] // ne pas lier la bibliothèque standard Rust +#![no_main] // désactiver tous les points d'entrée Rust use core::panic::PanicInfo; -/// This function is called on panic. +/// Cette fonction est invoquée lorsque le système panique #[panic_handler] fn panic(_info: &PanicInfo) -> ! { loop {} } -#[no_mangle] // don't mangle the name of this function +#[no_mangle] // ne pas massacrer le nom de cette fonction pub extern "C" fn _start() -> ! { - // this function is the entry point, since the linker looks for a function - // named `_start` by default + // cette fonction est le point d'entrée, puisque le lieur cherche une fonction + // nommée `_start` par défaut loop {} } ``` -Note that the entry point needs to be called `_start` regardless of your host OS. +Noter que le point d'entrée doit être appelé `_start` indépendamment du système d'exploitation hôte. -We can now build the kernel for our new target by passing the name of the JSON file as `--target`: +Nous pouvons maintenant construire le noyau pour notre nouvelle cible en fournissant le nom du fichier JSON comme `--target`: ``` > cargo build --target x86_64-blog_os.json @@ -251,11 +251,11 @@ We can now build the kernel for our new target by passing the name of the JSON f error[E0463]: can't find crate for `core` ``` -It fails! The error tells us that the Rust compiler no longer finds the [`core` library]. This library contains basic Rust types such as `Result`, `Option`, and iterators, and is implicitly linked to all `no_std` crates. +Cela échoue! L'erreur nous dit que le compilateur ne trouve plus la [`core` library][bibliothèque `core`]. Cette bibliothèque contient les types de base Rust comme `Result`, `Option`, les itérateurs, et est implicitement liée à toutes les caisses `no_std`. [`core` library]: https://doc.rust-lang.org/nightly/core/index.html -The problem is that the core library is distributed together with the Rust compiler as a _precompiled_ library. So it is only valid for supported host triples (e.g., `x86_64-unknown-linux-gnu`) but not for our custom target. If we want to compile code for other targets, we need to recompile `core` for these targets first. +Le problème est que la bibliothèque essentielle est distribuée avec le Rust compilateur comme biliothèque _precompilée_. Donc, elle est seulement valide pour les triplets d'hôtes supportés (par exemple, `x86_64-unknown-linux-gnu`) mais pas pour notre cible personnalisée. Si nous voulons compiler du code pour d'autres cibles, nous devons d'abord recompiler `core` pour ces cibles. #### The `build-std` Option From 90a92f04a69ca94db8186285b7ef062e9a0250bb Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sun, 2 Oct 2022 08:07:28 -0400 Subject: [PATCH 19/23] Translate "The `build-std` Option" section --- .../posts/02-minimal-rust-kernel/index.fr.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index f7498e0d..b2b87526 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -257,31 +257,31 @@ Cela échoue! L'erreur nous dit que le compilateur ne trouve plus la [`core` lib Le problème est que la bibliothèque essentielle est distribuée avec le Rust compilateur comme biliothèque _precompilée_. Donc, elle est seulement valide pour les triplets d'hôtes supportés (par exemple, `x86_64-unknown-linux-gnu`) mais pas pour notre cible personnalisée. Si nous voulons compiler du code pour d'autres cibles, nous devons d'abord recompiler `core` pour ces cibles. -#### The `build-std` Option +#### L'option `build-std` -That's where the [`build-std` feature] of cargo comes in. It allows to recompile `core` and other standard library crates on demand, instead of using the precompiled versions shipped with the Rust installation. This feature is very new and still not finished, so it is marked as "unstable" and only available on [nightly Rust compilers]. +C'est ici que la [`build-std` feature][fonctionnalité `build-std`] de cargo entre en jeu. Elle permet de recompiler `core` et d'autres caisses de la bibliothèque standard sur demande, plutôt que d'utiliser des versions précompilées incluses avec l'installation de Rust. Cette fonctionnalité est très récente et n'est pas encore complète, donc elle est définie comme instable et est seulement disponible avec les [nightly Rust compilers][versions nocturnes du compilateur Rust]. [`build-std` feature]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std [nightly Rust compilers]: #installing-rust-nightly -To use the feature, we need to create a [cargo configuration] file at `.cargo/config.toml` with the following content: +Pour utiliser cette fonctionnalité, nous devons créer un fichier de [cargo configuration][configuration cargo] dans `.cargo/config.toml` avec le contenu suivant: ```toml -# in .cargo/config.toml +# dans .cargo/config.toml [unstable] build-std = ["core", "compiler_builtins"] ``` -This tells cargo that it should recompile the `core` and `compiler_builtins` libraries. The latter is required because it is a dependency of `core`. In order to recompile these libraries, cargo needs access to the rust source code, which we can install with `rustup component add rust-src`. +Ceci indique à cargo qu'il doit recompiler les bibliothèques `core` et `compiler_builtins`. Celle-ci est nécessaire pour qu'elle est une dépendance de `core`. Afin de recompiler ces bibliothèques, cargo doit avoir accès au code source de Rust, que nous pouvons installer avec `rustup component add rust-src`.
-**Note:** The `unstable.build-std` configuration key requires at least the Rust nightly from 2020-07-15. +**Note:** La clé de configuration `unstable.build-std` nécessite une version nocturne de Rust plus récente que 2020-07-15.
-After setting the `unstable.build-std` configuration key and installing the `rust-src` component, we can rerun our build command: +Après avoir défini la clé de configuration `unstable.build-std` et installé la composante `rust-src`, nous pouvons exécuter notre commande de construction à nouveau: ``` > cargo build --target x86_64-blog_os.json @@ -292,7 +292,7 @@ After setting the `unstable.build-std` configuration key and installing the `rus Finished dev [unoptimized + debuginfo] target(s) in 0.29 secs ``` -We see that `cargo build` now recompiles the `core`, `rustc-std-workspace-core` (a dependency of `compiler_builtins`), and `compiler_builtins` libraries for our custom target. +Nous voyons que `cargo build` recompile maintenant les bibliothèques `core`, `rustc-std-workspace-core` (une dépendance de `compiler_builtins`), et `compiler_builtins` pour notre cible personnalisée. #### Détails reliés à la mémoire From 1c66190ac2426ab48b0e100c6d1b96594a49802b Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sun, 2 Oct 2022 08:26:16 -0400 Subject: [PATCH 20/23] Fix typos, reword --- .../posts/02-minimal-rust-kernel/index.fr.md | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index b2b87526..cc4a5381 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -12,13 +12,13 @@ translation_based_on_commit = "c689ecf810f8e93f6b2fb3c4e1e8b89b8a0998eb" translators = ["TheMimiCodes", "maximevaillancourt"] +++ -Dans cet article, nous créons un noyau Rust minimal 64-bit pour l'architecture x86. Nous continuons le travail fait dans l'article précédent [freestanding Rust binary] pour créer une image de disque amorçable qui imprime quelque chose à l'écran. +Dans cet article, nous créons un noyau Rust 64-bit minimal pour l'architecture x86. Nous continuons le travail fait dans l'article précédent ([freestanding Rust binary][binaire Rust autonome]) pour créer une image de disque amorçable qui imprime quelque chose à l'écran. [freestanding Rust binary]: @/edition-2/posts/01-freestanding-rust-binary/index.md -Cet article est développé ouvertement sur [GitHub]. Si vous avez des problèmes ou des questions, veuillez ouvrir une Issue sur GitHub. Vous pouvez aussi laisser un commentaire [au bas de la page]. Le code source complet pour cet article peut être trouvé dans la branche [`post-02`][post branch]. +Cet article est développé ouvertement sur [GitHub]. Si vous avez des problèmes ou des questions, veuillez ouvrir une _Issue_ sur GitHub. Vous pouvez aussi laisser un commentaire [au bas de la page]. Le code source complet pour cet article se trouve dans la branche [`post-02`][post branch]. [GitHub]: https://github.com/phil-opp/blog_os [au bas de la page]: #comments @@ -27,75 +27,75 @@ Cet article est développé ouvertement sur [GitHub]. Si vous avez des problème -## The Boot Process -QUand vous ouvrez un ordinateur, il commence à exécuter le code du micrologiciel qui est enregistré dans la carte maîtresse[ROM]. Ce code performe un [power-on self-test], détecte la mémoire volatile disponible, et pré-initialise le CPU et le matériel. Par la suite, il recherche un disque amorçable et commence le processus d'amorçage du noyau du système d'exploitation. +## Le processus d'amorçage +Quand vous ouvrez un ordinateur, il commence à exécuter le code du micrologiciel qui est enregistré dans la carte maîtresse ([ROM]). Ce code performe un [power-on self-test][test d'auto-diagnostic de démarrage], détecte la mémoire volatile disponible, et pré-initialise le processeur et le matériel. Par la suite, il recherche un disque amorçable et commence le processus d'amorçage du noyau du système d'exploitation. [ROM]: https://en.wikipedia.org/wiki/Read-only_memory [power-on self-test]: https://en.wikipedia.org/wiki/Power-on_self-test -Sur x86, il y a deux standards pour les micrologiciels: le “Basic Input/Output System“ (**[BIOS]**) et le nouvel “Unified Extensible Firmware Interface” (**[UEFI]**). Le BIOS standard est vieux et dépassé, mais il est simple et bien suporté sur toutes les machines x86 depuis les années 1980. Au contraire, l'UEFI, est plutôt moderne et il offre davantage de fonctionnalités, cependant, il est plus complexe à installer (du moins, selon moi). +Sur x86, il existe deux standards pour les micrologiciels : le “Basic Input/Output System“ (**[BIOS]**) et le nouvel “Unified Extensible Firmware Interface” (**[UEFI]**). Le BIOS standard est vieux et dépassé, mais il est simple et bien supporté sur toutes les machines x86 depuis les années 1980. Au contraire, l'UEFI est moderne et offre davantage de fonctionnalités. Cependant, il est plus complexe à installer (du moins, selon moi). [BIOS]: https://en.wikipedia.org/wiki/BIOS [UEFI]: https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface -Actuellement, nous offrons seulement un support BIOS, mais nous planifions aussi du support pour l'UEFI. Si vous aimeriez nous aider avec cela, consultez [Github issue](https://github.com/phil-opp/blog_os/issues/349). +Actuellement, nous offrons seulement un support BIOS, mais nous planifions aussi du support pour l'UEFI. Si vous aimeriez nous aider avec cela, consultez l'[_issue_ sur GitHub](https://github.com/phil-opp/blog_os/issues/349). -### BIOS Boot -Presque tous les systèmes x86 ont des support pour amorcer le BIOS, incluant les récentes machine UEFI-based qui utilisent un BIOS émulé. C'est bien étant donné que vous pouvez utiliser la même logique d'armorçage sur toutes les machines du dernier siècle. De plus, cette grande compatibilité est à la fois le plus grand désavantage de l'amorçage BIOS. En effet, cela signifie que le CPU est mis dans un mode de compatibilité 16-bit appelé [real mode] avant l'amorçage afin que les bootloaders archaïques des années 1980 puissent encore fonctionner. +### Amorçage BIOS +Presque tous les systèmes x86 peuvent amorcer le BIOS, incluant les nouvelles machines UEFI qui utilisent un BIOS émulé. C'est bien étant donné que vous pouvez utiliser la même logique d'amorçage sur toutes les machines du dernier siècle. Or, cette grande compatibilité est à la fois le plus grand désavantage de l'amorçage BIOS. En effet, cela signifie que le CPU est mis dans un mode de compatibilité 16-bit appelé _[real mode]_ avant l'amorçage afin que les bootloaders archaïques des années 1980 puissent encore fonctionner. -Commençons par le commencement: +Commençons par le commencement : -Quand vous ouvrez votre ordinateur, il charge le BIOS provenant d'un emplacement de mémoire flash spéciale localisée sur la carte maîtresse. Le BIOS exécute des tests d'auto-diagnostic et es routines d'initialisation du matériel, puis il cherche des disques amorçables. S'il en trouve un, le contrôle est transféré à its _bootloader_, qui est une portion 512-byte du code exécutable enregistré au début du disque. La pluplart des bootloaders sont plus gros que 512 bytes, alors les bootloaders sont communément séparés en deux étapes. La première étape, est de 512 bytes, et la seconde étape, est chargé subséquemment à la première étapge. +Quand vous ouvrez votre ordinateur, il charge le BIOS provenant d'un emplacement de mémoire flash spéciale localisée sur la carte maîtresse. Le BIOS exécute des tests d'auto-diagnostic et des routines d'initialisation du matériel, puis il cherche des disques amorçables. S'il en trouve un, le contrôle est transféré à son _bootloader_, qui est une portion de 512 octets de code exécutable enregistré au début du disque. La plupart des bootloaders sont plus gros que 512 octets, alors les bootloaders sont communément séparés en deux phases. La première phase est de 512 octets, et la seconde phase est chargée subséquemment à la première étapge. -Le bootloader doit déterminé la localisation de l'image de noyau sur le disque et de la télécharger dans sa mémoire. Il doit aussi transformer le CPU 16-bit [real mode] en un 32-bit [protected mode], puis en un 64-bit [long mode], où les registres 64-bit et la mémoire maîtresse complète sont disponibles. Sa troisième tâche est de récupérer certaines informations (telle que les associations mémoires) du BIOS et les passer au noyau du système d'exploitation. +Le bootloader doit déterminer la localisation de l'image de noyau sur le disque et la charger en mémoire. Il doit aussi passer le processeur de 16-bit ([real mode]) à 32-bit ([protected mode]), puis à 64-bit ([long mode]), où les registres 64-bit et la mémoire maîtresse complète sont disponibles. Sa troisième tâche est de récupérer certaines informations (telle que les associations mémoires) du BIOS et les passer au noyau du système d'exploitation. [real mode]: https://en.wikipedia.org/wiki/Real_mode [protected mode]: https://en.wikipedia.org/wiki/Protected_mode [long mode]: https://en.wikipedia.org/wiki/Long_mode [memory segmentation]: https://en.wikipedia.org/wiki/X86_memory_segmentation -Implémenter un bootloader est délicat puisque cela requiert l'écriture de code assembleur et plusieurs autres étapes particulières comme “write this magic value to this processor register”. Par conséquent, nous ne couvrons pas la création d'un bootoader dans cet article et nous fournissons plutôt un outil appelé [bootimage] qui ajoute automatiquement un bootloader à votre noyau. +Implémenter un bootloader est délicat puisque cela requiert l'écriture de code assembleur et plusieurs autres étapes particulières comme “écrire une valeur magique dans un registre du processeur". Par conséquent, nous ne couvrons pas la création d'un bootloader dans cet article et nous fournissons plutôt un outil appelé [bootimage] qui ajoute automatiquement un bootloader au noyau. [bootimage]: https://github.com/rust-osdev/bootimage -Si vous êtes intéressé à créer votre propre booloader : Gardez l'oeil ouvert, plusieurs articles sur ce sujet sont déjà prévus! +Si vous êtes intéressé à créer votre propre booloader : gardez l'oeil ouvert, plusieurs articles sur ce sujet sont déjà prévus! -#### The Multiboot Standard -Pour éviter que chaque système d'opération implémente son propre bootloader, qui est seulement compatible avec un seul système d'exploitation, le [Free Software Foundation] à créé un bootloader public standard appelé [Multiboot] en 1995. Le standard défini une interface entre le bootloader et le système d'opération afin que n'importe quel Multiboot-compliant bootloader puisse charger n'importe quel système d'opérations Multiboot-compliant. La référence d'implementation est [GNU GRUB], qui est le bootloader le plus populaire pour les systèmes Linux. +#### Le standard Multiboot +Pour éviter que chaque système d'exploitation implémente son propre bootloader, qui est seulement compatible avec un seul système d'exploitation, la [Free Software Foundation] a créé en 1995 un bootloader standard public appelé [Multiboot]. Le standard définit une interface entre le bootloader et le système d'exploitation afin que n'importe quel bootloader comforme à Multiboot puisse charger n'importe quel système d'exploitation conforme à Multiboot. La référence d'implementation est [GNU GRUB], qui est le bootloader le plus populaire pour les systèmes Linux. [Free Software Foundation]: https://en.wikipedia.org/wiki/Free_Software_Foundation [Multiboot]: https://wiki.osdev.org/Multiboot [GNU GRUB]: https://en.wikipedia.org/wiki/GNU_GRUB -Pour faire un noyau conforme à la spécification Multiboot, il faut seulement inséré un [Multiboot header] au début du fichier du noyau. Cela fait en sorte que c'est très simple to boot un système d'exploitation depuis GRUB. Cependant, le GRUB et le Multiboot standard présentent aussi des problèmes : +Pour créer un noyau conforme à la spécification Multiboot, il faut seulement insérer une [Multiboot header][en-tête Multiboot] au début du fichier du noyau. Cela fait en sorte que c'est très simple d'amorcer un système d'exploitation depuis GRUB. Cependant, GRUB et le standard Multiboot présentent aussi des problèmes : [Multiboot header]: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#OS-image-format -- Ils supportent seulement le mode de protection 32-bit. Cela signifie que si vous devez encore faire la configuration du CPU pour changer au 64-bit long mode. -- Ils sont désignés pour faire le bootloader simple plutôt que le noyau. Par exemple, le noyau doit être lié avec un [adjusted default page size], étant donné que le GRUB ne peut pas trouver les entêtes Multiboot autrement. Un autre exemple est que le [boot information], qui est passé au noyau, contient plusieurs structures spécifiques à l'architecture plutôt que de fournir des abstractions pures. +- Ils supportent seulement le "protected mode" 32-bit. Cela signifie que vous devez encore faire la configuration du processeur pour changer au "long mode" 64-bit. +- Ils sont désignés pour simplifier le bootloader plutôt que le noyau. Par exemple, le noyau doit être lié avec une [adjusted default page size][taille de page par défaut ajustée], étant donné que le GRUB ne peut pas trouver les entêtes Multiboot autrement. Un autre exemple est que l'[boot information][information de boot], qui est fournies au noyau, contient plusieurs structures spécifiques à l'architecture plutôt que de fournir des abstractions pures. - GRUB et le standard Multiboot sont peu documentés. - GRUB doit être installé sur un système hôte pour créer une image de disque amorçable depuis le fichier du noyau. Cela rend le développement sur Windows ou sur Mac plus difficile. [adjusted default page size]: https://wiki.osdev.org/Multiboot#Multiboot_2 [boot information]: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format -En raison de ces désavantages, nous avons décidé de ne pas utiliser GRUB ou le standard Multiboot. Cependant, nous avons planifié d'ajouter un support Multiboot à notre outil [bootimage], afin qu'il soit aussi possible de charger votre noyau sur un système GRUB. Si vous êtes interessé à écrire un noyau Multiboot conforme, consultez la [first edition] de cette série d'articles. +En raison de ces désavantages, nous avons décidé de ne pas utiliser GRUB ou le standard Multiboot. Cependant, nous avons l'intention d'ajouter le support Multiboot à notre outil [bootimage], afin qu'il soit aussi possible de charger le noyau sur un système GRUB. Si vous êtes interessé à écrire un noyau Multiboot conforme, consultez la [first edition][première édition] de cette série d'articles. [first edition]: @/edition-1/_index.md ### UEFI -(Nous ne fournissons pas le support UEFI à l'heure actuelle, mais nous aimerions bien! Si vous êtes intéressé à aider, dites-le nous dans le [Github issue](https://github.com/phil-opp/blog_os/issues/349).) +(Nous ne fournissons pas le support UEFI à l'heure actuelle, mais nous aimerions bien! Si vous êtes intéressé à aider, dites-le nous dans cette [_issue_ GitHub](https://github.com/phil-opp/blog_os/issues/349).) -## A Minimal Kernel -Maintenant que nous savons à peu près comment un ordinateur démarre, c'est le temps de créer notre propre noyau minimal. Notre objectif est de créé une image de disque qui imprime “Hello World!” à l'écran lorsqu'il démarre. Nous faisons ceci en améliorant le [freestanding Rust binary][binaire Rust autonome] du dernier article. +## Un noyau minimal +Maintenant que nous savons à peu près comment un ordinateur démarre, il est temps de créer notre propre noyau minimal. Notre objectif est de créer une image de disque qui imprime “Hello World!” à l'écran lorsqu'il démarre. Nous faisons ceci en améliorant le [freestanding Rust binary][binaire Rust autonome] du dernier article. -Comme vous vous en rappelez peut-être, nous avons bâti un binaire autonome grâce à `cargo`, mais selon le système d'opérations, nous avions besoin de différents points d'entrée et d'options de compilation. Ceci est dû au fait que `cargo` construit pour le the _host system_ by default, i.e., le système que vous utilisez. Ce n'est pas quelque chose que nous voulons pour notre noyau, puisqu'un noyau exécute par dessus, e.g., Windows, ce qui ne fait pas de sens. À la place, nous voulons compiler un système cible bien défini _target system_. +Comme vous vous en rappelez peut-être, nous avons bâti un binaire autonome grâce à `cargo`, mais selon le système d'exploitation, nous avions besoin de différents points d'entrée et d'options de compilation. Ceci est dû au fait que `cargo` construit pour _système hôte_ par défaut, c'est-à-dire le système que vous utilisez. Ce n'est pas ce que nous voulons pour notre noyau, puisqu'un noyau qui s'exécute par dessus Windows par exemple ne fait pas de sens. Nous voulons plutôt compiler pour un _système cible_ bien défini. -### Installing Rust Nightly -Rust a trois canaux de distribution : _stable_, _beta_, et _nightly_. The Rust Book explique bien les différences entre ces canaux, alors prenez une minute et [check it out](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#choo-choo-release-channels-and-riding-the-trains). Pour construire un système d'opérations, nous aurons besoin de fonctionalités expérimentales qui sont disponibles uniquement sur le canal de distribution nocturne, alors nous devons installer une version nocturne de Rust. +### Installer une version nocturne de Rust +Rust a trois canaux de distribution : _stable_, _beta_, et _nightly_. Le Livre de Rust explique bien les différences entre ces canaux, alors prenez une minute et [jetez y un coup d'oeil](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#choo-choo-release-channels-and-riding-the-trains). Pour construire un système d'exploitation, nous aurons besoin de fonctionalités expérimentales qui sont disponibles uniquement sur le canal de distribution nocturne, alors nous devons installer une version nocturne de Rust. -Pour gérer l'installation de Rust, je recommande fortement [rustup]. Cela vous permet d'installer la version nocturne, beta and stable compilers côte-à-côte et facilite leur mise à jour. Avec rustup, vous pouvez utiliser un canal de distribution nocturne pour les directives actuelles en excéutant `rustup override set nightly`. Par ailleurs, vous pouvez ajouter un fichier appelé `rust-toolchain` avec le contenu `nightly` au dossier racine du projet. Vous pouvez vérifier que vous avez une version nocturne installée en exécutant `rustc --version`: Le numéro de la version devrait comprendre `-nightly` à la fin. +Pour gérer l'installation de Rust, je recommande fortement [rustup]. Cela vous permet d'installer les versions nocturne, beta et stable du compilateur côte-à-côte et facilite leurs mises à jour. Avec rustup, vous pouvez utiliser un canal de distribution nocturne pour le dossier actuel en exécutant `rustup override set nightly`. Par ailleurs, vous pouvez ajouter un fichier appelé `rust-toolchain` avec le contenu `nightly` au dossier racine du projet. Vous pouvez vérifier que vous avez une version nocturne installée en exécutant `rustc --version`: Le numéro de la version devrait comprendre `-nightly` à la fin. [rustup]: https://www.rustup.rs/ @@ -395,7 +395,7 @@ Maintenant que nous avons un exécutable qui fait quelque chose de perceptible, ### Créer une image d'amorçage -Pour transformer notre noyau compilé en image de disque amorçable, nous devons le lier avec un bootloader. Comme nous l'avons appris dans la [section about booting][section à propos du lancement], le bootloader est responsable de lancer le CPU et de charger notre noyau. +Pour transformer notre noyau compilé en image de disque amorçable, nous devons le lier avec un bootloader. Comme nous l'avons appris dans la [section about booting][section à propos du lancement], le bootloader est responsable de lancer le processeur et de charger notre noyau. [section about booting]: #the-boot-process @@ -487,7 +487,7 @@ runner = "bootimage runner" La table `target.'cfg(target_os = "none")'` s'applique à toutes les cibles dont le champ `"os"` dans le fichier de configuration est défini à `"none"`. Ceci inclut notre cible `x86_64-blog_os.json`. La clé `runner` key spécifie la commande qui doit être invoquée pour `cargo run`. La commande est exécutée après une build réussie avec le chemin de l'exécutable comme premier argument. Voir la [configuration cargo][cargo configuration] pour plus de détails. -La commande `bootimage runner` est spécifiquement conçue pour être utilisable comme un exécutable `runner`. Elle lie l'exécutable fourni avec le bootloader duquel le projet dépend et lance ensuite QEMU. Voir le [Readme of `bootimage`][README de `bootimage`] pour plus de détails et les options de configuration possibles. +La commande `bootimage runner` est spécifiquement conçue pour être utilisable comme un exécutable `runner`. Elle lie l'exécutable fourni avec le bootloader duquel dépend le projet et lance ensuite QEMU. Voir le [Readme of `bootimage`][README de `bootimage`] pour plus de détails et les options de configuration possibles. [Readme of `bootimage`]: https://github.com/rust-osdev/bootimage From c2c6d644520231c52599eeaa98ffa932eb8f70b1 Mon Sep 17 00:00:00 2001 From: Maxime Vaillancourt Date: Sun, 2 Oct 2022 08:28:03 -0400 Subject: [PATCH 21/23] Translate "Putting it Together" section --- .../edition-2/posts/02-minimal-rust-kernel/index.fr.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index cc4a5381..ba774975 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -193,8 +193,8 @@ Un problème avec la désactivation de SIMD est que les opérations sur les nomb Pour plus d'informations, voir notre article sur la [désactivation de SIMD](@/edition-2/posts/02-minimal-rust-kernel/disable-simd/index.md). -#### Putting it Together -Our target specification file now looks like this: +#### Assembler le tout +Notre fichier de spécification de cible ressemble maintenant à ceci : ```json { From 633bc2e0323c2f20c641162679f4b096a6bb00fd Mon Sep 17 00:00:00 2001 From: Alain CAO Date: Thu, 13 Oct 2022 23:31:04 +0200 Subject: [PATCH 22/23] French translation fix suggestions --- .../posts/02-minimal-rust-kernel/index.fr.md | 120 +++++++++--------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index ba774975..e1659068 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -12,13 +12,13 @@ translation_based_on_commit = "c689ecf810f8e93f6b2fb3c4e1e8b89b8a0998eb" translators = ["TheMimiCodes", "maximevaillancourt"] +++ -Dans cet article, nous créons un noyau Rust 64-bit minimal pour l'architecture x86. Nous continuons le travail fait dans l'article précédent ([freestanding Rust binary][binaire Rust autonome]) pour créer une image de disque amorçable qui imprime quelque chose à l'écran. +Dans cet article, nous créons un noyau Rust 64-bit minimal pour l'architecture x86. Nous continuons le travail fait dans l'article précédent ([freestanding Rust binary][binaire Rust autonome]) pour créer une image de disque amorçable qui affiche quelque chose à l'écran. -[freestanding Rust binary]: @/edition-2/posts/01-freestanding-rust-binary/index.md +[freestanding Rust binary]: @/edition-2/posts/01-freestanding-rust-binary/index.fr.md -Cet article est développé ouvertement sur [GitHub]. Si vous avez des problèmes ou des questions, veuillez ouvrir une _Issue_ sur GitHub. Vous pouvez aussi laisser un commentaire [au bas de la page]. Le code source complet pour cet article se trouve dans la branche [`post-02`][post branch]. +Cet article est développé de manière ouverte sur [GitHub]. Si vous avez des problèmes ou des questions, veuillez ouvrir une _Issue_ sur GitHub. Vous pouvez aussi laisser un commentaire [au bas de la page]. Le code source complet pour cet article se trouve dans la branche [`post-02`][post branch]. [GitHub]: https://github.com/phil-opp/blog_os [au bas de la page]: #comments @@ -28,83 +28,83 @@ Cet article est développé ouvertement sur [GitHub]. Si vous avez des problème ## Le processus d'amorçage -Quand vous ouvrez un ordinateur, il commence à exécuter le code du micrologiciel qui est enregistré dans la carte maîtresse ([ROM]). Ce code performe un [power-on self-test][test d'auto-diagnostic de démarrage], détecte la mémoire volatile disponible, et pré-initialise le processeur et le matériel. Par la suite, il recherche un disque amorçable et commence le processus d'amorçage du noyau du système d'exploitation. +Quand vous allumez un ordinateur, il commence par exécuter le code du micrologiciel qui est enregistré dans la carte mère ([ROM]). Ce code performe un [power-on self-test][test d'auto-diagnostic de démarrage], détecte la mémoire volatile disponible, et pré-initialise le processeur et le matériel. Par la suite, il recherche un disque amorçable et commence le processus d'amorçage du noyau du système d'exploitation. -[ROM]: https://en.wikipedia.org/wiki/Read-only_memory -[power-on self-test]: https://en.wikipedia.org/wiki/Power-on_self-test +[ROM]: https://fr.wikipedia.org/wiki/M%C3%A9moire_morte +[power-on self-test]: https://fr.wikipedia.org/wiki/Power-on_self-test_(informatique) Sur x86, il existe deux standards pour les micrologiciels : le “Basic Input/Output System“ (**[BIOS]**) et le nouvel “Unified Extensible Firmware Interface” (**[UEFI]**). Le BIOS standard est vieux et dépassé, mais il est simple et bien supporté sur toutes les machines x86 depuis les années 1980. Au contraire, l'UEFI est moderne et offre davantage de fonctionnalités. Cependant, il est plus complexe à installer (du moins, selon moi). -[BIOS]: https://en.wikipedia.org/wiki/BIOS -[UEFI]: https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface +[BIOS]: https://fr.wikipedia.org/wiki/BIOS_(informatique) +[UEFI]: https://fr.wikipedia.org/wiki/UEFI Actuellement, nous offrons seulement un support BIOS, mais nous planifions aussi du support pour l'UEFI. Si vous aimeriez nous aider avec cela, consultez l'[_issue_ sur GitHub](https://github.com/phil-opp/blog_os/issues/349). ### Amorçage BIOS -Presque tous les systèmes x86 peuvent amorcer le BIOS, incluant les nouvelles machines UEFI qui utilisent un BIOS émulé. C'est bien étant donné que vous pouvez utiliser la même logique d'amorçage sur toutes les machines du dernier siècle. Or, cette grande compatibilité est à la fois le plus grand désavantage de l'amorçage BIOS. En effet, cela signifie que le CPU est mis dans un mode de compatibilité 16-bit appelé _[real mode]_ avant l'amorçage afin que les bootloaders archaïques des années 1980 puissent encore fonctionner. +Presque tous les systèmes x86 peuvent amorcer le BIOS, y compris les nouvelles machines UEFI qui utilisent un BIOS émulé. C'est une bonne chose car cela permet d'utiliser la même logique d'amorçage sur toutes les machines du dernier siècle. Cependant, cette grande compatibilité est aussi le plus grand inconvénient de l'amorçage BIOS, car cela signifie que le CPU est mis dans un mode de compatibilité 16-bit appelé _[real mode]_ avant l'amorçage afin que les bootloaders archaïques des années 1980 puissent encore fonctionner. -Commençons par le commencement : +Mais commençons par le commencement : -Quand vous ouvrez votre ordinateur, il charge le BIOS provenant d'un emplacement de mémoire flash spéciale localisée sur la carte maîtresse. Le BIOS exécute des tests d'auto-diagnostic et des routines d'initialisation du matériel, puis il cherche des disques amorçables. S'il en trouve un, le contrôle est transféré à son _bootloader_, qui est une portion de 512 octets de code exécutable enregistré au début du disque. La plupart des bootloaders sont plus gros que 512 octets, alors les bootloaders sont communément séparés en deux phases. La première phase est de 512 octets, et la seconde phase est chargée subséquemment à la première étapge. +Quand vous allumez votre ordinateur, il charge le BIOS provenant d'un emplacement de mémoire flash spéciale localisée sur la carte mère. Le BIOS exécute des tests d'auto-diagnostic et des routines d'initialisation du matériel, puis il cherche des disques amorçables. S'il en trouve un, le contrôle est transféré à son _bootloader_, qui est une portion de 512 octets de code exécutable enregistré au début du disque. Vu que la plupart des bootloaders dépassent 512 octets, ils sont généralement divisés en deux phases: la première, plus petite, tient dans ces 512 octets, tandis que la seconde phase est chargée subséquemment. -Le bootloader doit déterminer la localisation de l'image de noyau sur le disque et la charger en mémoire. Il doit aussi passer le processeur de 16-bit ([real mode]) à 32-bit ([protected mode]), puis à 64-bit ([long mode]), où les registres 64-bit et la mémoire maîtresse complète sont disponibles. Sa troisième tâche est de récupérer certaines informations (telle que les associations mémoires) du BIOS et les passer au noyau du système d'exploitation. +Le bootloader doit déterminer l'emplacement de l'image de noyau sur le disque et la charger en mémoire. Il doit aussi passer le processeur de 16-bit ([real mode]) à 32-bit ([protected mode]), puis à 64-bit ([long mode]), dans lequel les registres 64-bit et la totalité de la mémoire principale sont disponibles. Sa troisième responsabilité est de récupérer certaines informations (telle que les associations mémoires) du BIOS et de les transférer au noyau du système d'exploitation. -[real mode]: https://en.wikipedia.org/wiki/Real_mode -[protected mode]: https://en.wikipedia.org/wiki/Protected_mode +[real mode]: https://fr.wikipedia.org/wiki/Mode_r%C3%A9el +[protected mode]: https://fr.wikipedia.org/wiki/Mode_prot%C3%A9g%C3%A9 [long mode]: https://en.wikipedia.org/wiki/Long_mode -[memory segmentation]: https://en.wikipedia.org/wiki/X86_memory_segmentation +[memory segmentation]: https://fr.wikipedia.org/wiki/Segmentation_(informatique) -Implémenter un bootloader est délicat puisque cela requiert l'écriture de code assembleur et plusieurs autres étapes particulières comme “écrire une valeur magique dans un registre du processeur". Par conséquent, nous ne couvrons pas la création d'un bootloader dans cet article et nous fournissons plutôt un outil appelé [bootimage] qui ajoute automatiquement un bootloader au noyau. +Implémenter un bootloader est fastidieux car cela requiert l'écriture en language assembleur ainsi que plusieurs autres étapes particulières comme “écrire une valeur magique dans un registre du processeur". Par conséquent, nous ne couvrons pas la création d'un bootloader dans cet article et fournissons plutôt un outil appelé [bootimage] qui ajoute automatiquement un bootloader au noyau. [bootimage]: https://github.com/rust-osdev/bootimage -Si vous êtes intéressé à créer votre propre booloader : gardez l'oeil ouvert, plusieurs articles sur ce sujet sont déjà prévus! +Si vous êtes intéressé par la création de votre propre booloader : restez dans le coin, plusieurs articles sur ce sujet sont déjà prévus à ce sujet! #### Le standard Multiboot -Pour éviter que chaque système d'exploitation implémente son propre bootloader, qui est seulement compatible avec un seul système d'exploitation, la [Free Software Foundation] a créé en 1995 un bootloader standard public appelé [Multiboot]. Le standard définit une interface entre le bootloader et le système d'exploitation afin que n'importe quel bootloader comforme à Multiboot puisse charger n'importe quel système d'exploitation conforme à Multiboot. La référence d'implementation est [GNU GRUB], qui est le bootloader le plus populaire pour les systèmes Linux. +Pour éviter que chaque système d'exploitation implémente son propre bootloader, qui est seulement compatible avec un seul système d'exploitation, la [Free Software Foundation] a créé en 1995 un bootloader standard public appelé [Multiboot]. Le standard définit une interface entre le bootloader et le système d'exploitation afin que n'importe quel bootloader compatible Multiboot puisse charger n'importe quel système d'exploitation compatible Multiboot. L'implémentation de référence est [GNU GRUB], qui est le bootloader le plus populaire pour les systèmes Linux. -[Free Software Foundation]: https://en.wikipedia.org/wiki/Free_Software_Foundation +[Free Software Foundation]: https://fr.wikipedia.org/wiki/Free_Software_Foundation [Multiboot]: https://wiki.osdev.org/Multiboot -[GNU GRUB]: https://en.wikipedia.org/wiki/GNU_GRUB +[GNU GRUB]: https://fr.wikipedia.org/wiki/GNU_GRUB -Pour créer un noyau conforme à la spécification Multiboot, il faut seulement insérer une [Multiboot header][en-tête Multiboot] au début du fichier du noyau. Cela fait en sorte que c'est très simple d'amorcer un système d'exploitation depuis GRUB. Cependant, GRUB et le standard Multiboot présentent aussi des problèmes : +Pour créer un noyau compatible Multiboot, il suffit d'insérer une [Multiboot header][en-tête Multiboot] au début du fichier du noyau. Cela rend très simple l'amorçage d'un système d'exploitation depuis GRUB. Cependant, GRUB et le standard Multiboot présentent aussi quelques problèmes : [Multiboot header]: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#OS-image-format -- Ils supportent seulement le "protected mode" 32-bit. Cela signifie que vous devez encore faire la configuration du processeur pour changer au "long mode" 64-bit. -- Ils sont désignés pour simplifier le bootloader plutôt que le noyau. Par exemple, le noyau doit être lié avec une [adjusted default page size][taille de page par défaut ajustée], étant donné que le GRUB ne peut pas trouver les entêtes Multiboot autrement. Un autre exemple est que l'[boot information][information de boot], qui est fournies au noyau, contient plusieurs structures spécifiques à l'architecture plutôt que de fournir des abstractions pures. +- Ils supportent seulement le "protected mode" 32-bit. Cela signifie que vous devez encore effectuer la configuration du processeur pour passer au "long mode" 64-bit. +- Ils sont conçus pour simplifier le bootloader plutôt que le noyau. Par exemple, le noyau doit être lié avec une [adjusted default page size][taille de page prédéfinie], étant donné que GRUB ne peut pas trouver les entêtes Multiboot autrement. Un autre exemple est que l'[boot information][information de boot], qui est fournies au noyau, contient plusieurs structures spécifiques à l'architecture au lieu de fournir des abstractions pures. - GRUB et le standard Multiboot sont peu documentés. - GRUB doit être installé sur un système hôte pour créer une image de disque amorçable depuis le fichier du noyau. Cela rend le développement sur Windows ou sur Mac plus difficile. [adjusted default page size]: https://wiki.osdev.org/Multiboot#Multiboot_2 [boot information]: https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#Boot-information-format -En raison de ces désavantages, nous avons décidé de ne pas utiliser GRUB ou le standard Multiboot. Cependant, nous avons l'intention d'ajouter le support Multiboot à notre outil [bootimage], afin qu'il soit aussi possible de charger le noyau sur un système GRUB. Si vous êtes interessé à écrire un noyau Multiboot conforme, consultez la [first edition][première édition] de cette série d'articles. +En raison de ces désavantages, nous avons décidé de ne pas utiliser GRUB ou le standard Multiboot. Cependant, nous avons l'intention d'ajouter le support Multiboot à notre outil [bootimage], afin qu'il soit aussi possible de charger le noyau sur un système GRUB. Si vous êtes interessé par l'écriture d'un noyau Multiboot conforme, consultez la [first edition][première édition] de cette série d'articles. [first edition]: @/edition-1/_index.md ### UEFI -(Nous ne fournissons pas le support UEFI à l'heure actuelle, mais nous aimerions bien! Si vous êtes intéressé à aider, dites-le nous dans cette [_issue_ GitHub](https://github.com/phil-opp/blog_os/issues/349).) +(Nous ne fournissons pas le support UEFI à l'heure actuelle, mais nous aimerions bien! Si vous voulez aider, dites-le nous dans cette [_issue_ GitHub](https://github.com/phil-opp/blog_os/issues/349).) ## Un noyau minimal -Maintenant que nous savons à peu près comment un ordinateur démarre, il est temps de créer notre propre noyau minimal. Notre objectif est de créer une image de disque qui imprime “Hello World!” à l'écran lorsqu'il démarre. Nous faisons ceci en améliorant le [freestanding Rust binary][binaire Rust autonome] du dernier article. +Maintenant que nous savons à peu près comment un ordinateur démarre, il est temps de créer notre propre noyau minimal. Notre objectif est de créer une image de disque qui affiche “Hello World!” à l'écran lorsqu'il démarre. Nous ferons ceci en améliorant le [freestanding Rust binary][binaire Rust autonome] du dernier article. -Comme vous vous en rappelez peut-être, nous avons bâti un binaire autonome grâce à `cargo`, mais selon le système d'exploitation, nous avions besoin de différents points d'entrée et d'options de compilation. Ceci est dû au fait que `cargo` construit pour _système hôte_ par défaut, c'est-à-dire le système que vous utilisez. Ce n'est pas ce que nous voulons pour notre noyau, puisqu'un noyau qui s'exécute par dessus Windows par exemple ne fait pas de sens. Nous voulons plutôt compiler pour un _système cible_ bien défini. +Comme vous vous en rappelez peut-être, nous avons créé un binaire autonome grâce à `cargo`, mais selon le système d'exploitation, nous avions besoin de différents points d'entrée et d'options de compilation. C'est dû au fait que `cargo` construit pour _système hôte_ par défaut, c'est-à-dire le système que vous utilisez. Ce n'est pas ce que nous voulons pour notre noyau, car un noyau qui s'exécute, par exemple, sur Windows n'a pas de sens. Nous voulons plutôt compiler pour un _système cible_ bien défini. ### Installer une version nocturne de Rust -Rust a trois canaux de distribution : _stable_, _beta_, et _nightly_. Le Livre de Rust explique bien les différences entre ces canaux, alors prenez une minute et [jetez y un coup d'oeil](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#choo-choo-release-channels-and-riding-the-trains). Pour construire un système d'exploitation, nous aurons besoin de fonctionalités expérimentales qui sont disponibles uniquement sur le canal de distribution nocturne, alors nous devons installer une version nocturne de Rust. +Rust a trois canaux de distribution : _stable_, _beta_, et _nightly_. Le Livre de Rust explique bien les différences entre ces canaux, alors prenez une minute et [jetez y un coup d'oeil](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#choo-choo-release-channels-and-riding-the-trains). Pour construire un système d'exploitation, nous aurons besoin de fonctionalités expérimentales qui sont disponibles uniquement sur le canal de distribution nocturne. Donc nous devons installer une version nocturne de Rust. -Pour gérer l'installation de Rust, je recommande fortement [rustup]. Cela vous permet d'installer les versions nocturne, beta et stable du compilateur côte-à-côte et facilite leurs mises à jour. Avec rustup, vous pouvez utiliser un canal de distribution nocturne pour le dossier actuel en exécutant `rustup override set nightly`. Par ailleurs, vous pouvez ajouter un fichier appelé `rust-toolchain` avec le contenu `nightly` au dossier racine du projet. Vous pouvez vérifier que vous avez une version nocturne installée en exécutant `rustc --version`: Le numéro de la version devrait comprendre `-nightly` à la fin. +Pour gérer l'installation de Rust, je recommande fortement [rustup]. Il vous permet d'installer les versions nocturne, beta et stable du compilateur côte-à-côte et facilite leurs mises à jour. Avec rustup, vous pouvez utiliser un canal de distribution nocturne pour le dossier actuel en exécutant `rustup override set nightly`. Par ailleurs, vous pouvez ajouter un fichier appelé `rust-toolchain` avec le contenu `nightly` au dossier racine du projet. Vous pouvez vérifier que vous avez une version nocturne installée en exécutant `rustc --version`: Le numéro de la version devrait comprendre `-nightly` à la fin. [rustup]: https://www.rustup.rs/ -La version nocturne du compilateur nous permet d'activer certaines fonctionnalités expérimentales en utilisant certains _drapeaux de fonctionalité_ dans le haut de notre fichier. Par exemple, nous pourrions activer [`asm!` macro][macro expérimentale `asm!`] pour écrire du code assembleur intégré en ajoutant `#![feature(asm)]` au haut de notre `main.rs`. Noter que ces fonctionnalités expérimentales sont tout à fait instables, ce qui veut dire que des versions futures de Rust pourraient les changer ou les retirer sans préavis. Pour cette raison, nous les utiliserons seulement lorsque strictement nécessaire. +La version nocturne du compilateur nous permet d'activer certaines fonctionnalités expérimentales en utilisant certains _drapeaux de fonctionalité_ dans le haut de notre fichier. Par exemple, nous pourrions activer [`asm!` macro][macro expérimentale `asm!`] pour écrire du code assembleur intégré en ajoutant `#![feature(asm)]` au haut de notre `main.rs`. Notez que ces fonctionnalités expérimentales sont tout à fait instables, ce qui veut dire que des versions futures de Rust pourraient les changer ou les retirer sans préavis. Pour cette raison, nous les utiliserons seulement lorsque strictement nécessaire. [`asm!` macro]: https://doc.rust-lang.org/stable/reference/inline-assembly.html -### Spécification de cible -Cargo supporte différent systèmes cibles avec le paramètre `--target`. La cible est définie par un soi-disant _[target triple][triplet de cible]_, qui décrit l'architecteur du processeur, le fabricant, le système d'exploitation, et l'interface binaire d'application ([ABI]). Par exemple, le triplet `x86_64-unknown-linux-gnu` décrit un système avec un processeur `x86_64`, pas de fabricant défini, et un système d'exploitation Linux avec l'interface binaire d'application GNU. Rust supporte [plusieurs différents triplets de cible][platform-support], incluant `arm-linux-androideabi` pour Android ou [`wasm32-unknown-unknown` pour WebAssembly](https://www.hellorust.com/setup/wasm-target/). +### Spécification de la cible +Cargo supporte différent systèmes cibles avec le paramètre `--target`. La cible est définie par un soi-disant _[target triple][triplet de cible]_, qui décrit l'architecteur du processeur, le fabricant, le système d'exploitation, et l'interface binaire d'application ([ABI]). Par exemple, le triplet `x86_64-unknown-linux-gnu` décrit un système avec un processeur `x86_64`, sans fabricant défini, et un système d'exploitation Linux avec l'interface binaire d'application GNU. Rust supporte [plusieurs différents triplets de cible][platform-support], incluant `arm-linux-androideabi` pour Android ou [`wasm32-unknown-unknown` pour WebAssembly](https://www.hellorust.com/setup/wasm-target/). [target triple]: https://clang.llvm.org/docs/CrossCompilation.html#target-triple [ABI]: https://stackoverflow.com/a/2456882 @@ -129,7 +129,7 @@ Pour notre système cible toutefois, nous avons besoin de paramètres de configu } ``` -La plupart des champs sont requis par LLVM pour générer le code pour cette plateforme. Par exemple, le champ [`data-layout`] définit la taille de divers types d'entiers, de nombres à virgule flottante, et de pointeurs. Puis, il y a des champs que Rust utilise pour de la compilation conditionelle, comme `target-pointer-width`. Le troisième type de champ définit comme une caisse doit être construite. Par exemple, le champ `pre-link-args` spécifie les arguments fournis au [linker][lieur]. +La plupart des champs sont requis par LLVM pour générer le code pour cette plateforme. Par exemple, le champ [`data-layout`] définit la taille de divers types d'entiers, de nombres à virgule flottante, et de pointeurs. Puis, il y a des champs que Rust utilise pour de la compilation conditionelle, comme `target-pointer-width`. Le troisième type de champ définit comment la crate doit être construite. Par exemple, le champ `pre-link-args` spécifie les arguments fournis au [linker][lieur]. [`data-layout`]: https://llvm.org/docs/LangRef.html#data-layout [linker]: https://en.wikipedia.org/wiki/Linker_(computing) @@ -149,7 +149,7 @@ Nous pouvons aussi cibler les systèmes `x86_64` avec notre noyau, donc notre sp } ``` -Noter que nous avons changé le système d'exploitation dans le champs `llvm-target` et `os` pour `none`, puisque nous ferons l'exécution sur du "bare metal" (pas de système d'exploitation sous-jacent). +Notez que nous avons changé le système d'exploitation dans le champs `llvm-target` et `os` en `none`, puisque nous ferons l'exécution sur du "bare metal" (donc, sans système d'exploitation sous-jacent). Nous ajoutons ensuite les champs suivants reliés à la construction: @@ -167,7 +167,7 @@ Plutôt que d'utiliser le lieur par défaut de la plateforme (qui pourrait ne pa "panic-strategy": "abort", ``` -Ce paramètre spécifie que la cible ne permet pas le [stack unwinding][déroulement de la pile] lorsque le noyau panique, alors le système devrait plutôt s'arrêter directement. Ceci mène au même résultat que l'option `panic = "abort"` dans notre Cargo.toml, alors nous pouvons la retirer de ce fichier. (Noter que, contrairement à l'option Cargo.toml, cette option de cible s'applique aussi quand nous recompilerons la bibliothèque `core` plus loin dans cet article. Ainsi, même si vous préférez garder l'option Cargo.toml, gardez cette option.) +Ce paramètre spécifie que la cible ne permet pas le [stack unwinding][déroulement de la pile] lorsque le noyau panique, alors le système devrait plutôt s'arrêter directement. Ceci mène au même résultat que l'option `panic = "abort"` dans notre Cargo.toml, alors nous pouvons la retirer de ce fichier. (Notez que, contrairement à l'option Cargo.toml, cette option de cible s'applique aussi quand nous recompilerons la bibliothèque `core` plus loin dans cet article. Ainsi, même si vous préférez garder l'option Cargo.toml, gardez cette option.) [stack unwinding]: https://www.bogotobogo.com/cplusplus/stackunwinding.php @@ -175,7 +175,7 @@ Ce paramètre spécifie que la cible ne permet pas le [stack unwinding][déroule "disable-redzone": true, ``` -Nous écrivons un noyau, donc nous devrons éventuellement gérer les interruptions. Pour ce faire en toute sécurité, nous devons désactiver une optimisation de pointeur de pile nommée la _“zone rouge", puisqu'elle causerait une corruption de la pile autrement. Pour plus d'informations, lire notre article séparé à propos de la [disabling the red zone][désactivation de la zone rouge]. +Nous écrivons un noyau, donc nous devrons éventuellement gérer les interruptions. Pour ce faire en toute sécurité, nous devons désactiver une optimisation de pointeur de pile nommée la _“zone rouge"_, puisqu'elle causerait une corruption de la pile autrement. Pour plus d'informations, lire notre article séparé à propos de la [disabling the red zone][désactivation de la zone rouge]. [disabling the red zone]: @/edition-2/posts/02-minimal-rust-kernel/disable-red-zone/index.md @@ -183,11 +183,11 @@ Nous écrivons un noyau, donc nous devrons éventuellement gérer les interrupti "features": "-mmx,-sse,+soft-float", ``` -Le champ `features` active/désactive des fonctionalités de la cible. Nous désactivons les fonctionalités `mmx` et `sse` en les précédant d'un signe "moins" et activons la fonctionnalité `soft-float` en la précédant d'un signe "plus". Noter qu'il ne doit pas y avoir d'espace entre les différentes fonctionnalités, sinon LLVM n'arrive pas à analyser la chaîne de caractères des fonctionnalités. +Le champ `features` active/désactive des fonctionalités de la cible. Nous désactivons les fonctionalités `mmx` et `sse` en les précédant d'un signe "moins" et activons la fonctionnalité `soft-float` en la précédant d'un signe "plus". Notez qu'il ne doit pas y avoir d'espace entre les différentes fonctionnalités, sinon LLVM n'arrive pas à analyser la chaîne de caractères des fonctionnalités. -Les fonctionnalités `mmx` et `sse` déterminent le support les instructions [Single Instruction Multiple Data (SIMD)], qui peuvent souvent significativement accélérer les programmes. Toutefois, utiliser les grands registres SIMD dans les noyaux des systèmes d'exploitation mène à des problèmes de performance. Ceci arrive puisque le noyau a besoin de restaurer tous les registres à leur état original avant de continuer un programme interrompu. Cela signifie que le noyau doit enregistrer l'état SIMD complet dans la mémoire principale à chaque appel système ou interruption matérielle. Puisque l'état SIMD est très grand (512–1600 octets) et que les interruptions peuvent survenir très fréquemment, ces opérations d'enregistrement/restauration additionnelles nuisent considérablement à la performance. Pour prévenir cela, nous désactivons SIMD pour notre noyau (pas pour les applications qui s'exécutent dessus!). +Les fonctionnalités `mmx` et `sse` déterminent le support les instructions [Single Instruction Multiple Data (SIMD)], qui peuvent souvent significativement accélérer les programmes. Toutefois, utiliser les grands registres SIMD dans les noyaux des systèmes d'exploitation mène à des problèmes de performance. Ceci parce que le noyau a besoin de restaurer tous les registres à leur état original avant de continuer un programme interrompu. Cela signifie que le noyau doit enregistrer l'état SIMD complet dans la mémoire principale à chaque appel système ou interruption matérielle. Puisque l'état SIMD est très grand (512–1600 octets) et que les interruptions peuvent survenir très fréquemment, ces opérations d'enregistrement/restauration additionnelles nuisent considérablement à la performance. Pour prévenir cela, nous désactivons SIMD pour notre noyau (pas pour les applications qui s'exécutent dessus!). -[Single Instruction Multiple Data (SIMD)]: https://en.wikipedia.org/wiki/SIMD +[Single Instruction Multiple Data (SIMD)]: https://fr.wikipedia.org/wiki/Single_instruction_multiple_data Un problème avec la désactivation de SIMD est que les opérations sur les nombres à virgule flottante sur `x86_64` nécessitent les registres SIMD par défaut. Pour résoudre ce problème, nous ajoutons la fonctionnalité `soft-float`, qui émule toutes les opérations à virgule flottante avec des fonctions logicielles utilisant des entiers normaux. @@ -215,9 +215,9 @@ Notre fichier de spécification de cible ressemble maintenant à ceci : ``` ### Construction de notre noyau -Compiler pour notre nouvelle cible utilisera les conventions Linux (je ne suis pas trop certain pourquoi; j'assume que c'est simplement le comportement par défaut de LLVM). Cela signifie que nos avons besoin d'un point d'entrée nommé `_start` comme décrit dans le [previous post][dernier article]: +Compiler pour notre nouvelle cible utilisera les conventions Linux (je ne suis pas trop certain pourquoi; j'assume que c'est simplement le comportement par défaut de LLVM). Cela signifie que nos avons besoin d'un point d'entrée nommé `_start` comme décrit dans [previous post][l'article précédent]: -[previous post]: @/edition-2/posts/01-freestanding-rust-binary/index.md +[previous post]: @/edition-2/posts/01-freestanding-rust-binary/index.fr.md ```rust // src/main.rs @@ -241,7 +241,7 @@ pub extern "C" fn _start() -> ! { } ``` -Noter que le point d'entrée doit être appelé `_start` indépendamment du système d'exploitation hôte. +Notez que le point d'entrée doit être appelé `_start` indépendamment du système d'exploitation hôte. Nous pouvons maintenant construire le noyau pour notre nouvelle cible en fournissant le nom du fichier JSON comme `--target`: @@ -251,15 +251,15 @@ Nous pouvons maintenant construire le noyau pour notre nouvelle cible en fournis error[E0463]: can't find crate for `core` ``` -Cela échoue! L'erreur nous dit que le compilateur ne trouve plus la [`core` library][bibliothèque `core`]. Cette bibliothèque contient les types de base Rust comme `Result`, `Option`, les itérateurs, et est implicitement liée à toutes les caisses `no_std`. +Cela échoue! L'erreur nous dit que le compilateur ne trouve plus la [`core` library][bibliothèque `core`]. Cette bibliothèque contient les types de base Rust comme `Result`, `Option`, les itérateurs, et est implicitement liée à toutes les crates `no_std`. [`core` library]: https://doc.rust-lang.org/nightly/core/index.html -Le problème est que la bibliothèque essentielle est distribuée avec le Rust compilateur comme biliothèque _precompilée_. Donc, elle est seulement valide pour les triplets d'hôtes supportés (par exemple, `x86_64-unknown-linux-gnu`) mais pas pour notre cible personnalisée. Si nous voulons compiler du code pour d'autres cibles, nous devons d'abord recompiler `core` pour ces cibles. +Le problème est que la bibliothèque `core` est distribuée avec le compilateur Rust comme biliothèque _precompilée_. Donc, elle est seulement valide pour les triplets d'hôtes supportés (par exemple, `x86_64-unknown-linux-gnu`) mais pas pour notre cible personnalisée. Si nous voulons compiler du code pour d'autres cibles, nous devons d'abord recompiler `core` pour ces cibles. #### L'option `build-std` -C'est ici que la [`build-std` feature][fonctionnalité `build-std`] de cargo entre en jeu. Elle permet de recompiler `core` et d'autres caisses de la bibliothèque standard sur demande, plutôt que d'utiliser des versions précompilées incluses avec l'installation de Rust. Cette fonctionnalité est très récente et n'est pas encore complète, donc elle est définie comme instable et est seulement disponible avec les [nightly Rust compilers][versions nocturnes du compilateur Rust]. +C'est ici que la [`build-std` feature][fonctionnalité `build-std`] de cargo entre en jeu. Elle permet de recompiler `core` et d'autres crates de la bibliothèque standard sur demande, plutôt que d'utiliser des versions précompilées incluses avec l'installation de Rust. Cette fonctionnalité est très récente et n'est pas encore complète, donc elle est définie comme instable et est seulement disponible avec les [nightly Rust compilers][versions nocturnes du compilateur Rust]. [`build-std` feature]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std [nightly Rust compilers]: #installing-rust-nightly @@ -273,7 +273,7 @@ Pour utiliser cette fonctionnalité, nous devons créer un fichier de [cargo con build-std = ["core", "compiler_builtins"] ``` -Ceci indique à cargo qu'il doit recompiler les bibliothèques `core` et `compiler_builtins`. Celle-ci est nécessaire pour qu'elle est une dépendance de `core`. Afin de recompiler ces bibliothèques, cargo doit avoir accès au code source de Rust, que nous pouvons installer avec `rustup component add rust-src`. +Ceci indique à cargo qu'il doit recompiler les bibliothèques `core` et `compiler_builtins`. Celle-ci est nécessaire pour qu'elle ait une dépendance de `core`. Afin de recompiler ces bibliothèques, cargo doit avoir accès au code source de Rust, que nous pouvons installer avec `rustup component add rust-src`.
@@ -296,13 +296,13 @@ Nous voyons que `cargo build` recompile maintenant les bibliothèques `core`, `r #### Détails reliés à la mémoire -Le compilateur Rust assume qu'un certain ensemble de fonctions intégrées sont disponibles pour tous les systèmes. La plupart de ces fonctions sont fournies par la caisse `compiler_builtins` que nous venons de recompiler. Toutefois, certaines fonctions liées à la mémoire dans cette caisse ne sont pas activées par défaut puisqu'elles sont normalement fournies par la bibliothèque C sur le système. Parmi ces fonctions, on retrouve `memset`, qui définit tous les octets dans un bloc mémoire à une certaine valeur, `memcpy`, qui copie un bloc mémoire vers un autre, et `memcmp`, qui compare deux blocs mémoire. Alors que nous n'avions pas besoin de ces fonctions pour compiler notre noyau maintenant, elles seront nécessaires aussitôt que nous lui ajouterons plus de code (par exemple, lorsque nous copierons des `struct`). +Le compilateur Rust assume qu'un certain ensemble de fonctions intégrées sont disponibles pour tous les systèmes. La plupart de ces fonctions sont fournies par la crate `compiler_builtins` que nous venons de recompiler. Toutefois, certaines fonctions liées à la mémoire dans cette crate ne sont pas activées par défaut puisqu'elles sont normalement fournies par la bibliothèque C sur le système. Parmi ces fonctions, on retrouve `memset`, qui définit tous les octets dans un bloc mémoire à une certaine valeur, `memcpy`, qui copie un bloc mémoire vers un autre, et `memcmp`, qui compare deux blocs mémoire. Alors que nous n'avions pas besoin de ces fonctions pour compiler notre noyau maintenant, elles seront nécessaires aussitôt que nous lui ajouterons plus de code (par exemple, lorsque nous copierons des `struct`). -Puisque nous ne pouvons pas lier avec la bibliothèque C du système d'exploitation, nous avons besoin d'une méthode alternative de fournir ces fonctions au compilateur. Une approche possible pour ce faire serait d'implémenter nos propre fonctions `memset`, etc. et de leur appliquer l'attribut `#[no_mangle]` (pour prévenir le changement de nom automatique pendant la compilation). Or, ceci est dangereux puisque toute erreur dans l'implémentation pourrait mener à un comportement indéterminé. Par exemple, implémenter `memcpy` avec une boucle `for` pourrait mener à une recursion infinie puisque les boucles `for` invoquent implicitement la méthode caractéristique [`IntoIterator::into_iter`], qui pourrait invoquer `memcpy` de nouveau. C'est donc une bonne idée de plutôt réutiliser des implémentations existantes et éprouvées. +Puisque nous ne pouvons pas lier avec la bibliothèque C du système d'exploitation, nous avons besoin d'une méthode alternative de fournir ces fonctions au compilateur. Une approche possible pour ce faire serait d'implémenter nos propre fonctions `memset`, etc. et de leur appliquer l'attribut `#[no_mangle]` (pour prévenir le changement de nom automatique pendant la compilation). Or, ceci est dangereux puisque toute erreur dans l'implémentation pourrait mener à un comportement indéterminé. Par exemple, implémenter `memcpy` avec une boucle `for` pourrait mener à une recursion infinie puisque les boucles `for` invoquent implicitement la méthode _trait_ [`IntoIterator::into_iter`], qui pourrait invoquer `memcpy` de nouveau. C'est donc une bonne idée de plutôt réutiliser des implémentations existantes et éprouvées. [`IntoIterator::into_iter`]: https://doc.rust-lang.org/stable/core/iter/trait.IntoIterator.html#tymethod.into_iter -Heureusement, la caisse `compiler_builtins` contient déjà des implémentations pour toutes les fonctions nécessaires, elles sont seulement désactivées par défaut pour ne pas interférer avec les implémentations de la bibliothèque C. Nous pouvons les activer en définissant le drapeau [`build-std-features`] de cargo à `["compiler-builtins-mem"]`. Comme pour le drapeau `build-std`, ce drapeau peut être soit fourni en ligne de commande comme drapeau `-Z` ou configuré dans la table `unstable` du fichier `.cargo/config.toml`. Puisque nous voulons toujours construire avec ce drapeau, l'option du fichier de configuration fait plus de sens pour nous: +Heureusement, la crate `compiler_builtins` contient déjà des implémentations pour toutes les fonctions nécessaires, elles sont seulement désactivées par défaut pour ne pas interférer avec les implémentations de la bibliothèque C. Nous pouvons les activer en définissant le drapeau [`build-std-features`] de cargo à `["compiler-builtins-mem"]`. Comme pour le drapeau `build-std`, ce drapeau peut être soit fourni en ligne de commande avec `-Z` ou configuré dans la table `unstable` du fichier `.cargo/config.toml`. Puisque nous voulons toujours construire avec ce drapeau, l'option du fichier de configuration fait plus de sens pour nous: [`build-std-features`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std-features @@ -338,10 +338,10 @@ target = "x86_64-blog_os.json" Ceci indique à `cargo` d'utiliser notre cible `x86_64-blog_os.json` quand il n'y a pas d'argument de cible `--target` explicitement fourni. Ceci veut dire que nous pouvons maintenant construire notre noyau avec un simple `cargo build`. Pour plus d'informations sur les options de configuration cargo, jetez un coup d'oeil à la [official documentation][documentation officielle de cargo]. -Nous pouvons maintenant construire notre noyau pour une cible "bare metal" avec un simple `cargo build`. Toutefois, notre point d'entrée `_start`, qui sera appelé par le bootloader, est encore vide. Il est temps de lui faire imprimer quelque chose à l'écran. +Nous pouvons maintenant construire notre noyau pour une cible "bare metal" avec un simple `cargo build`. Toutefois, notre point d'entrée `_start`, qui sera appelé par le bootloader, est encore vide. Il est temps de lui faire afficher quelque chose à l'écran. -### Imprimer à l'écran -La façon la plus facile d'imprimer à l'écran à ce stade est grâce au tampon texte VGA. C'est un emplacement mémoire spécial associé au matériel VGA qui contient le contenu affiché à l'écran. Il consiste normalement en 25 lines qui contiennent chacune 80 cellules de caractère. Chaque cellule de caractère affiche un caractère ASCII avec des couleurs d'avant-plan et d'arrière-plan. Le résultat à l'écran ressemble à ceci: +### Afficher à l'écran +La façon la plus facile d'afficher à l'écran à ce stade est grâce au tampon texte VGA. C'est un emplacement mémoire spécial associé au matériel VGA qui contient le contenu affiché à l'écran. Il consiste normalement en 25 lines qui contiennent chacune 80 cellules de caractère. Chaque cellule de caractère affiche un caractère ASCII avec des couleurs d'avant-plan et d'arrière-plan. Le résultat à l'écran ressemble à ceci: [VGA text buffer]: https://en.wikipedia.org/wiki/VGA-compatible_text_mode @@ -378,14 +378,14 @@ D'abord, nous transformons l'entier `0xb8000` en un [raw pointer][pointeur brut] [raw pointer]: https://doc.rust-lang.org/stable/book/ch19-01-unsafe-rust.html#dereferencing-a-raw-pointer [`offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.offset -Noter qu'il y a un bloc [`unsafe`] qui enveloppe les écritures mémoire. La raison est que le compilateur Rust ne peut pas prouver que les pointeurs bruts que nous créons sont valides. Ils pourraient pointer n'importe où et mener à une corruption de données. En les mettant dans un bloc `unsafe`, nous disons fondamentalement au compilateur que nous sommes absolument certains que les opérations sont valides. Noter qu'un bloc `unsafe` ne désactive pas les contrôles de sécurité de Rust. Il permet seulement de faire [five additional things][cinq choses supplémentaires]. +Notez qu'il y a un bloc [`unsafe`] qui enveloppe les écritures mémoire. La raison en est que le compilateur Rust ne peut pas prouver que les pointeurs bruts que nous créons sont valides. Ils pourraient pointer n'importe où et mener à une corruption de données. En les mettant dans un bloc `unsafe`, nous disons fondamentalement au compilateur que nous sommes absolument certains que les opérations sont valides. Notez qu'un bloc `unsafe` ne désactive pas les contrôles de sécurité de Rust. Il permet seulement de faire [five additional things][cinq choses supplémentaires]. [`unsafe`]: https://doc.rust-lang.org/stable/book/ch19-01-unsafe-rust.html [five additional things]: https://doc.rust-lang.org/stable/book/ch19-01-unsafe-rust.html#unsafe-superpowers -Je veux souligner que **ceci n'est pas la façon de faire les choses en Rust!** Il est très facile de faire un gâchis en travaillant avec des pointeurs bruts à l'intérieur de blocs `unsafe`. Par exemple, nous pourrions facilement écrire au-delà de la fin du tampon si nous ne sommes pas prudents. +Je veux souligner que **ce n'est pas comme cela que les choses se font en Rust!** Il est très facile de faire des erreurs en travaillant avec des pointeurs bruts à l'intérieur de blocs `unsafe`. Par exemple, nous pourrions facilement écrire au-delà de la fin du tampon si nous ne sommes pas prudents. -Alors nous voulons minimiser l'utilisation de `unsafe` autant que possible. Rust nous offre la possibilité de faire cela en créant des abstractions sécuritaires. Par exemple, nous pourrions créer un type tampon VGA qui encapsule les risques et qui s'assure qu'il est impossible de faire quoi que ce soit d'incorrect à l'extérieur de ce type. Ainsi, nous aurions besoin de très peu de code `unsafe` and nous serions certains que nous ne violons pas la [memory safety][sécurité de mémoire]. Nous allons créer une telle abstraction de tampon VGA buffer dans le prochain article. +Alors nous voulons minimiser l'utilisation de `unsafe` autant que possible. Rust nous offre la possibilité de le faire en créant des abstractions de sécurité. Par exemple, nous pourrions créer un type tampon VGA qui encapsule les risques et qui s'assure qu'il est impossible de faire quoi que ce soit d'incorrect à l'extérieur de ce type. Ainsi, nous aurions besoin de très peu de code `unsafe` et nous serions certains que nous ne violons pas la [memory safety][sécurité de mémoire]. Nous allons créer une telle abstraction de tampon VGA buffer dans le prochain article. [memory safety]: https://en.wikipedia.org/wiki/Memory_safety @@ -395,11 +395,11 @@ Maintenant que nous avons un exécutable qui fait quelque chose de perceptible, ### Créer une image d'amorçage -Pour transformer notre noyau compilé en image de disque amorçable, nous devons le lier avec un bootloader. Comme nous l'avons appris dans la [section about booting][section à propos du lancement], le bootloader est responsable de lancer le processeur et de charger notre noyau. +Pour transformer notre noyau compilé en image de disque amorçable, nous devons le lier avec un bootloader. Comme nous l'avons appris dans la [section about booting][section à propos du lancement], le bootloader est responsable de l'initialisation du processeur et du chargement de notre noyau. [section about booting]: #the-boot-process -Plutôt que d'écrire notre propre bootloader, ce qui est un projet en soi, nous utilisons la caisse [`bootloader`]. Cette caisse propose un bootloader BIOS de base sans dépendance C, seulement du code Rust et de l'assembleur intégré. Pour l'utiliser pour lancer notre noyau, nous devons ajouter une dépendance pour cette caisse: +Plutôt que d'écrire notre propre bootloader, ce qui est un projet en soi, nous utilisons la crate [`bootloader`]. Cette crate propose un bootloader BIOS de base sans dépendance C. Seulement du code Rust et de l'assembleur intégré. Pour l'utiliser afin de lancer notre noyau, nous devons ajouter une dépendance à cette crate: [`bootloader`]: https://crates.io/crates/bootloader @@ -422,13 +422,13 @@ cargo install bootimage Pour exécuter `bootimage` et construire le bootloader, vous devez avoir la composante rustup `llvm-tools-preview` installée. Vous pouvez l'installer en exécutant `rustup component add llvm-tools-preview`. -Après avoir installé `bootimage` and ajouté la composante `llvm-tools-preview`, nous pouvons créer une image de disque amorçable en exécutant: +Après avoir installé `bootimage` et ajouté la composante `llvm-tools-preview`, nous pouvons créer une image de disque amorçable en exécutant: ``` > cargo bootimage ``` -Nous voyons que l'outil recompile notre noyau en utilisant `cargo build`, alors il utilisera automatiquement tout changement que vous faites. Ensuite, il compile le bootloader, ce qui peut prendre un certain temps. Comme toutes les dépendances de caisses, il est seulement construit une fois puis il est mis en cache, donc les builds subséquentes seront beaucoup plus rapides. Enfin, `bootimage` combine le bootloader et le noyau en une image de disque amorçable. +Nous voyons que l'outil recompile notre noyau en utilisant `cargo build`, donc il utilisera automatiquement tout changements que vous faites. Ensuite, il compile le bootloader, ce qui peut prendre un certain temps. Comme toutes les dépendances de crates, il est seulement construit une fois puis il est mis en cache, donc les builds subséquentes seront beaucoup plus rapides. Enfin, `bootimage` combine le bootloader et le noyau en une image de disque amorçable. Après avoir exécuté la commande, vous devriez voir une image de disque amorçable nommée `bootimage-blog_os.bin` dans votre dossier `target/x86_64-blog_os/debug`. Vous pouvez la lancer dans une machine virtuelle ou la copier sur une clé USB pour la lancer sur du véritable matériel. (Notez que ceci n'est pas une image CD, qui est un format différent, donc la graver sur un CD ne fonctionne pas). @@ -487,7 +487,7 @@ runner = "bootimage runner" La table `target.'cfg(target_os = "none")'` s'applique à toutes les cibles dont le champ `"os"` dans le fichier de configuration est défini à `"none"`. Ceci inclut notre cible `x86_64-blog_os.json`. La clé `runner` key spécifie la commande qui doit être invoquée pour `cargo run`. La commande est exécutée après une build réussie avec le chemin de l'exécutable comme premier argument. Voir la [configuration cargo][cargo configuration] pour plus de détails. -La commande `bootimage runner` est spécifiquement conçue pour être utilisable comme un exécutable `runner`. Elle lie l'exécutable fourni avec le bootloader duquel dépend le projet et lance ensuite QEMU. Voir le [Readme of `bootimage`][README de `bootimage`] pour plus de détails et les options de configuration possibles. +La commande `bootimage runner` est spécifiquement conçue pour être utilisable comme un exécutable `runner`. Elle lie l'exécutable fourni avec le bootloader duquel dépend le projet et lance ensuite QEMU. Voir le [Readme of `bootimage`][README de `bootimage`] pour plus de détails et les options de configuration possibles. [Readme of `bootimage`]: https://github.com/rust-osdev/bootimage From 7a44cd1f604cb819cf08d8d156629f259b092a92 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 28 Oct 2022 10:14:50 +0200 Subject: [PATCH 23/23] Add `alaincao` to translation contributors --- blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md index e1659068..cb423bc4 100644 --- a/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md +++ b/blog/content/edition-2/posts/02-minimal-rust-kernel/index.fr.md @@ -10,6 +10,8 @@ chapter = "Bare Bones" translation_based_on_commit = "c689ecf810f8e93f6b2fb3c4e1e8b89b8a0998eb" # GitHub usernames of the people that translated this post translators = ["TheMimiCodes", "maximevaillancourt"] +# GitHub usernames of the people that contributed to this translation +translation_contributors = ["alaincao"] +++ Dans cet article, nous créons un noyau Rust 64-bit minimal pour l'architecture x86. Nous continuons le travail fait dans l'article précédent ([freestanding Rust binary][binaire Rust autonome]) pour créer une image de disque amorçable qui affiche quelque chose à l'écran.