├── .gitignore
├── EDITOR_GUIDE.md
├── Gemfile
├── LICENSE
├── README.md
├── _includes
└── breadcrumbs.html
├── _layouts
└── default.html
├── browser
├── cover.png
├── errata.md
└── index.md
├── errata.md
└── os1
├── cover.png
├── errata.md
└── index.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # This .gitignore is appropriate for repositories deployed to GitHub Pages and using
2 | # a Gemfile as specified at https://github.com/github/pages-gem#conventional
3 |
4 | # Basic Jekyll gitignores (synchronize to Jekyll.gitignore)
5 | _site/
6 | .sass-cache/
7 | .jekyll-cache/
8 | .jekyll-metadata
9 |
10 | # Additional Ruby/bundler ignore for when you run: bundle install
11 | /vendor
12 |
13 | # Specific ignore for GitHub Pages
14 | # GitHub Pages will always use its own deployed version of pages-gem
15 | # This means GitHub Pages will NOT use your Gemfile.lock and therefore it is
16 | # counterproductive to check this file into the repository.
17 | # Details at https://github.com/github/pages-gem/issues/768
18 | Gemfile.lock
19 |
--------------------------------------------------------------------------------
/EDITOR_GUIDE.md:
--------------------------------------------------------------------------------
1 | ```
2 | sudo apt-get install ruby-full
3 | gem install bundler
4 | bundle install
5 | bundle exec jekyll serve
6 | ```
7 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source "https://rubygems.org"
4 |
5 | # gem "jekyll"
6 | gem "github-pages", "~> 232", group: :jekyll_plugins
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 hikalium
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [Wasabi サポートページ](https://lowlayergirls.github.io/wasabi-help/) へようこそ!
2 |
3 | [
4 |
5 | 「[作って学ぶ] ブラウザのしくみ」
6 | サポートページはこちら
7 | ](./browser/)
8 |
9 | ----
10 |
11 | [
12 |
13 | 「[作って学ぶ] OSのしくみI」
14 | サポートページはこちら
15 | ](./os1)
16 |
--------------------------------------------------------------------------------
/_includes/breadcrumbs.html:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/_layouts/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {% seo %}
9 |
10 | {% include head-custom.html %}
11 |
12 |
13 |
14 | {% include breadcrumbs.html %}
15 | {% if site.title and site.title != page.title and false %}
16 |
17 | {% endif %}
18 |
19 | {{ content }}
20 |
21 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/browser/cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lowlayergirls/wasabi-help/11a0e8659504d903562eb13d92722969db5aa89f/browser/cover.png
--------------------------------------------------------------------------------
/browser/errata.md:
--------------------------------------------------------------------------------
1 | - Table of Content
2 | {:toc}
3 |
4 | # 正誤表(最終更新日:2025/04/23)
5 |
6 | 本書に下記のとおり誤りがございました。お詫びして訂正いたします。
7 |
8 | # 初版第1刷をお持ちの方(第2刷で修正済み)
9 |
10 | ## p.vii 「アプリケーションをWasabiOSで動かす」1段落目
11 |
12 | - 誤:
13 |
14 | アプリケーションをWasabiOSで動かすためには、cargo buildコマンドでビルドしたアプリケーションのバイナリを、WasabiOSが提供するrun_with_app.shというスクリプトを使用して走らせる必要があります。これらを自動的に行ってくれる便利なシェルスクリプトを用意したので、以下のスクリプトを自分のプロジェクトに追加してください。または、d0iasm/saba/run_on_wasabi.shからコピーすることもできます。
15 |
16 | - 正:
17 |
18 | アプリケーションをWasabiOSで**動かすには**、cargo buildコマンドでビルドしたアプリケーションのバイナリを、WasabiOSが提供するrun_with_app.shというスクリプトを使用して走らせる必要があります。これらを自動的に**行う**シェルスクリプトを用意したので、以下のスクリプトを**後ほどcargoコマンドによって作成するプロジェクトのトップディレクトリに追加してください。d0iasm/saba/run_on_wasabi.shからコピーもできます。**
19 |
20 | ## p.viii 1つ目のリスト下から6行目
21 |
22 | - 誤:wget https://raw.githubusercontent.com/hikalium/wasabi/main/external_app_template/
23 | - 正:wget https://raw.githubusercontent.com/hikalium/wasabi/**for_saba**/external_app_template/**↵**
24 |
25 | ## p.viii 3段落1行目
26 |
27 | - 誤:
28 |
29 | また、もしスクリプトが途中で失敗したら、rm -rf buildなどによりダウンロードしたWasabiOSのソースコードを削除してみてください。
30 |
31 | - 正:
32 |
33 | **もし**スクリプトが途中で失敗したら、rm -rf buildなど**で**ダウンロードしたWasabiOSのソースコードを**削除してください**。**環境によってはwgetの導入が必要です。**
34 |
35 | ## p.ix 4段落1行目
36 |
37 | - 誤:スクリプトを走らせると、QEMUのアプリケーションが開始します(図0-1)。
38 | - 正:**スクリプト**を走らせると、QEMUのアプリケーション**上でOS**が開始します(図0-1)。
39 |
40 | ## p.28 「ストレージ」1段落5行目
41 |
42 | - 誤:少なくとも合計で3,000個までのCookieを保存
43 | - 正:少なくとも合計で3,000個**の**Cookieを保存
44 |
45 | ## p.48 「スキームの確認」2つ目のリスト上から3行目
46 |
47 | - 誤:fn is_http(&mut self) -> bool {
48 | - 正:fn is_http(**&self**) -> bool {
49 |
50 | ## p.57 1つ目のリスト7行目
51 | - 誤:let url = "http://example.com:8888/index.html?a=123&b= 456".to_string();
52 | - 正:let url = "http://example.com:8888/index.html?a=123&**b=456**".to_string();
53 |
54 | 「3&b= 456」の半角スペースを削除
55 |
56 | ## p.75 2つ目のリスト3行目
57 | - 誤:use crate::alloc::string::ToString;
58 | - 正:use **alloc**::string::ToString;
59 |
60 | ## p.77 2行目
61 | - 誤:コネクション確率
62 | - 正:コネクション**確立**
63 |
64 | ## p.84 「文字列の前処理」2段落3行目
65 | - 誤:改行シーケンス(\n\r)
66 | - 正:改行シーケンス(**\r\n**)
67 |
68 | ## p.84 「文字列の前処理」2段落4行目
69 | - 誤:\n\rはWindows
70 | - 正:**\r\n**はWindows
71 |
72 | ## p.84 2つ目のリスト5行目
73 | - 誤:raw_response.trim_start().replace("\n\r", "\n");
74 | - 正:raw_response.trim_start().replace("**\r\n**", "\n");
75 |
76 | ## p.84 3つ目のリスト5行目
77 | - 誤:raw_response.trim_start().replace("\n\r", "\n");
78 | - 正:raw_response.trim_start().replace("**\r\n**", "\n");
79 |
80 | ## p.126 「AttributeValueUnquoted状態の実装」1段落1行目
81 | - 誤:シングルクオートで囲まれたタグ
82 | - 正:**クオート**で囲まれ**ていない**タグ
83 |
84 | ## p.130 1つ目のリスト3行目
85 | - 誤:either↵StartTag
86 | - 正:either StartTag
87 |
88 | 間の矢印を削除し半角スペースに
89 |
90 | ## p.134 1つ目のコマンド1行目
91 | - 誤:$ mv saba_core
92 | - 正:$ **cd** saba_core
93 |
94 | ## p.188 1つ目のコマンド1行目
95 | - 誤:$ mv saba_core
96 | - 正:$ **cd** saba_core
97 |
98 | ## p.215 1つ目のリスト10行目
99 | - 誤:(self.consume_numeric_token());
100 | - 正:(self.consume_numeric_t**oken());**
101 |
102 | 「oken());」の部分を太字に
103 |
104 | ## p.216 1つ目のリスト5行目
105 | - 誤:floating_digit
106 | - 正:f**loating_digit**
107 |
108 | 「loating_digit」の部分を太字に
109 |
110 | ## p.216 1つ目のリスト7行目
111 | - 誤:c.to_digit(10).unwrap() as f64
112 | - 正:c.to_digit(10).unwrap() **as f64**
113 |
114 | 「as f64」の部分を太字に
115 |
116 | ## p.241 1つ目のコマンド7,8行目
117 | - 誤:
118 |
119 | ```
120 | ├── layout_object.rs
121 | ├── layout_point.rs
122 | ├── layout_size.rs
123 | └── layout_view.rs
124 | ```
125 |
126 | - 正:
127 |
128 | ```
129 | ├── layout_object.rs
130 | └── layout_view.rs
131 | ```
132 |
133 | ## p.438 「ローカルサーバの構築」2段落1行目
134 | - 誤:OSを起動させたあと、
135 | - 正:OSを起動させ**、sabaと入力しアプリケーションを開始した**あと、
136 |
137 | # 初版第1~2刷をお持ちの方(第3刷で修正済み)
138 |
139 | ## p90 「メイン関数の実装」リスト下から1行目
140 | - 誤:match client.get("example.com".to_string(), 80, "/".to_string()) {
141 | - 正:match client.get("example.com".to_string(), 80, **""**.to_string()) { ◀「"/"」の「/」を削除
142 |
143 | ## p94 「メイン関数の変更」リスト5行目
144 | - 誤:match client.get("host.test".to_string(), 8000, "/test.html".to_string()) {
145 | - 正:match client.get("host.test".to_string(), 8000, "**test.html**".to_string()) {
146 |
147 | ## p127 「AfterAttributeValueQuoted 状態の実装」2段落7行目
148 | - 誤:BeforeAttributeValue 状態に移動します。
149 | - 正:BeforeAttribute**Name**状態に移動します。
150 |
151 | ## p128 リスト下から7行目
152 | - 誤:self.state = State::BeforeAttributeValue;
153 | - 正:self.state = State::BeforeAttribute**Name**;
154 |
155 | ## p166 「要素ノードの追加」2段落2行目
156 | - 誤:ノード(current)呼ぶ
157 | - 正:るノード(current)**と**呼ぶ
158 |
159 | ## p167 リスト
160 |
161 | - 誤:
162 |
163 | ```
164 | if current.borrow().first_child().is_some() { ── ❹
165 | let mut last_sibiling = current.borrow().first_child();
166 | loop { ── ❺
167 | last_sibiling = match last_sibiling {
168 | Some(ref node) => {
169 | if node.borrow().next_sibling().is_some() {
170 | node.borrow().next_sibling()
171 | } else {
172 | break;
173 | }
174 | }
175 | None => unimplemented!("last_sibiling should be Some"),
176 | };
177 | }
178 |
179 | last_sibiling
180 | .unwrap()
181 | .borrow_mut()
182 | .set_next_sibling(Some(node.clone())); ── ❻
183 | node.borrow_mut().set_previous_sibling(Rc::downgrade(
184 | ¤t
185 | .borrow()
186 | .first_child()
187 | .expect("failed to get a first child"),
188 | ))
189 | } else { ── ❼
190 | current.borrow_mut().set_first_child(Some(node.clone())); ── ❽
191 | }
192 |
193 | current.borrow_mut().set_last_child(Rc::downgrade(&node)); ── ❾
194 | node.borrow_mut().set_parent(Rc::downgrade(¤t)); ── ❿
195 |
196 | self.stack_of_open_elements.push(node); ── ⓫
197 | }
198 | }
199 | ```
200 |
201 | - 正:
202 |
203 | ```
204 | if current.borrow().first_child().is_some() { ── ❹
205 | let mut last_sibling = current.borrow().first_child(); ◀「sibling」のスペルを修正
206 | loop { ── ❺
207 | last_sibling = match last_sibling { ◀「sibling」のスペルを修正
208 | Some(ref node) => {
209 | if node.borrow().next_sibling().is_some() {
210 | node.borrow().next_sibling()
211 | } else {
212 | break;
213 | }
214 | }
215 | None => unimplemented!("last_sibling should be Some"), ◀「sibling」のスペルを修正
216 | };
217 | }
218 |
219 | last_sibling ◀「sibling」のスペルを修正
220 | .as_ref() ◀追加
221 | .unwrap()
222 | .borrow_mut()
223 | .set_next_sibling(Some(node.clone())); ── ❻
224 | node.borrow_mut().set_previous_sibling(Rc::downgrade(
225 | &last_sibling.expect("last_sibling should be Some") ◀変更
226 | ))
227 | } else { ── ❼
228 | current.borrow_mut().set_first_child(Some(node.clone())); ── ❽
229 | }
230 |
231 | current.borrow_mut().set_last_child(Rc::downgrade(&node)); ── ❾
232 | node.borrow_mut().set_parent(Rc::downgrade(¤t)); ── ❿
233 |
234 | self.stack_of_open_elements.push(node); ── ⓫
235 | }
236 | }
237 | ```
238 |
239 | ## p171 リストの19行目
240 |
241 | - 誤:
242 |
243 | ```
244 | if current.borrow().first_child().is_some() { ── ❺
245 | current
246 | .borrow()
247 | .first_child()
248 | .unwrap()
249 | .borrow_mut()
250 | .set_next_sibling(Some(node.clone())); ── ❻
251 | node.borrow_mut().set_previous_sibling(Rc::downgrade(
252 | ¤t
253 | .borrow()
254 | .first_child()
255 | .expect("failed to get a first child"),
256 | ));
257 | ```
258 |
259 | - 正:
260 |
261 | ```
262 | if current.borrow().first_child().is_some() { ── ❺
263 | current
264 | .borrow()
265 | .first_child()
266 | .unwrap()
267 | .borrow_mut()
268 | .set_next_sibling(Some(node.clone())); ── ❻
269 | ◀削除
270 | ```
271 |
272 | ## p273 「位置の計算」2段落3、4、5行目
273 | - 誤:sibiling
274 | - 正:**sibling**
275 |
276 | ## p273-274 リスト5、6、7、12、13、14行目
277 | - 誤:sibiling
278 | - 正:**sibling**
279 |
280 | ## p275 リスト5、6、7、11、14、15、24、25行目
281 | - 誤:sibiling
282 | - 正:**sibling**
283 |
284 | ## p334 リスト下から7行目
285 | - 誤:return Err(Error::InvalidUI("failed to draw a string".to_string()));
286 | - 正:return Err(Error::InvalidUI("failed to draw a **rect**".to_string()));
287 |
288 | ## p379 リスト1行目
289 |
290 | - 誤:
291 |
292 | ```
293 | if self.input[self.pos].is_ascii_alphanumeric() || self.input[self.pos] == '$' {
294 | ```
295 |
296 |
297 | - 正:
298 |
299 | ```
300 | if self.input[self.pos].is_ascii_alphanumeric()
301 | || self.input[s elf.pos] == '_' || self.input[self.pos] == '$' { ◀「|| self.input[s elf.pos] == '_'」を追加
302 | ```
303 |
304 | ## p384 1つ目のリスト10行目
305 |
306 | - 誤: ::= (& | _ | a-z | A-Z) (& | a-z | A-Z)*
307 | - 正: ::= ($ | _ | a-z | A-Z)+ ◀「$」「+」に変更
308 |
309 | ## p394 「変数の取得」1段落1行目
310 |
311 | - 誤:Environment 構造体に保存されている変数をまずvariablesに保存されている変数をチェックし
312 | - 正:Environment 構造体**の**variablesに保存されている変数をチェックし
313 |
314 | ## p394 「変数の追加と更新」1段落1行目、2段落1行目
315 |
316 | - 誤:varialbe
317 | - 正:vari**able**
318 |
319 | ## p395 「evalメソッドの変更」3段落3行目、6段落1行目
320 |
321 | - 誤:varialbe
322 | - 正:vari**able**
323 |
324 | ## p405 上から3行目
325 |
326 | - 誤:変名
327 | - 正:変**数**名
328 |
329 | ## p426 「ブラウザAPIを呼び出すメソッドの追加」4段落4行目
330 |
331 | - 誤:取得ための
332 | - 正:取得**する**ための
333 |
334 | # 初版第1~3刷をお持ちの方
335 |
336 | ## p379 リスト上から2行目
337 |
338 | - 誤:`|| self.input[s elf.pos] == '_' || self.input[self.pos] == '$' {`
339 | - 正:`|| self.input[self.pos] == '_' || self.input[self.pos] == '$' {` ◀「s elf」から半角スペースを削除
340 |
--------------------------------------------------------------------------------
/browser/index.md:
--------------------------------------------------------------------------------
1 | # 「作って学ぶ ブラウザのしくみ」サポートページ
2 | このページは、[土井麻未(d0iasm) 著 「作って学ぶ ブラウザのしくみ」(技術評論社, 2024)](https://gihyo.jp/book/2024/978-4-297-14546-0)の内容を補完する情報を掲載しています。
3 |
4 | 本ページや上記書籍についてのフィードバックは、[本サポートサイトの GitHub Issues](https://github.com/lowlayergirls/wasabi-help/issues)経由で著者までお知らせください。
5 |
6 | ハッシュタグは [#作って学ぶブラウザのしくみ](https://x.com/search?q=%23%E4%BD%9C%E3%81%A3%E3%81%A6%E5%AD%A6%E3%81%B6%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF&src=typed_query&f=live) です。
7 |
8 |
9 |
10 | ## 関連リンク
11 |
12 | -
13 | -
14 |
15 | # 正誤情報
16 |
17 | [『[作って学ぶ]ブラウザのしくみ』正誤表](./errata)
18 |
19 | # 補足情報
20 |
21 | ## wgetがみつからない
22 |
23 | 原因: wgetコマンドがインストールされていない。(macOS等)
24 |
25 | 解決策: wgetコマンドをHomebrew等のパッケージマネージャ経由でインストールするか、`wget`を`curl -O`(curlのあとに半角スペース、続いてハイフンと大文字アルファベットO)に置き換えて実行してみてください。
26 |
27 | ## (コード修正済)`the x86_64-unknown-none target may not be installed`
28 |
29 | **(2024-11-11)[Makefileの変更](https://github.com/hikalium/wasabi/commit/4796f62364ce8f24613dccba60618e1d35254b16)により修正しました。**
30 | **`run_on_wasabi.sh`によって自動的にダウンロードしたMakefileを削除し、もう一度`run_on_wasabi.sh`スクリプトを走らせると問題は出なくなっているはずです。**
31 |
32 | 症状: 以下のようなエラーが`./run_on_wasabi.sh`を実行した際に発生し、失敗する。
33 |
34 | ```
35 | error[E0463]: can't find crate for `core`
36 | |
37 | = note: the `x86_64-unknown-none` target may not be installed
38 | = help: consider downloading the target with `rustup target add x86_64-unknown-none`
39 |
40 | For more information about this error, try `rustc --explain E0463`.
41 | error: could not compile `sabi` (lib) due to 1 previous error
42 | ```
43 |
44 | 解決策: 以下のコマンドを実行してから再度試してみてください。
45 | ```
46 | rustup target add x86_64-unknown-none
47 | ```
48 |
49 | それでもだめな場合は、cargoがパスに正しく登録されていない可能性があります。rustupのインストールをやり直すか、パスを手動で追加して実行してみてください。
50 | ```
51 | export PATH="$HOME/.cargo/bin:$PATH"
52 | rustup target add x86_64-unknown-none
53 | ```
54 |
55 | #### Reference
56 |
57 | -
58 |
59 | ## (コード修正済)環境構築のHello, Worldで、"No route" "Timed out"という WARN が出ている
60 |
61 | **(2024-11-11)[OS側のログ出力の変更](https://github.com/hikalium/wasabi/commit/abf27c6f587e777fce5c53234d45d997ed075996)により修正しました。**
62 |
63 | これはOS側のコード由来のWarningなので、無視して大丈夫です。
64 |
65 | エラーを無視して自作OS上で`saba`と実行すれば、Hello, worldが表示されます。
66 |
67 | ## run_on_wasabi.shを実行してもQEMUが起動しない
68 |
69 | ```
70 | export DISPLAY=0
71 | ```
72 |
73 | を実行してから再度試してみてください。OS側ビルドスクリプトでの修正を予定しています。
74 |
75 | #### Reference
76 |
77 | -
78 |
79 | ## net/wasabi/src/http.rsでcrate::alloc::string::ToStringが見つからない
80 |
81 | `net/wasabi/src/http.rs`で`ToString`モジュールをインポートする際、unresolved importのエラーになってしまう。
82 |
83 | ```
84 | error[E0433]: failed to resolve: unresolved import
85 | --> net/wasabi/src/http.rs:4:12
86 | |
87 | 4 | use crate::alloc::string::ToString;
88 | | ^^^^^
89 | | |
90 | | unresolved import
91 | | help: a similar path exists: `core::alloc`
92 | ```
93 |
94 | [リファレンスコード](https://github.com/d0iasm/sababook/blob/main/ch3/saba/net/wasabi/src/http.rs)にあるように、`crate`をつけずに`use alloc::string::ToString`としてください。
95 |
96 | 書籍のコードは次の版で修正予定です。
97 |
98 | #### Reference
99 |
100 | -
101 |
102 | ## 関連書『[作って学ぶ]OSのしくみ』の出版予定
103 |
104 | 『[作って学ぶ]ブラウザのしくみ』の中で関連書として紹介している『[作って学ぶ]OSのしくみ』は、2025年の刊行を予定しております。刊行まで、もうしばらくお待ち下さい。
105 |
106 | なお、OS部分のソースコードについては、機能的に同等なものを[こちら](https://github.com/hikalium/wasabi)から読むことができます。
107 |
--------------------------------------------------------------------------------
/errata.md:
--------------------------------------------------------------------------------
1 | [
2 |
3 | 「[作って学ぶ] ブラウザのしくみ」
4 | 正誤表はこちら
5 | ](./browser/errata)
6 |
7 | ----
8 |
9 | [
10 |
11 | 「[作って学ぶ] OSのしくみI」
12 | 正誤表はこちら
13 | ](./os1/errata)
14 |
--------------------------------------------------------------------------------
/os1/cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lowlayergirls/wasabi-help/11a0e8659504d903562eb13d92722969db5aa89f/os1/cover.png
--------------------------------------------------------------------------------
/os1/errata.md:
--------------------------------------------------------------------------------
1 | - Table of Content
2 | {:toc}
3 |
4 | # 正誤表(最終更新日:2025/05/03)
5 |
6 | 本書に下記のとおり誤りがございました。お詫びして訂正いたします。
7 |
8 | # 初版第1刷の正誤表
9 |
10 | ## p.xv「第4章 マルチタスクを実装しよう」目次要素
11 |
12 | - 誤:
13 |
14 | aync/awaitを使えるようにする
15 |
16 | - 正:
17 |
18 | async/awaitを使えるようにする
19 |
20 | ## p.48「"Hello, world"はどこへ行く?」2段落目
21 |
22 | - 誤:
23 |
24 | 鍵となるのは、この`prinln!`です。
25 |
26 | - 正:
27 |
28 | 鍵となるのは、この`println!`です。
29 |
30 |
31 | ## p.161「OSのテストをRustで書く」3段落2行目
32 |
33 | - 誤:
34 |
35 | うまくいったら正常に終了し、そうでなければ`panic()`するような関数を書けばよいです。
36 |
37 | - 正:
38 |
39 | うまくいったら正常に終了し、そうでなければ`panic!()`するような関数を書けばよいです。
40 |
41 | ## p.161「OSのテストをRustで書く」3段落4行目
42 |
43 | - 誤:
44 |
45 | もし想定と違えば`panic()`するような
46 |
47 | - 正:
48 |
49 | もし想定と違えば`panic!()`するような
50 |
51 | ## p.162「シリアルポート出力の実装」4段落目
52 |
53 | - 誤:
54 |
55 | 今回はエミューレーターを使用して
56 |
57 | - 正:
58 |
59 | 今回はエミュレーターを使用して
60 |
61 | ## p.167 サンプルコード`src/allocator.rs`内
62 |
63 | - 誤:
64 |
65 | ```
66 | assert_eq!(round_up_to_nearest_pow2(9), Ok(16));
67 | assert_eq!(round_up_to_nearest_pow2(9), Ok(16));
68 | ```
69 |
70 | - 正:
71 |
72 | ```
73 | assert_eq!(round_up_to_nearest_pow2(9), Ok(16));
74 |
75 | ```
76 |
77 | (注:
78 | テストケースの最後の2つが冗長でしたので片方を削除しました。残っていても間違いではありませんが、削除したほうがより適切です。)
79 |
80 | ## p.188 コードブロック内
81 |
82 | 最上部のコードブロックと、ページ中央のコードブロックの2箇所について:
83 |
84 | - 誤:
85 |
86 | ```
87 | 0x0XAC_TUWP
88 | ```
89 |
90 | - 正:
91 |
92 | ```
93 | 0b0XAC_TUWP
94 | ```
95 |
96 | ## p.194 「async/awaitを使えるようにする」4段落目
97 |
98 | - 誤:
99 |
100 | _Identity mapping_
101 |
102 | - 正:
103 |
104 | _Identity Mapping_
105 |
106 | ## p.204 サンプルコード`src/x86.rs`内
107 |
108 | - 誤:
109 |
110 | ```
111 | struct FPUContenxt {
112 | ```
113 |
114 | - 正:
115 |
116 | ```
117 | struct FPUContext {
118 | ```
119 |
120 | ## p.205 サンプルコード`src/x86.rs`内
121 |
122 | - 誤:
123 |
124 | ```
125 | fpu_context: FPUContenxt, // used by FXSAVE / FXRSTOR
126 | ```
127 |
128 | - 正:
129 |
130 | ```
131 | fpu_context: FPUContext, // used by FXSAVE / FXRSTOR
132 | ```
133 |
134 | ## p.214 サンプルコード`src/x86.rs`内
135 |
136 | - 誤:
137 |
138 | ```
139 | pub const BIT_CS_READABLE: u64 = 1u64 << 53;
140 | ```
141 |
142 | - 正:
143 |
144 | ```
145 | pub const BIT_CS_READABLE: u64 = 1u64 << 41;
146 | ```
147 |
148 | ## p.219 サンプルコード`src/uefi.rs`内
149 |
150 | - 誤:
151 |
152 | ```
153 | #[derive(Debug, PartialEq, Eq, Copy, Clone)]
154 | #[must_use]
155 | #[repr(u64)]
156 | descriptor_size: *mut usize,
157 | descriptor_version: *mut u32,
158 | ) -> EfiStatus,
159 | ```
160 |
161 | - 正:
162 |
163 | ```
164 | #[derive(Debug, PartialEq, Eq, Copy, Clone)]
165 | #[must_use]
166 | #[repr(u64)]
167 |
168 | // << 中略 >>
169 |
170 | pub struct EfiBootServicesTable {
171 | // << 中略 >>
172 | descriptor_size: *mut usize,
173 | descriptor_version: *mut u32,
174 | ) -> EfiStatus,
175 | ```
176 |
177 | ## p.220 サンプルコード内 `locate_loaded_image_protocol()`関数内
178 |
179 | ここでは`graphic_output_protocol`という名前の変数が宣言・使用されていますが、実際には`loaded_image_protocol`に相当する値を格納する変数となっています。したがって、これに即した変数名とするのがより適切でした。プログラム自体の動作には影響ありませんが、混乱を招いたことをお詫びいたします。
180 |
181 | ## p.224 サンプルコード`src/init.rs`内
182 |
183 | - 誤:
184 |
185 | ```
186 | pub fn init_basic_runtime(
187 | image_handle: EfiHandle,
188 | ALLOCATOR.init_with_mmap(&memory_map);
189 | memory_map
190 | }
191 | ```
192 |
193 | - 正:
194 |
195 | ```
196 | pub fn init_basic_runtime(
197 | image_handle: EfiHandle,
198 |
199 | // << 中略 >>
200 |
201 | ALLOCATOR.init_with_mmap(&memory_map);
202 | memory_map
203 | }
204 | ```
205 |
206 | ## p.245 「async/awaitを使えるようにする」見出し
207 |
208 | - 誤:
209 |
210 | aync/awaitを使えるようにする
211 |
212 | - 正:
213 |
214 | async/awaitを使えるようにする
215 |
216 | ## p.311「ECAM ―― Enhanced Configuration Access Method」3段落目
217 |
218 | - 誤:
219 |
220 | 各デバイスに対応するConfiguration間
221 |
222 | - 正:
223 |
224 | 各デバイスに対応するConfiguration空間
225 |
226 | ## p.312 ページ一番下のコマンド出力結果について
227 |
228 | - 誤:
229 |
230 | ```
231 | $ qemu-system-x86_64 -machine ? | grep q35 | head -n 1
232 | ```
233 |
234 | - 正:
235 |
236 | ```
237 | $ qemu-system-x86_64 -machine '?' | grep q35 | head -n 1
238 | ```
239 |
--------------------------------------------------------------------------------
/os1/index.md:
--------------------------------------------------------------------------------
1 | # 「作って学ぶ OSのしくみ(I)」サポートページ
2 | このページは、[hikalium 著 「作って学ぶ OSのしくみ(I)」(技術評論社, 2025)](https://gihyo.jp/book/2025/978-4-297-14859-1)の内容を補完する情報を掲載しています。
3 |
4 | 本ページや上記書籍についてのフィードバックは、[本サポートサイトの GitHub Issues](https://github.com/lowlayergirls/wasabi-help/issues)経由で著者までお知らせください。
5 |
6 | ハッシュタグは [#OSのしくみ](https://x.com/search?q=%23OS%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF%20OR%20%E4%BD%9C%E3%81%A3%E3%81%A6%E5%AD%A6%E3%81%B6OS%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF&src=typed_query&f=live) です。
7 |
8 |
9 |
10 | ## 関連リンク
11 |
12 | -
13 | -
14 |
15 | # 正誤情報
16 |
17 | [『[作って学ぶ]OSのしくみ』正誤表](./errata)
18 |
19 | # 補足情報
20 |
21 | ## `rust-analyzer`の設定について
22 |
23 | Rustのコードを書く際には`rust-analyzer`というLSPサーバーが非常に便利です。筆者もいつも大変お世話になっています。
24 | しかし、本書のリポジトリで`rust-analyzer`がうまく動作しない場合があるようですので、その解決策をご紹介します。
25 |
26 | 本書のリポジトリでは再現性を確保するため、Rustツールチェインのバージョンを`rust-toolchain.toml`に記載のとおり固定しています。そのため、より新しいバージョンのRustツールチェインに同梱されている`rust-analyzer`を使用すると、エラーが発生する可能性があります。多くのエディタにおいて`rust-analyzer`拡張機能は、`rust-toolchain.toml`の内容にかかわらず、最新の(もしくは拡張機能に同梱されているバージョンの)`rust-analyzer`をデフォルトで使用するようになっているため、以下のようなエラーメッセージが表示されることがあります。
27 |
28 | ```
29 | [coc.nvim] Workspace `/home/hikalium/repo/wasabi/Cargo.toml` is using an outdated toolchain version `1.77.0-nightly` but rust-analyzer only supports `1.78.0` and higher.
30 | Consider using the rust-analyzer rustup component for your toolchain or upgrade your toolchain to a supported version.
31 | ```
32 |
33 | これを回避するためには、本書のリポジトリで使用されているツールチェインに適合したバージョンの`rust-analyzer`をLSPサーバーとして使用するよう、エディタに指示してあげる必要があります。
34 |
35 | まず、以下のコマンドをwasabiリポジトリの内部で実行して、`rust-analyzer`の実行ファイルパスを確認します。
36 |
37 | ```
38 | $ rustup component add rust-analyzer && rustup which rust-analyzer
39 | info: component 'rust-analyzer' for target 'x86_64-unknown-linux-gnu' is up to date
40 | /home/hikalium/.rustup/toolchains/nightly-2024-01-01-x86_64-unknown-linux-gnu/bin/rust-analyzer
41 | ```
42 |
43 | その後、このファイルパスをエディタの設定に追記します。
44 |
45 | - Neovimで`coc.nvim`経由で`coc-rust-analyzer`を利用している場合は、エディタを開いて`:CocConfig`もしくは`:CocLocalConfig`を実行して開かれたファイルを
46 | - VSCodeで[`rust-analyzer`拡張機能](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)を利用している場合は、wasabiレポジトリの配下で`.vscode/settings.json`を
47 |
48 | 開き、次のアイテムを追加します:
49 |
50 | ```
51 | {
52 | "rust-analyzer.server.path": "/home/hikalium/.rustup/toolchains/nightly-2024-01-01-x86_64-unknown-linux-gnu/bin/rust-analyzer"
53 | }
54 | ```
55 |
56 | 設定を保存したのちエディタを再起動すれば、wasabiに対しても`rust-analyzer`が問題なく動作するようになるはずです。
57 |
58 | See also:
59 |
60 | ## 本書を読む前に、Rust言語に関して理解しておいた方がいい内容はありますか?
61 |
62 | 本書はRust初心者の方でも、それ以外のプログラミング言語の経験がある方であれば問題なく読めることを目指して書かれているため、事前学習は必ずしも必要ではありません。どうしても事前に予習したい場合や、読んでいる途中で参考書が欲しくなってきたら、以下の資料を参考にするとよいでしょう。
63 |
64 | - [The Rust Programming Language 日本語版](https://doc.rust-jp.rs/book-ja/)
65 | - こちらはRust言語の公式チュートリアル([英語版](https://doc.rust-lang.org/stable/book/))を日本語に翻訳したものです。Rustの基礎を学ぶ際にちょうどよい、信頼できる情報源となっています。
66 | - [Comprehensive Rust 日本語版](https://google.github.io/comprehensive-rust/ja/)
67 | - こちらの資料は、Rustの利用を推進している会社のひとつであるGoogle社のソフトウェアエンジニアが、社内のRust講座で使用するために書き上げたドキュメントをオープンソース化したものです。こちらも[英語版](https://google.github.io/comprehensive-rust/)が原文となっています。講義形式の内容になっているため、時間を区切ってコツコツ進めたい場合に便利です。また、この資料を利用して講義を運営する人向けのアドバイスも書かれているため、複数人で学習する際にも役立つかもしれません。
68 |
69 | また、本書とあわせて、もしくは本書の次に読むと理解が深まると思われる資料はこちらです。
70 |
71 | - [並行プログラミング入門 ―Rust、C、アセンブリによる実装からのアプローチ](https://www.oreilly.co.jp//books/9784873119595/)
72 | - こちらの書籍は、人類には早すぎた「並行プログラミング」という複雑な問題を、様々な言語による実装を交えつつ解説してくれる良書です。
73 | - [Writing an OS in Rust 日本語版](https://os.phil-opp.com/ja/)
74 | - こちらの一連のブログ記事は、RustでOSを実装する際に必要となる知見が非常に多く掲載されており、筆者も大いにお世話になった情報源です。本書でも、いくつかの箇所でこのブログに言及しています。こちらも[原文](https://os.phil-opp.com/)は英語ですが、有志により翻訳されているため日本語で読むことができます。
75 | - こちらのブログ記事を題材にした輪読会に筆者は以前参加しており、その際の録画アーカイブが[YouTubeのプレイリスト](https://www.youtube.com/playlist?list=PL8U-_gKA4tWtNXVnqYRmn8En5Nh6xzADO)にまとめてありますので、睡眠用BGM等としてお役立てください。
76 |
77 | さらに発展的なOS自作に関わる情報を手に入れたい方は、筆者だけでなくたくさんの自作OS開発者が集うコミュニティ[osdev-jp](https://osdev.jp/)のSlackへの参加を検討してもよいでしょう。参加方法は[こちら](https://osdev.jp/joinus.html)に記載されています。また、定期的に「自作OSもくもく会」や「作業会」という[イベント](https://osdev-jp.connpass.com/)が開催されておりますので、そちらに参加して本を読み進めるというのもありかもしれません。これらのイベント等の動画アーカイブは[YouTubeのプレイリスト](https://www.youtube.com/@osdev-jp/playlists)にありますので、こちらもあわせて参考にしてみてください。
78 |
79 | ## rustfmtでuseの内容を自動でバラしてほしい
80 |
81 | 初版第1刷p.139で、useを行ごとにバラすようにしているよう説明しています。
82 | これを自動でやってくれる方法があると読者より教えていただいたので共有します。
83 | [(Thanks @lapla-cogito!)](https://github.com/lowlayergirls/wasabi-help/issues/7)
84 |
85 | `rustfmt.toml`で
86 | `imports_granularity = "Item"`と設定すれば、自動でバラしてくれるようです。
87 |
--------------------------------------------------------------------------------