mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-21 16:37:48 +00:00
Compare commits
38 Commits
edition-3
...
bde9fd0262
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bde9fd0262 | ||
|
|
bd361ee25a | ||
|
|
f13ccee48b | ||
|
|
e4316a8a16 | ||
|
|
3eeb25c946 | ||
|
|
813f434ecd | ||
|
|
71f5d220ee | ||
|
|
71e5ea0268 | ||
|
|
da82fe8a0f | ||
|
|
2b444d3262 | ||
|
|
b118828956 | ||
|
|
4595872c6b | ||
|
|
1dced13b29 | ||
|
|
4b023bb432 | ||
|
|
b1b35833d6 | ||
|
|
34120a0409 | ||
|
|
6367e931e5 | ||
|
|
02fe09d56f | ||
|
|
f4ab296b8b | ||
|
|
db4068826b | ||
|
|
9b1791a48d | ||
|
|
61d074cc6c | ||
|
|
417c22556d | ||
|
|
5b4d04e337 | ||
|
|
684ef64767 | ||
|
|
87d0ce5fa2 | ||
|
|
5b67cb05ff | ||
|
|
81b7829657 | ||
|
|
1ddeb129ac | ||
|
|
53d181d57b | ||
|
|
b634a24f4b | ||
|
|
4ef59648be | ||
|
|
73628c1d05 | ||
|
|
2e3230eca2 | ||
|
|
63dc179cc7 | ||
|
|
211544af00 | ||
|
|
1ff26bb4b6 | ||
|
|
7ce356f99d |
@@ -8,7 +8,7 @@ from github import Github
|
|||||||
|
|
||||||
g = Github()
|
g = Github()
|
||||||
|
|
||||||
one_month_ago = datetime.datetime.now() - datetime.timedelta(days=32)
|
one_month_ago = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=32)
|
||||||
|
|
||||||
def filter_date(issue):
|
def filter_date(issue):
|
||||||
return issue.closed_at > one_month_ago
|
return issue.closed_at > one_month_ago
|
||||||
|
|||||||
@@ -49,6 +49,13 @@ translated_content_notice = "This is a community translation of the <strong><a h
|
|||||||
translated_by = "Translation by"
|
translated_by = "Translation by"
|
||||||
translation_contributors = "With contributions from"
|
translation_contributors = "With contributions from"
|
||||||
word_separator = "and"
|
word_separator = "and"
|
||||||
|
support_me = """
|
||||||
|
<h2>Support Me</h2>
|
||||||
|
<p>Creating and maintaining this blog and the associated libraries is a lot of work, but I really enjoy doing it. By supporting me, you allow me to invest more time in new content, new features, and continuous maintenance. The best way to support me is to <a href="https://github.com/sponsors/phil-opp"><em>sponsor me on GitHub</em></a>. Thank you!</p>
|
||||||
|
"""
|
||||||
|
comment_note = """
|
||||||
|
Do you have a problem, want to share feedback, or discuss further ideas? Feel free to leave a comment here! Please stick to English and follow Rust's <a href="https://www.rust-lang.org/policies/code-of-conduct">code of conduct</a>. This comment thread directly maps to a <a href="_discussion_url_"><em>discussion on GitHub</em></a>, so you can also comment there if you prefer.
|
||||||
|
"""
|
||||||
|
|
||||||
# Chinese (simplified)
|
# Chinese (simplified)
|
||||||
[languages.zh-CN]
|
[languages.zh-CN]
|
||||||
@@ -67,6 +74,13 @@ translated_content_notice = "这是对原文章 <strong><a href=\"_original.perm
|
|||||||
translated_by = "翻译者:"
|
translated_by = "翻译者:"
|
||||||
translation_contributors = "With contributions from"
|
translation_contributors = "With contributions from"
|
||||||
word_separator = "和"
|
word_separator = "和"
|
||||||
|
support_me = """
|
||||||
|
<h2>支持我</h2>
|
||||||
|
<p>创建和维护这个博客以及相关的库带来了十分庞大的工作量,即便我十分热爱它们,仍然需要你们的支持。通过赞助我,可以让我有能投入更多时间与精力在创造新内容,开发新功能上。赞助我最好的办法是通过<a href="https://github.com/sponsors/phil-opp"><em>sponsor me on GitHub</em></a>. 十分感谢各位!</p>
|
||||||
|
"""
|
||||||
|
comment_note = """
|
||||||
|
你有问题需要解决,想要分享反馈,或者讨论更多的想法吗?请随时在这里留下评论!请使用尽量使用英文并遵循 Rust 的 <a href="https://www.rust-lang.org/policies/code-of-conduct">code of conduct</a>. 这个讨论串将与 <a href="_discussion_url_"><em>discussion on GitHub</em></a> 直接连接,所以你也可以直接在那边发表评论
|
||||||
|
"""
|
||||||
|
|
||||||
# Chinese (traditional)
|
# Chinese (traditional)
|
||||||
[languages.zh-TW]
|
[languages.zh-TW]
|
||||||
@@ -85,6 +99,13 @@ translated_content_notice = "這是對原文章 <strong><a href=\"_original.perm
|
|||||||
translated_by = "翻譯者:"
|
translated_by = "翻譯者:"
|
||||||
translation_contributors = "With contributions from"
|
translation_contributors = "With contributions from"
|
||||||
word_separator = "和"
|
word_separator = "和"
|
||||||
|
support_me = """
|
||||||
|
<h2>Support Me</h2>
|
||||||
|
<p>Creating and maintaining this blog and the associated libraries is a lot of work, but I really enjoy doing it. By supporting me, you allow me to invest more time in new content, new features, and continuous maintenance. The best way to support me is to <a href="https://github.com/sponsors/phil-opp"><em>sponsor me on GitHub</em></a>. Thank you!</p>
|
||||||
|
"""
|
||||||
|
comment_note = """
|
||||||
|
Do you have a problem, want to share feedback, or discuss further ideas? Feel free to leave a comment here! Please stick to English and follow Rust's <a href="https://www.rust-lang.org/policies/code-of-conduct">code of conduct</a>. This comment thread directly maps to a <a href="_discussion_url_"><em>discussion on GitHub</em></a>, so you can also comment there if you prefer.
|
||||||
|
"""
|
||||||
|
|
||||||
# Japanese
|
# Japanese
|
||||||
[languages.ja]
|
[languages.ja]
|
||||||
@@ -103,6 +124,13 @@ translated_content_notice = "この記事は<strong><a href=\"_original.permalin
|
|||||||
translated_by = "翻訳者:"
|
translated_by = "翻訳者:"
|
||||||
translation_contributors = "With contributions from"
|
translation_contributors = "With contributions from"
|
||||||
word_separator = "及び"
|
word_separator = "及び"
|
||||||
|
support_me = """
|
||||||
|
<h2>Support Me</h2>
|
||||||
|
<p>Creating and maintaining this blog and the associated libraries is a lot of work, but I really enjoy doing it. By supporting me, you allow me to invest more time in new content, new features, and continuous maintenance. The best way to support me is to <a href="https://github.com/sponsors/phil-opp"><em>sponsor me on GitHub</em></a>. Thank you!</p>
|
||||||
|
"""
|
||||||
|
comment_note = """
|
||||||
|
Do you have a problem, want to share feedback, or discuss further ideas? Feel free to leave a comment here! Please stick to English and follow Rust's <a href="https://www.rust-lang.org/policies/code-of-conduct">code of conduct</a>. This comment thread directly maps to a <a href="_discussion_url_"><em>discussion on GitHub</em></a>, so you can also comment there if you prefer.
|
||||||
|
"""
|
||||||
|
|
||||||
# Persian
|
# Persian
|
||||||
[languages.fa]
|
[languages.fa]
|
||||||
@@ -121,6 +149,13 @@ translated_content_notice = "این یک ترجمه از جامعه کاربرا
|
|||||||
translated_by = "ترجمه توسط"
|
translated_by = "ترجمه توسط"
|
||||||
translation_contributors = "With contributions from"
|
translation_contributors = "With contributions from"
|
||||||
word_separator = "و"
|
word_separator = "و"
|
||||||
|
support_me = """
|
||||||
|
<h2>Support Me</h2>
|
||||||
|
<p>Creating and maintaining this blog and the associated libraries is a lot of work, but I really enjoy doing it. By supporting me, you allow me to invest more time in new content, new features, and continuous maintenance. The best way to support me is to <a href="https://github.com/sponsors/phil-opp"><em>sponsor me on GitHub</em></a>. Thank you!</p>
|
||||||
|
"""
|
||||||
|
comment_note = """
|
||||||
|
Do you have a problem, want to share feedback, or discuss further ideas? Feel free to leave a comment here! Please stick to English and follow Rust's <a href="https://www.rust-lang.org/policies/code-of-conduct">code of conduct</a>. This comment thread directly maps to a <a href="_discussion_url_"><em>discussion on GitHub</em></a>, so you can also comment there if you prefer.
|
||||||
|
"""
|
||||||
|
|
||||||
# Russian
|
# Russian
|
||||||
[languages.ru]
|
[languages.ru]
|
||||||
@@ -139,6 +174,13 @@ translated_content_notice = "Это перевод сообщества пост
|
|||||||
translated_by = "Перевод сделан"
|
translated_by = "Перевод сделан"
|
||||||
translation_contributors = "With contributions from"
|
translation_contributors = "With contributions from"
|
||||||
word_separator = "и"
|
word_separator = "и"
|
||||||
|
support_me = """
|
||||||
|
<h2>Support Me</h2>
|
||||||
|
<p>Creating and maintaining this blog and the associated libraries is a lot of work, but I really enjoy doing it. By supporting me, you allow me to invest more time in new content, new features, and continuous maintenance. The best way to support me is to <a href="https://github.com/sponsors/phil-opp"><em>sponsor me on GitHub</em></a>. Thank you!</p>
|
||||||
|
"""
|
||||||
|
comment_note = """
|
||||||
|
Do you have a problem, want to share feedback, or discuss further ideas? Feel free to leave a comment here! Please stick to English and follow Rust's <a href="https://www.rust-lang.org/policies/code-of-conduct">code of conduct</a>. This comment thread directly maps to a <a href="_discussion_url_"><em>discussion on GitHub</em></a>, so you can also comment there if you prefer.
|
||||||
|
"""
|
||||||
|
|
||||||
# French
|
# French
|
||||||
[languages.fr]
|
[languages.fr]
|
||||||
@@ -157,6 +199,13 @@ translated_content_notice = "Ceci est une traduction communautaire de l'article
|
|||||||
translated_by = "Traduit par : "
|
translated_by = "Traduit par : "
|
||||||
translation_contributors = "With contributions from"
|
translation_contributors = "With contributions from"
|
||||||
word_separator = "et"
|
word_separator = "et"
|
||||||
|
support_me = """
|
||||||
|
<h2>Support Me</h2>
|
||||||
|
<p>Creating and maintaining this blog and the associated libraries is a lot of work, but I really enjoy doing it. By supporting me, you allow me to invest more time in new content, new features, and continuous maintenance. The best way to support me is to <a href="https://github.com/sponsors/phil-opp"><em>sponsor me on GitHub</em></a>. Thank you!</p>
|
||||||
|
"""
|
||||||
|
comment_note = """
|
||||||
|
Do you have a problem, want to share feedback, or discuss further ideas? Feel free to leave a comment here! Please stick to English and follow Rust's <a href="https://www.rust-lang.org/policies/code-of-conduct">code of conduct</a>. This comment thread directly maps to a <a href="_discussion_url_"><em>discussion on GitHub</em></a>, so you can also comment there if you prefer.
|
||||||
|
"""
|
||||||
|
|
||||||
# Korean
|
# Korean
|
||||||
[languages.ko]
|
[languages.ko]
|
||||||
@@ -175,3 +224,10 @@ translated_content_notice = "이것은 커뮤니티 멤버가 <strong><a href=\"
|
|||||||
translated_by = "번역한 사람 : "
|
translated_by = "번역한 사람 : "
|
||||||
translation_contributors = "With contributions from"
|
translation_contributors = "With contributions from"
|
||||||
word_separator = "와"
|
word_separator = "와"
|
||||||
|
support_me = """
|
||||||
|
<h2>Support Me</h2>
|
||||||
|
<p>Creating and maintaining this blog and the associated libraries is a lot of work, but I really enjoy doing it. By supporting me, you allow me to invest more time in new content, new features, and continuous maintenance. The best way to support me is to <a href="https://github.com/sponsors/phil-opp"><em>sponsor me on GitHub</em></a>. Thank you!</p>
|
||||||
|
"""
|
||||||
|
comment_note = """
|
||||||
|
Do you have a problem, want to share feedback, or discuss further ideas? Feel free to leave a comment here! Please stick to English and follow Rust's <a href="https://www.rust-lang.org/policies/code-of-conduct">code of conduct</a>. This comment thread directly maps to a <a href="_discussion_url_"><em>discussion on GitHub</em></a>, so you can also comment there if you prefer.
|
||||||
|
"""
|
||||||
|
|||||||
@@ -505,7 +505,7 @@ A minimal target specification that describes the `x86_64-unknown-linux-gnu` tar
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
"target-c-int-width": "32",
|
"target-c-int-width": "32",
|
||||||
@@ -527,7 +527,7 @@ In order to disable the multimedia extensions, we create a new target named `x86
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
"target-c-int-width": "32",
|
"target-c-int-width": "32",
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ Rust allows us to define [custom targets] through a JSON configuration file. A m
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"linker-flavor": "gcc",
|
"linker-flavor": "gcc",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -133,7 +133,7 @@ For our target system, we define the following JSON configuration in a file name
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"linker-flavor": "gcc",
|
"linker-flavor": "gcc",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ rtl = true
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -145,7 +145,7 @@ rtl = true
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -204,7 +204,7 @@ For more information, see our post on [disabling SIMD](@/edition-2/posts/02-mini
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ Pour notre système cible toutefois, nous avons besoin de paramètres de configu
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -141,7 +141,7 @@ Nous pouvons aussi cibler les systèmes `x86_64` avec notre noyau, donc notre sp
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -201,7 +201,7 @@ Notre fichier de spécification de cible ressemble maintenant à ceci :
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ chapter = "Bare Bones"
|
|||||||
# Please update this when updating the translation
|
# Please update this when updating the translation
|
||||||
translation_based_on_commit = "7212ffaa8383122b1eb07fe1854814f99d2e1af4"
|
translation_based_on_commit = "7212ffaa8383122b1eb07fe1854814f99d2e1af4"
|
||||||
# GitHub usernames of the people that translated this post
|
# GitHub usernames of the people that translated this post
|
||||||
translators = ["woodyZootopia", "JohnTitor"]
|
translators = ["swnakamura", "JohnTitor"]
|
||||||
+++
|
+++
|
||||||
|
|
||||||
この記事では、Rustで最小限の64bitカーネルを作ります。前の記事で作った[フリースタンディングなRustバイナリ][freestanding Rust binary]を下敷きにして、何かを画面に出力する、ブータブルディスクイメージを作ります。
|
この記事では、Rustで最小限の64bitカーネルを作ります。前の記事で作った[フリースタンディングなRustバイナリ][freestanding Rust binary]を下敷きにして、何かを画面に出力する、ブータブルディスクイメージを作ります。
|
||||||
@@ -116,7 +116,7 @@ Cargoは`--target`パラメータを使ってさまざまなターゲットを
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -139,7 +139,7 @@ Cargoは`--target`パラメータを使ってさまざまなターゲットを
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -198,7 +198,7 @@ SIMDを無効化することによる問題に、`x86_64`における浮動小
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ Cargo는 `--target` 인자를 통해 여러 컴파일 대상 시스템들을 지
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -148,7 +148,7 @@ Cargo는 `--target` 인자를 통해 여러 컴파일 대상 시스템들을 지
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -209,7 +209,7 @@ SIMD 레지스터 값들을 메모리에 백업하고 또 다시 복구하는
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ For our target system, however, we require some special configuration parameters
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -135,7 +135,7 @@ We also target `x86_64` systems with our kernel, so our target specification wil
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -195,7 +195,7 @@ Our target specification file now looks like this:
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -260,7 +260,7 @@ That's where the [`build-std` feature] of cargo comes in. It allows to recompile
|
|||||||
[`build-std` feature]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std
|
[`build-std` feature]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std
|
||||||
[nightly Rust compilers]: #installing-rust-nightly
|
[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:
|
To use the feature, we need to create a local [cargo configuration] file at `.cargo/config.toml` (the `.cargo` folder should be next to your `src` folder) with the following content:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
# in .cargo/config.toml
|
# in .cargo/config.toml
|
||||||
@@ -410,7 +410,7 @@ Adding the bootloader as a dependency is not enough to actually create a bootabl
|
|||||||
|
|
||||||
[post-build scripts]: https://github.com/rust-lang/cargo/issues/545
|
[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:
|
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, go into your home directory (or any directory outside of your cargo project) and execute the following command in your terminal:
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo install bootimage
|
cargo install bootimage
|
||||||
@@ -418,7 +418,7 @@ 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`.
|
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:
|
After installing `bootimage` and adding the `llvm-tools-preview` component, you can create a bootable disk image by going back into your cargo project directory and executing:
|
||||||
|
|
||||||
```
|
```
|
||||||
> cargo bootimage
|
> cargo bootimage
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ Cargo поддерживает различные целевые системы
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -142,7 +142,7 @@ Cargo поддерживает различные целевые системы
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -202,7 +202,7 @@ Cargo поддерживает различные целевые системы
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ translation_contributors = ["JiangengDong"]
|
|||||||
|
|
||||||
在这篇文章中,我们将基于 **x86架构**(the x86 architecture),使用 Rust 语言,编写一个最小化的 64 位内核。我们将从上一章中构建的[独立式可执行程序][freestanding-rust-binary]开始,构建自己的内核;它将向显示器打印字符串,并能被打包为一个能够引导启动的**磁盘映像**(disk image)。
|
在这篇文章中,我们将基于 **x86架构**(the x86 architecture),使用 Rust 语言,编写一个最小化的 64 位内核。我们将从上一章中构建的[独立式可执行程序][freestanding-rust-binary]开始,构建自己的内核;它将向显示器打印字符串,并能被打包为一个能够引导启动的**磁盘映像**(disk image)。
|
||||||
|
|
||||||
[freestanding Rust binary]: @/edition-2/posts/01-freestanding-rust-binary/index.md
|
[freestanding-rust-binary]: @/edition-2/posts/01-freestanding-rust-binary/index.md
|
||||||
|
|
||||||
<!-- more -->
|
<!-- more -->
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ Nightly 版本的编译器允许我们在源码的开头插入**特性标签**
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-linux-gnu",
|
"llvm-target": "x86_64-unknown-linux-gnu",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -112,7 +112,7 @@ Nightly 版本的编译器允许我们在源码的开头插入**特性标签**
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -157,14 +157,16 @@ Nightly 版本的编译器允许我们在源码的开头插入**特性标签**
|
|||||||
|
|
||||||
禁用 SIMD 产生的一个问题是,`x86_64` 架构的浮点数指针运算默认依赖于 SIMD 寄存器。我们的解决方法是,启用 `soft-float` 特征,它将使用基于整数的软件功能,模拟浮点数指针运算。
|
禁用 SIMD 产生的一个问题是,`x86_64` 架构的浮点数指针运算默认依赖于 SIMD 寄存器。我们的解决方法是,启用 `soft-float` 特征,它将使用基于整数的软件功能,模拟浮点数指针运算。
|
||||||
|
|
||||||
为了让读者的印象更清晰,我们撰写了一篇关于 [禁用 SIMD][disabling SIMD](@/edition-2/posts/02-minimal-rust-kernel/disable-simd/index.zh-CN.md) 的短文。
|
为了让读者的印象更清晰,我们撰写了一篇关于 [禁用 SIMD][disabling SIMD] 的短文。
|
||||||
|
|
||||||
|
[disabling SIMD]: @/edition-2/posts/02-minimal-rust-kernel/disable-simd/index.zh-CN.md
|
||||||
|
|
||||||
现在,我们将各个配置项整合在一起。我们的目标配置清单应该长这样:
|
现在,我们将各个配置项整合在一起。我们的目标配置清单应该长这样:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"llvm-target": "x86_64-unknown-none",
|
"llvm-target": "x86_64-unknown-none",
|
||||||
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
|
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
|
||||||
"arch": "x86_64",
|
"arch": "x86_64",
|
||||||
"target-endian": "little",
|
"target-endian": "little",
|
||||||
"target-pointer-width": "64",
|
"target-pointer-width": "64",
|
||||||
@@ -225,10 +227,10 @@ error[E0463]: can't find crate for `core`
|
|||||||
|
|
||||||
#### `build-std` 选项
|
#### `build-std` 选项
|
||||||
|
|
||||||
此时就到了cargo中 [`build-std` 特性][`build-std` feature] 登场的时刻,该特性允许你按照自己的需要重编译 `core` 等标准crate,而不需要使用Rust安装程序内置的预编译版本。 但是该特性是全新的功能,到目前为止尚未完全完成,所以它被标记为 "unstable" 且仅被允许在 [nightly Rust 编译器][nightly Rust compilers] 环境下调用。
|
此时就到了cargo中 [`build-std` 特性][`build-std` feature] 登场的时刻,该特性允许你按照自己的需要重编译 `core` 等标准crate,而不需要使用Rust安装程序内置的预编译版本。 但是该特性是全新的功能,到目前为止尚未完全完成,所以它被标记为 "unstable" 且仅被允许在 [Nightly Rust 编译器][Nightly Rust compilers] 环境下调用。
|
||||||
|
|
||||||
[`build-std` feature]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std
|
[`build-std` feature]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std
|
||||||
[nightly Rust compilers]: #安装 Nightly Rust
|
[Nightly Rust compilers]:https://os.phil-opp.com/zh-CN/minimal-rust-kernel/#an-zhuang-nightly-rust
|
||||||
|
|
||||||
要启用该特性,你需要创建一个 [cargo 配置][cargo configuration] 文件,即 `.cargo/config.toml`,并写入以下语句:
|
要启用该特性,你需要创建一个 [cargo 配置][cargo configuration] 文件,即 `.cargo/config.toml`,并写入以下语句:
|
||||||
|
|
||||||
@@ -347,7 +349,7 @@ pub extern "C" fn _start() -> ! {
|
|||||||
|
|
||||||
使用 `unsafe` 语句块要求程序员有足够的自信,所以必须强调的一点是,**肆意使用 unsafe 语句块并不是 Rust 编程的一贯方式**。在缺乏足够经验的前提下,直接在 `unsafe` 语句块内操作裸指针,非常容易把事情弄得很糟糕;比如,在不注意的情况下,我们很可能会意外地操作缓冲区以外的内存。
|
使用 `unsafe` 语句块要求程序员有足够的自信,所以必须强调的一点是,**肆意使用 unsafe 语句块并不是 Rust 编程的一贯方式**。在缺乏足够经验的前提下,直接在 `unsafe` 语句块内操作裸指针,非常容易把事情弄得很糟糕;比如,在不注意的情况下,我们很可能会意外地操作缓冲区以外的内存。
|
||||||
|
|
||||||
在这样的前提下,我们希望最小化 `unsafe ` 语句块的使用。使用 Rust 语言,我们能够将不安全操作将包装为一个安全的抽象模块。举个例子,我们可以创建一个 VGA 缓冲区类型,把所有的不安全语句封装起来,来确保从类型外部操作时,无法写出不安全的代码:通过这种方式,我们只需要最少的 `unsafe` 语句块来确保我们不破坏**内存安全**([memory safety](https://en.wikipedia.org/wiki/Memory_safety))。在下一篇文章中,我们将会创建这样的 VGA 缓冲区封装。
|
在这样的前提下,我们希望最小化 `unsafe` 语句块的使用。使用 Rust 语言,我们能够将不安全操作将包装为一个安全的抽象模块。举个例子,我们可以创建一个 VGA 缓冲区类型,把所有的不安全语句封装起来,来确保从类型外部操作时,无法写出不安全的代码:通过这种方式,我们只需要最少的 `unsafe` 语句块来确保我们不破坏**内存安全**([memory safety](https://en.wikipedia.org/wiki/Memory_safety))。在下一篇文章中,我们将会创建这样的 VGA 缓冲区封装。
|
||||||
|
|
||||||
## 启动内核
|
## 启动内核
|
||||||
|
|
||||||
@@ -396,7 +398,7 @@ cargo install bootimage
|
|||||||
|
|
||||||
### 在 QEMU 中启动内核
|
### 在 QEMU 中启动内核
|
||||||
|
|
||||||
现在我们可以在虚拟机中启动内核了。为了在[ QEMU](https://www.qemu.org/) 中启动内核,我们使用下面的命令:
|
现在我们可以在虚拟机中启动内核了。为了在[QEMU](https://www.qemu.org/) 中启动内核,我们使用下面的命令:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
> qemu-system-x86_64 -drive format=raw,file=target/x86_64-blog_os/debug/bootimage-blog_os.bin
|
> qemu-system-x86_64 -drive format=raw,file=target/x86_64-blog_os/debug/bootimage-blog_os.bin
|
||||||
@@ -426,7 +428,7 @@ warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
|
|||||||
要让在 QEMU 中运行内核更轻松,我们可以设置在 cargo 配置文件中设置 `runner` 配置项:
|
要让在 QEMU 中运行内核更轻松,我们可以设置在 cargo 配置文件中设置 `runner` 配置项:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
# in .cargo/config
|
# in .cargo/config.toml
|
||||||
|
|
||||||
[target.'cfg(target_os = "none")']
|
[target.'cfg(target_os = "none")']
|
||||||
runner = "bootimage runner"
|
runner = "bootimage runner"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ chapter = "Bare Bones"
|
|||||||
# Please update this when updating the translation
|
# Please update this when updating the translation
|
||||||
translation_based_on_commit = "bd6fbcb1c36705b2c474d7fcee387bfea1210851"
|
translation_based_on_commit = "bd6fbcb1c36705b2c474d7fcee387bfea1210851"
|
||||||
# GitHub usernames of the people that translated this post
|
# GitHub usernames of the people that translated this post
|
||||||
translators = ["woodyZootopia", "JohnTitor"]
|
translators = ["swnakamura", "JohnTitor"]
|
||||||
+++
|
+++
|
||||||
|
|
||||||
[VGAテキストモード][VGA text mode]は画面にテキストを出力するシンプルな方法です。この記事では、すべてのunsafeな要素を別のモジュールにカプセル化することで、それを安全かつシンプルに扱えるようにするインターフェースを作ります。また、Rustの[フォーマッティングマクロ][formatting macros]のサポートも実装します。
|
[VGAテキストモード][VGA text mode]は画面にテキストを出力するシンプルな方法です。この記事では、すべてのunsafeな要素を別のモジュールにカプセル化することで、それを安全かつシンプルに扱えるようにするインターフェースを作ります。また、Rustの[フォーマッティングマクロ][formatting macros]のサポートも実装します。
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ pub struct Writer {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
我们将让这个 `Writer` 类型将字符写入屏幕的最后一行,并在一行写满或接收到换行符 `\n` 的时候,将所有的字符向上位移一行。`column_position` 变量将跟踪光标在最后一行的位置。当前字符的前景和背景色将由 `color_code` 变量指定;另外,我们存入一个 VGA 字符缓冲区的可变借用到`buffer`变量中。需要注意的是,这里我们对借用使用**显式生命周期**([explicit lifetime](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-annotation-syntax)),告诉编译器这个借用在何时有效:我们使用** `'static` 生命周期 **(['static lifetime](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#the-static-lifetime)),意味着这个借用应该在整个程序的运行期间有效;这对一个全局有效的 VGA 字符缓冲区来说,是非常合理的。
|
我们将让这个 `Writer` 类型将字符写入屏幕的最后一行,并在一行写满或接收到换行符 `\n` 的时候,将所有的字符向上位移一行。`column_position` 变量将跟踪光标在最后一行的位置。当前字符的前景和背景色将由 `color_code` 变量指定;另外,我们存入一个 VGA 字符缓冲区的可变借用到`buffer`变量中。需要注意的是,这里我们对借用使用**显式生命周期**([explicit lifetime](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-annotation-syntax)),告诉编译器这个借用在何时有效:我们使用 `'static` 生命周期(['static lifetime](https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#the-static-lifetime)),意味着这个借用应该在整个程序的运行期间有效;这对一个全局有效的 VGA 字符缓冲区来说,是非常合理的。
|
||||||
|
|
||||||
### 打印字符
|
### 打印字符
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ error[E0463]: can't find crate for `test`
|
|||||||
#![test_runner(crate::test_runner)]
|
#![test_runner(crate::test_runner)]
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn test_runner(tests: &[&dyn Fn()]) {
|
pub fn test_runner(tests: &[&dyn Fn()]) {
|
||||||
println!("Running {} tests", tests.len());
|
println!("Running {} tests", tests.len());
|
||||||
for test in tests {
|
for test in tests {
|
||||||
test();
|
test();
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ chapter = "Bare Bones"
|
|||||||
# Please update this when updating the translation
|
# Please update this when updating the translation
|
||||||
translation_based_on_commit = "dce5c9825bd4e7ea6c9530e999c9d58f80c585cc"
|
translation_based_on_commit = "dce5c9825bd4e7ea6c9530e999c9d58f80c585cc"
|
||||||
# GitHub usernames of the people that translated this post
|
# GitHub usernames of the people that translated this post
|
||||||
translators = ["woodyZootopia", "JohnTitor"]
|
translators = ["swnakamura", "JohnTitor"]
|
||||||
+++
|
+++
|
||||||
|
|
||||||
この記事では、`no_std`な実行環境における<ruby>単体テスト<rp> (</rp><rt>unit test</rt><rp>) </rp></ruby>と<ruby>結合テスト<rp> (</rp><rt>integration test</rt><rp>) </rp></ruby>について学びます。Rustではカスタムテストフレームワークがサポートされているので、これを使ってカーネルの中でテスト関数を実行します。QEMUの外へとテストの結果を通知するため、QEMUと`bootimage`の様々な機能を使います。
|
この記事では、`no_std`な実行環境における<ruby>単体テスト<rp> (</rp><rt>unit test</rt><rp>) </rp></ruby>と<ruby>結合テスト<rp> (</rp><rt>integration test</rt><rp>) </rp></ruby>について学びます。Rustではカスタムテストフレームワークがサポートされているので、これを使ってカーネルの中でテスト関数を実行します。QEMUの外へとテストの結果を通知するため、QEMUと`bootimage`の様々な機能を使います。
|
||||||
@@ -81,7 +81,7 @@ error[E0463]: can't find crate for `test`
|
|||||||
#![test_runner(crate::test_runner)]
|
#![test_runner(crate::test_runner)]
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn test_runner(tests: &[&dyn Fn()]) {
|
pub fn test_runner(tests: &[&dyn Fn()]) {
|
||||||
println!("Running {} tests", tests.len());
|
println!("Running {} tests", tests.len());
|
||||||
for test in tests {
|
for test in tests {
|
||||||
test();
|
test();
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ To implement a custom test framework for our kernel, we add the following to our
|
|||||||
#![test_runner(crate::test_runner)]
|
#![test_runner(crate::test_runner)]
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn test_runner(tests: &[&dyn Fn()]) {
|
pub fn test_runner(tests: &[&dyn Fn()]) {
|
||||||
println!("Running {} tests", tests.len());
|
println!("Running {} tests", tests.len());
|
||||||
for test in tests {
|
for test in tests {
|
||||||
test();
|
test();
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ error[E0463]: can't find crate for `test`
|
|||||||
#![test_runner(crate::test_runner)]
|
#![test_runner(crate::test_runner)]
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn test_runner(tests: &[&dyn Fn()]) {
|
pub fn test_runner(tests: &[&dyn Fn()]) {
|
||||||
println!("Running {} tests", tests.len());
|
println!("Running {} tests", tests.len());
|
||||||
for test in tests {
|
for test in tests {
|
||||||
test();
|
test();
|
||||||
@@ -989,7 +989,7 @@ harness = false
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use blog_os::{QemuExitCode, exit_qemu, serial_println};
|
use blog_os::{QemuExitCode, exit_qemu, serial_println, serial_print};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn _start() -> ! {
|
pub extern "C" fn _start() -> ! {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ chapter = "Interrupts"
|
|||||||
# Please update this when updating the translation
|
# Please update this when updating the translation
|
||||||
translation_based_on_commit = "a8a6b725cff2e485bed76ff52ac1f18cec08cc7b"
|
translation_based_on_commit = "a8a6b725cff2e485bed76ff52ac1f18cec08cc7b"
|
||||||
# GitHub usernames of the people that translated this post
|
# GitHub usernames of the people that translated this post
|
||||||
translators = ["woodyZootopia"]
|
translators = ["swnakamura"]
|
||||||
+++
|
+++
|
||||||
|
|
||||||
CPU例外は、例えば無効なメモリアドレスにアクセスしたときやゼロ除算したときなど、様々なミスによって発生します。それらに対処するために、ハンドラ関数を提供する **<ruby>割り込み記述子表<rp> (</rp><rt>interrupt descriptor table</rt><rp>) </rp></ruby>** を設定しなくてはなりません。この記事を読み終わる頃には、私達のカーネルは[ブレークポイント例外][breakpoint exceptions]を捕捉し、その後通常の実行を継続できるようになっているでしょう。
|
CPU例外は、例えば無効なメモリアドレスにアクセスしたときやゼロ除算したときなど、様々なミスによって発生します。それらに対処するために、ハンドラ関数を提供する **<ruby>割り込み記述子表<rp> (</rp><rt>interrupt descriptor table</rt><rp>) </rp></ruby>** を設定しなくてはなりません。この記事を読み終わる頃には、私達のカーネルは[ブレークポイント例外][breakpoint exceptions]を捕捉し、その後通常の実行を継続できるようになっているでしょう。
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ chapter = "Interrupts"
|
|||||||
# Please update this when updating the translation
|
# Please update this when updating the translation
|
||||||
translation_based_on_commit = "81d4f49f153eb5f390681f5c13018dd2aa6be0b1"
|
translation_based_on_commit = "81d4f49f153eb5f390681f5c13018dd2aa6be0b1"
|
||||||
# GitHub usernames of the people that translated this post
|
# GitHub usernames of the people that translated this post
|
||||||
translators = ["shimomura1004", "woodyZootopia"]
|
translators = ["shimomura1004", "swnakamura"]
|
||||||
+++
|
+++
|
||||||
|
|
||||||
この記事では、ハードウェア割り込みを正しく CPU に転送するためにプログラム可能な割り込みコントローラの設定を行います。これらの割り込みに対処するため、例外ハンドラのときに行ったのと同じように割り込み記述子表に新しいエントリを追加しなくてはいけません。ここでは周期タイマ割り込みの受け方と、キーボードからの入力の受け方を学びます。
|
この記事では、ハードウェア割り込みを正しく CPU に転送するためにプログラム可能な割り込みコントローラの設定を行います。これらの割り込みに対処するため、例外ハンドラのときに行ったのと同じように割り込み記述子表に新しいエントリを追加しなくてはいけません。ここでは周期タイマ割り込みの受け方と、キーボードからの入力の受け方を学びます。
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ chapter = "Memory Management"
|
|||||||
# Please update this when updating the translation
|
# Please update this when updating the translation
|
||||||
translation_based_on_commit = "3315bfe2f63571f5e6e924d58ed32afd8f39f892"
|
translation_based_on_commit = "3315bfe2f63571f5e6e924d58ed32afd8f39f892"
|
||||||
# GitHub usernames of the people that translated this post
|
# GitHub usernames of the people that translated this post
|
||||||
translators = ["woodyZootopia", "JohnTitor"]
|
translators = ["swnakamura", "JohnTitor"]
|
||||||
+++
|
+++
|
||||||
|
|
||||||
この記事では**ページング**を紹介します。これは、私達のオペレーティングシステムにも使う、とても一般的なメモリ管理方式です。なぜメモリの分離が必要なのか、**セグメンテーション**がどういう仕組みなのか、**仮想メモリ**とは何なのか、ページングがいかにしてメモリ<ruby>断片化<rp> (</rp><rt>フラグメンテーション</rt><rp>) </rp></ruby>の問題を解決するのかを説明します。また、x86_64アーキテクチャにおける、マルチレベルページテーブルのレイアウトについても説明します。
|
この記事では**ページング**を紹介します。これは、私達のオペレーティングシステムにも使う、とても一般的なメモリ管理方式です。なぜメモリの分離が必要なのか、**セグメンテーション**がどういう仕組みなのか、**仮想メモリ**とは何なのか、ページングがいかにしてメモリ<ruby>断片化<rp> (</rp><rt>フラグメンテーション</rt><rp>) </rp></ruby>の問題を解決するのかを説明します。また、x86_64アーキテクチャにおける、マルチレベルページテーブルのレイアウトについても説明します。
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ x86_64 平台使用4级页表,页大小为4KiB,无论层级,每个页表
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
我们可以看到,每个表索引号占据9个字节,这当然是有道理的,每个表都有 2^9 = 512 个条目,低12位用来表示内存页的偏移量(2^12 bytes = 4KiB,而上文提到页大小为4KiB)。第48-64位毫无用处,这也就意味着 x86_64 并非真正的64位,因为它实际上支持48位地址。
|
我们可以看到,每个表索引号占据 9 个比特,这当然是有道理的,每个表都有 2^9 = 512 个条目,低12位用来表示内存页的偏移量(2^12 bytes = 4KiB,而上文提到页大小为4KiB)。第 48-64 位毫无用处,这也就意味着 x86_64 并非真正的 64 位,因为它实际上支持 48 位地址。
|
||||||
|
|
||||||
[5-level page table]: https://en.wikipedia.org/wiki/Intel_5-level_paging
|
[5-level page table]: https://en.wikipedia.org/wiki/Intel_5-level_paging
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ x86_64 平台使用4级页表,页大小为4KiB,无论层级,每个页表
|
|||||||
- 1个4级页表
|
- 1个4级页表
|
||||||
- 512个3级页表(因为4级页表可以有512个条目)
|
- 512个3级页表(因为4级页表可以有512个条目)
|
||||||
- 512*512个2级页表(因为每个3级页表可以有512个条目)
|
- 512*512个2级页表(因为每个3级页表可以有512个条目)
|
||||||
- 512*512*512个1级页表(因为每个2级页表可以有512个条目)
|
- 512\*512\*512个1级页表(因为每个2级页表可以有512个条目)
|
||||||
|
|
||||||
### 页表格式
|
### 页表格式
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ pub struct PageTable {
|
|||||||
| 63 | no execute | 禁止在该页中运行代码(EFER寄存器中的NXE比特位必须一同被设置) |
|
| 63 | no execute | 禁止在该页中运行代码(EFER寄存器中的NXE比特位必须一同被设置) |
|
||||||
|
|
||||||
我们可以看到,仅12–51位会用于存储页帧地址或页表地址,其余比特都用于存储标志位,或由操作系统自由使用。
|
我们可以看到,仅12–51位会用于存储页帧地址或页表地址,其余比特都用于存储标志位,或由操作系统自由使用。
|
||||||
其原因就是,该地址总是指向一个4096比特对齐的地址、页表或者页帧的起始地址。
|
其原因就是,该地址总是指向一个4096字节对齐的地址、页表或者页帧的起始地址。
|
||||||
这也就意味着0-11位始终为0,没有必要存储这些东西,硬件层面在使用该地址之前,也会将这12位比特设置为0,52-63位同理,因为x86_64平台仅支持52位物理地址(类似于上文中提到的仅支持48位虚拟地址的原因)。
|
这也就意味着0-11位始终为0,没有必要存储这些东西,硬件层面在使用该地址之前,也会将这12位比特设置为0,52-63位同理,因为x86_64平台仅支持52位物理地址(类似于上文中提到的仅支持48位虚拟地址的原因)。
|
||||||
|
|
||||||
进一步说明一下可用的标志位:
|
进一步说明一下可用的标志位:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ date = 2019-03-14
|
|||||||
[extra]
|
[extra]
|
||||||
chapter = "Memory Management"
|
chapter = "Memory Management"
|
||||||
translation_based_on_commit = "27ab4518acbb132e327ed4f4f0508393e9d4d684"
|
translation_based_on_commit = "27ab4518acbb132e327ed4f4f0508393e9d4d684"
|
||||||
translators = ["woodyZootopia", "garasubo"]
|
translators = ["swnakamura", "garasubo"]
|
||||||
+++
|
+++
|
||||||
|
|
||||||
この記事では私達のカーネルをページングに対応させる方法についてお伝えします。まずページテーブルの物理フレームにカーネルがアクセスできるようにする様々な方法を示し、それらの利点と欠点について議論します。次にアドレス変換関数を、ついで新しい<ruby>対応付け<rp> (</rp><rt>マッピング</rt><rp>) </rp></ruby>を作るための関数を実装します。
|
この記事では私達のカーネルをページングに対応させる方法についてお伝えします。まずページテーブルの物理フレームにカーネルがアクセスできるようにする様々な方法を示し、それらの利点と欠点について議論します。次にアドレス変換関数を、ついで新しい<ruby>対応付け<rp> (</rp><rt>マッピング</rt><rp>) </rp></ruby>を作るための関数を実装します。
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ chapter = "Memory Management"
|
|||||||
# Please update this when updating the translation
|
# Please update this when updating the translation
|
||||||
translation_based_on_commit = "afeed7477bb19a29d94a96b8b0620fd241b0d55f"
|
translation_based_on_commit = "afeed7477bb19a29d94a96b8b0620fd241b0d55f"
|
||||||
# GitHub usernames of the people that translated this post
|
# GitHub usernames of the people that translated this post
|
||||||
translators = ["woodyZootopia", "garasubo"]
|
translators = ["swnakamura", "garasubo"]
|
||||||
+++
|
+++
|
||||||
|
|
||||||
この記事では、私たちのカーネルにヒープ<ruby>割り当て<rp> (</rp><rt>アロケーション</rt><rp>) </rp></ruby>の機能を追加します。まず動的メモリの基礎を説明し、どのようにして借用チェッカがありがちなアロケーションエラーを防いでくれるのかを示します。その後Rustの基本的なアロケーションインターフェースを実装し、ヒープメモリ領域を作成し、アロケータクレートを設定します。この記事を終える頃には、Rustに組み込みの`alloc`クレートのすべてのアロケーション・コレクション型が私たちのカーネルで利用可能になっているでしょう。
|
この記事では、私たちのカーネルにヒープ<ruby>割り当て<rp> (</rp><rt>アロケーション</rt><rp>) </rp></ruby>の機能を追加します。まず動的メモリの基礎を説明し、どのようにして借用チェッカがありがちなアロケーションエラーを防いでくれるのかを示します。その後Rustの基本的なアロケーションインターフェースを実装し、ヒープメモリ領域を作成し、アロケータクレートを設定します。この記事を終える頃には、Rustに組み込みの`alloc`クレートのすべてのアロケーション・コレクション型が私たちのカーネルで利用可能になっているでしょう。
|
||||||
|
|||||||
1243
blog/content/edition-2/posts/11-allocator-designs/index.ja.md
Normal file
1243
blog/content/edition-2/posts/11-allocator-designs/index.ja.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@ chapter = "Multitasking"
|
|||||||
# Please update this when updating the translation
|
# Please update this when updating the translation
|
||||||
translation_based_on_commit = "bf4f88107966c7ab1327c3cdc0ebfbd76bad5c5f"
|
translation_based_on_commit = "bf4f88107966c7ab1327c3cdc0ebfbd76bad5c5f"
|
||||||
# GitHub usernames of the authors of this translation
|
# GitHub usernames of the authors of this translation
|
||||||
translators = ["kahirokunn", "garasubo", "sozysozbot", "woodyZootopia"]
|
translators = ["kahirokunn", "garasubo", "sozysozbot", "swnakamura"]
|
||||||
# GitHub usernames of the people that contributed to this translation
|
# GitHub usernames of the people that contributed to this translation
|
||||||
translation_contributors = ["asami-kawasaki", "Foo-x"]
|
translation_contributors = ["asami-kawasaki", "Foo-x"]
|
||||||
+++
|
+++
|
||||||
@@ -469,9 +469,9 @@ ExampleStateMachine::End(_) => {
|
|||||||
|
|
||||||
Futureは `Poll::Ready` を返した後、再びポーリングされるべきではありません。したがって、すでに `End` の状態にあるときに `poll` が呼ばれるとパニックするようにしましょう。
|
Futureは `Poll::Ready` を返した後、再びポーリングされるべきではありません。したがって、すでに `End` の状態にあるときに `poll` が呼ばれるとパニックするようにしましょう。
|
||||||
|
|
||||||
コンパイラが生成するステートマシンとその `Future` traitの実装はこのようになっている**かもしれません**。実際には、コンパイラは異なる方法でコードを生成しています。 (一応、現在は[_generators_]をベースにした実装になっていますが、これはあくまでも実装の詳細です。)
|
コンパイラが生成するステートマシンとその `Future` traitの実装はこのようになっている**かもしれません**。実際には、コンパイラは異なる方法でコードを生成しています。 (一応、現在は[_coroutines_]をベースにした実装になっていますが、これはあくまでも実装の詳細です。)
|
||||||
|
|
||||||
[_generators_]: https://doc.rust-lang.org/nightly/unstable-book/language-features/generators.html
|
[_coroutines_]: https://doc.rust-lang.org/stable/unstable-book/language-features/coroutines.html
|
||||||
|
|
||||||
パズルの最後のピースは、生成された `example` 関数自体のコードです。関数のヘッダは次のように定義されていたことを思い出してください:
|
パズルの最後のピースは、生成された `example` 関数自体のコードです。関数のヘッダは次のように定義されていたことを思い出してください:
|
||||||
|
|
||||||
|
|||||||
@@ -462,9 +462,9 @@ ExampleStateMachine::End(_) => {
|
|||||||
|
|
||||||
Futures should not be polled again after they returned `Poll::Ready`, so we panic if `poll` is called while we are already in the `End` state.
|
Futures should not be polled again after they returned `Poll::Ready`, so we panic if `poll` is called while we are already in the `End` state.
|
||||||
|
|
||||||
We now know what the compiler-generated state machine and its implementation of the `Future` trait _could_ look like. In practice, the compiler generates code in a different way. (In case you're interested, the implementation is currently based on [_generators_], but this is only an implementation detail.)
|
We now know what the compiler-generated state machine and its implementation of the `Future` trait _could_ look like. In practice, the compiler generates code in a different way. (In case you're interested, the implementation is currently based on [_coroutines_], but this is only an implementation detail.)
|
||||||
|
|
||||||
[_generators_]: https://doc.rust-lang.org/nightly/unstable-book/language-features/generators.html
|
[_coroutines_]: https://doc.rust-lang.org/stable/unstable-book/language-features/coroutines.html
|
||||||
|
|
||||||
The last piece of the puzzle is the generated code for the `example` function itself. Remember, the function header was defined like this:
|
The last piece of the puzzle is the generated code for the `example` function itself. Remember, the function header was defined like this:
|
||||||
|
|
||||||
|
|||||||
@@ -61,8 +61,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="">
|
<div class="">
|
||||||
<h2>Support Me</h2>
|
{{ trans(key="support_me", lang=lang) | safe }}
|
||||||
{{ snippets::support() }}
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock main %}
|
{% endblock main %}
|
||||||
|
|
||||||
|
|||||||
@@ -91,8 +91,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="post-footer-support{% if page.extra.rtl %} right-to-left{% endif %}">
|
<div class="post-footer-support{% if page.extra.rtl %} right-to-left{% endif %}">
|
||||||
<h2>Support Me</h2>
|
{{ trans(key="support_me", lang=lang) | safe }}
|
||||||
{{ snippets::support() }}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|||||||
@@ -1,15 +1,3 @@
|
|||||||
{% macro support() %}
|
|
||||||
<p>
|
|
||||||
Creating and <a href="{{ get_url(path="@/status-update/_index.md") }}">maintaining</a> this blog and the associated libraries is a lot of work, but I really enjoy doing it. By supporting me, you allow me to invest more time in new content, new features, and continuous maintenance.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The best way to support me is to <a href="https://github.com/sponsors/phil-opp"><em>sponsor me on GitHub</em></a>, since they don't charge any fees. If you prefer other platforms, I also have <a href="https://www.patreon.com/phil_opp"><em>Patreon</em></a> and <a href="https://donorbox.org/phil-opp"><em>Donorbox</em></a> accounts. The latter is the most flexible as it supports multiple currencies and one-time contributions.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Thank you!
|
|
||||||
</p>
|
|
||||||
{% endmacro support %}
|
|
||||||
|
|
||||||
{% macro giscus(search_term, lang) %}
|
{% macro giscus(search_term, lang) %}
|
||||||
{% if lang != "en" %}
|
{% if lang != "en" %}
|
||||||
{% set category = "Post Comments (translated)" %}
|
{% set category = "Post Comments (translated)" %}
|
||||||
@@ -24,12 +12,12 @@
|
|||||||
{% if search_term is number %}
|
{% if search_term is number %}
|
||||||
{% set discussion_url = "https://github.com/phil-opp/blog_os/discussions/" ~ search_term %}
|
{% set discussion_url = "https://github.com/phil-opp/blog_os/discussions/" ~ search_term %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set search_term_encoded = `"` ~ search_term ~ `"` | urlencode %}
|
{% set search_term_encoded = `"` ~ search_term ~ `"` ~ ` in:title` | urlencode %}
|
||||||
{% set discussion_url = `https://github.com/phil-opp/blog_os/discussions/categories/` ~ category_path ~ `?discussions_q=` ~ search_term_encoded %}
|
{% set discussion_url = `https://github.com/phil-opp/blog_os/discussions/categories/` ~ category_path ~ `?discussions_q=` ~ search_term_encoded %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<p class="comment-note">
|
<p class="comment-note">
|
||||||
Do you have a problem, want to share feedback, or discuss further ideas? Feel free to leave a comment here! Please stick to English and follow Rust's <a href="https://www.rust-lang.org/policies/code-of-conduct">code of conduct</a>. This comment thread directly maps to a <a href="{{ discussion_url | safe }}"><em>discussion on GitHub</em></a>, so you can also comment there if you prefer.
|
{{ trans(key="comment_note", lang=lang) | replace(from="_discussion_url_", to=discussion_url) | safe }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="giscus"></div>
|
<div class="giscus"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user