経験は何よりも饒舌

10年後に真価を発揮するかもしれないブログ 

M1Macで「ゼロからのOS自作入門」(みかん本)を完走した

day1~day30のログはここに。
scrapbox.io

環境構築はこの記事を参考にしたらできたが、
zenn.dev

このコメント通りに修正する必要があった。
https://zenn.dev/link/comments/3860a03795708b


day4で発生した/usr/include/stdint.h:26:10: fatal error: 'bits/libc-header-start.h' file not foundを解決するために、stdint.hを使わないようにした。
https://scrapbox.io/wafuwafuoss/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%AEOS%E8%87%AA%E4%BD%9C%E5%85%A5%E9%96%80#635c8a98b96bbf0000ab84b8
osbook_day30fでこの差分を元に戻しても起動できた。原因はよくわかってない。

vscode ➜ /workspaces/mikanos-devcontainer/mikanos (tags/osbook_day30f ✗) $ git diff kernel/elf.hpp
diff --git a/kernel/elf.hpp b/kernel/elf.hpp
index 99ab80b..4f05cbc 100644
--- a/kernel/elf.hpp
+++ b/kernel/elf.hpp
@@ -1,14 +1,12 @@
 #pragma once
 
-#include <stdint.h>
-
-typedef uintptr_t Elf64_Addr;
-typedef uint64_t  Elf64_Off;
-typedef uint16_t  Elf64_Half;
-typedef uint32_t  Elf64_Word;
-typedef int32_t   Elf64_Sword;
-typedef uint64_t  Elf64_Xword;
-typedef int64_t   Elf64_Sxword;
+typedef unsigned long Elf64_Addr;
+typedef unsigned long  Elf64_Off;
+typedef unsigned char  Elf64_Half;
+typedef unsigned int  Elf64_Word;
+typedef int Elf64_Sword;
+typedef unsigned long  Elf64_Xword;
+typedef long Elf64_Sxword;
 
 #define EI_NIDENT 16
vscode ➜ /workspaces/mikanos-devcontainer/mikanos (tags/osbook_day30f ✗) $ git diff kernel/frame_buffer_config.hpp 
diff --git a/kernel/frame_buffer_config.hpp b/kernel/frame_buffer_config.hpp
index 0ce8035..c9bb380 100644
--- a/kernel/frame_buffer_config.hpp
+++ b/kernel/frame_buffer_config.hpp
@@ -1,16 +1,14 @@
 #pragma once
 
-#include <stdint.h>
-
 enum PixelFormat {
   kPixelRGBResv8BitPerColor,
   kPixelBGRResv8BitPerColor,
 };
 
 struct FrameBufferConfig {
-  uint8_t* frame_buffer;
-  uint32_t pixels_per_scan_line;
-  uint32_t horizontal_resolution;
-  uint32_t vertical_resolution;
+  unsigned char* frame_buffer;
+  unsigned int pixels_per_scan_line;
+  unsigned int horizontal_resolution;
+  unsigned int vertical_resolution;
   enum PixelFormat pixel_format;
 };
vscode ➜ /workspaces/mikanos-devcontainer/mikanos (tags/osbook_day30f ✗) $ git diff kernel/memory_map.hpp 
diff --git a/kernel/memory_map.hpp b/kernel/memory_map.hpp
index ef61348..e3b68d6 100644
--- a/kernel/memory_map.hpp
+++ b/kernel/memory_map.hpp
@@ -1,22 +1,20 @@
 #pragma once
 
-#include <stdint.h>
-
 struct MemoryMap {
   unsigned long long buffer_size;
   void* buffer;
   unsigned long long map_size;
   unsigned long long map_key;
   unsigned long long descriptor_size;
-  uint32_t descriptor_version;
+  unsigned int descriptor_version;
 };
 
 struct MemoryDescriptor {
-  uint32_t type;
-  uintptr_t physical_start;
-  uintptr_t virtual_start;
-  uint64_t number_of_pages;
-  uint64_t attribute;
+  unsigned int type;
+  unsigned long physical_start;
+  unsigned long virtual_start;
+  unsigned long number_of_pages;
+  unsigned long attribute;
 };
 
 #ifdef __cplusplus
@@ -39,11 +37,11 @@ enum class MemoryType {
   kEfiMaxMemoryType
 };
 
-inline bool operator==(uint32_t lhs, MemoryType rhs) {
-  return lhs == static_cast<uint32_t>(rhs);
+inline bool operator==(unsigned int lhs, MemoryType rhs) {
+  return lhs == static_cast<unsigned int>(rhs);
 }
 
-inline bool operator==(MemoryType lhs, uint32_t rhs) {
+inline bool operator==(MemoryType lhs, unsigned int rhs) {
   return rhs == lhs;
 }

osbook_day15dの「描画の高速化」をすると、Failed to allocate pages: NotFoundが出てしまったので、DrawAreaを使わないようにした。
https://scrapbox.io/wafuwafuoss/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E3%81%AEOS%E8%87%AA%E4%BD%9C%E5%85%A5%E9%96%80#63801fb5b96bbf0000092981
osbook_day30fでこの差分を元に戻しても起動できた。原因はよくわかってない。

vscode ➜ /workspaces/mikanos-devcontainer/mikanos (tags/osbook_day30f ✗) $ git diff kernel/message.hpp 
diff --git a/kernel/message.hpp b/kernel/message.hpp
index 8798623..148e82e 100644
--- a/kernel/message.hpp
+++ b/kernel/message.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
 enum class LayerOperation {
-  Move, MoveRelative, Draw, DrawArea
+  Move, MoveRelative, Draw
 };
 
 struct Message {
@@ -37,7 +37,6 @@ struct Message {
       LayerOperation op;
       unsigned int layer_id;
       int x, y;
-      int w, h;
     } layer;
 
     struct {
vscode ➜ /workspaces/mikanos-devcontainer/mikanos (tags/osbook_day30f ✗) $ git diff kernel/layer.hpp 
diff --git a/kernel/layer.hpp b/kernel/layer.hpp
index 5f616da..427ff29 100644
--- a/kernel/layer.hpp
+++ b/kernel/layer.hpp
@@ -69,8 +69,6 @@ class LayerManager {
   void Draw(const Rectangle<int>& area) const;
   /** @brief 指定したレイヤーに設定されているウィンドウの描画領域内を再描画する。 */
   void Draw(unsigned int id) const;
-  /** @brief 指定したレイヤーに設定されているウィンドウ内の指定された範囲を再描画する。 */
-  void Draw(unsigned int id, Rectangle<int> area) const;
 
   /** @brief レイヤーの位置情報を指定された絶対座標へと更新する。再描画する。 */
   void Move(unsigned int id, Vector2D<int> new_pos);
@@ -123,17 +121,5 @@ extern std::map<unsigned int, uint64_t>* layer_task_map;
 void InitializeLayer();
 void ProcessLayerMessage(const Message& msg);
 
-constexpr Message MakeLayerMessage(
-    uint64_t task_id, unsigned int layer_id,
-    LayerOperation op, const Rectangle<int>& area) {
-  Message msg{Message::kLayer, task_id};
-  msg.arg.layer.layer_id = layer_id;
-  msg.arg.layer.op = op;
-  msg.arg.layer.x = area.pos.x;
-  msg.arg.layer.y = area.pos.y;
-  msg.arg.layer.w = area.size.x;
-  msg.arg.layer.h = area.size.y;
-  return msg;
-}
 
 Error CloseLayer(unsigned int layer_id);
vscode ➜ /workspaces/mikanos-devcontainer/mikanos (tags/osbook_day30f ✗) $ git diff kernel/layer.cpp
diff --git a/kernel/layer.cpp b/kernel/layer.cpp
index 1188b71..f4d3978 100644
--- a/kernel/layer.cpp
+++ b/kernel/layer.cpp
@@ -89,20 +89,12 @@ void LayerManager::Draw(const Rectangle<int>& area) const {
 }
 
 void LayerManager::Draw(unsigned int id) const {
-  Draw(id, {{0, 0}, {-1, -1}});
-}
-
-void LayerManager::Draw(unsigned int id, Rectangle<int> area) const {
   bool draw = false;
   Rectangle<int> window_area;
   for (auto layer : layer_stack_) {
     if (layer->ID() == id) {
       window_area.size = layer->GetWindow()->Size();
       window_area.pos = layer->GetPosition();
-      if (area.size.x >= 0 || area.size.y >= 0) {
-        area.pos = area.pos + window_area.pos;
-        window_area = window_area & area;
-      }
       draw = true;
     }
     if (draw) {
@@ -304,9 +296,6 @@ void ProcessLayerMessage(const Message& msg) {
   case LayerOperation::Draw:
     layer_manager->Draw(arg.layer_id);
     break;
-  case LayerOperation::DrawArea:
-    layer_manager->Draw(arg.layer_id, {{arg.x, arg.y}, {arg.w, arg.h}});
-    break;
   }
 }
vscode ➜ /workspaces/mikanos-devcontainer/mikanos (tags/osbook_day30f ✗) $ git diff kernel/terminal.cpp 
diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp
index 8762f72..1f4665d 100644
diff --git a/kernel/terminal.cpp b/kernel/terminal.cpp
index 8762f72..1f4665d 100644
--- a/kernel/terminal.cpp
+++ b/kernel/terminal.cpp
@@ -639,27 +639,18 @@ void Terminal::Print(const char* s, std::optional<size_t> len) {
   }
 
   DrawCursor(true);
-  const auto cursor_after = CalcCursorPos();
-
-  Vector2D<int> draw_pos{ToplevelWindow::kTopLeftMargin.x, cursor_before.y};
-  Vector2D<int> draw_size{window_->InnerSize().x,
-                          cursor_after.y - cursor_before.y + 16};
-
-  Rectangle<int> draw_area{draw_pos, draw_size};
-
-  Message msg = MakeLayerMessage(
-      task_.ID(), LayerID(), LayerOperation::DrawArea, draw_area);
+  Message msg{Message::kLayer, task_.ID()};
+  msg.arg.layer.layer_id = LayerID();
+  msg.arg.layer.op = LayerOperation::Draw;
   __asm__("cli");
   task_manager->SendMessage(1, msg);
   __asm__("sti");
 }
 
 void Terminal::Redraw() {
-  Rectangle<int> draw_area{ToplevelWindow::kTopLeftMargin,
-                           window_->InnerSize()};
-
-  Message msg = MakeLayerMessage(
-      task_.ID(), LayerID(), LayerOperation::DrawArea, draw_area);
+  Message msg{Message::kLayer, task_.ID()};
+  msg.arg.layer.layer_id = LayerID();
+  msg.arg.layer.op = LayerOperation::Draw;
   __asm__("cli");
   task_manager->SendMessage(1, msg);
   __asm__("sti");
@@ -743,9 +734,10 @@ void TaskTerminal(uint64_t task_id, int64_t data) {
     case Message::kTimerTimeout:
       add_blink_timer(msg->arg.timer.timeout);
       if (show_window && window_isactive) {
-        const auto area = terminal->BlinkCursor();
-        Message msg = MakeLayerMessage(
-            task_id, terminal->LayerID(), LayerOperation::DrawArea, area);
+        terminal->BlinkCursor();
+        Message msg{Message::kLayer, task_id};
+        msg.arg.layer.layer_id = terminal->LayerID();
+        msg.arg.layer.op = LayerOperation::Draw;
         __asm__("cli");
         task_manager->SendMessage(1, msg);
         __asm__("sti");
@@ -757,8 +749,9 @@ void TaskTerminal(uint64_t task_id, int64_t data) {
                                              msg->arg.keyboard.keycode,
                                              msg->arg.keyboard.ascii);
         if (show_window) {
-          Message msg = MakeLayerMessage(
-              task_id, terminal->LayerID(), LayerOperation::DrawArea, area);
+          Message msg{Message::kLayer, task_id};
+          msg.arg.layer.layer_id = terminal->LayerID();
+          msg.arg.layer.op = LayerOperation::Draw;
           __asm__("cli");
           task_manager->SendMessage(1, msg);
           __asm__("sti");

osbook_day24aの「ターミナルを増やす」でF2キーが分からなかったのでZにした。

vscode ➜ /workspaces/mikanos-devcontainer/mikanos (tags/osbook_day30f ✗) $ git diff kernel/main.cpp 
diff --git a/kernel/main.cpp b/kernel/main.cpp
index 40e67ed..e483fcf 100644
--- a/kernel/main.cpp
+++ b/kernel/main.cpp
@@ -211,7 +211,7 @@ extern "C" void KernelMainNewStack(
           InputTextWindow(msg->arg.keyboard.ascii);
         }
       } else if (msg->arg.keyboard.press &&
-                 msg->arg.keyboard.keycode == 59 /* F2 */) {
+                 msg->arg.keyboard.keycode == 29 /* Z */) {
         task_manager->NewTask()
           .InitContext(TaskTerminal, 0)
           .Wakeup();


自分の場合、順番に進めるにあたって変更する箇所ができたが、osbook_day30fでは差分なしで起動できた。素晴らしいコンテナのおかげでMacでも問題なく開発できる。
意味がわからず進めていた箇所が多いのでこれから改造して理解を進めていきたい。