{"componentChunkName":"component---src-templates-post-template-js","path":"/diyos-mikanos-01-en","result":{"data":{"markdownRemark":{"id":"b7a23c63-d5f0-509c-b949-a0e4ed1a1a1e","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/diyos-mikanos-01\">original page</a>.</p>\n</blockquote>\n<p>I want to retry <a href=\"https://amzn.to/36JN8a5\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Introduction to OS Development from Scratch</a>, which I bought as soon as it was released but left untouched because I couldn’t find the time and got discouraged by the difficulty.</p>\n<p>Basically, I plan to proceed mainly by typing in the code, and then write up articles about the points where I get stuck or where my understanding is still shallow.</p>\n<p>This time, I’ll cover environment setup through Chapter 2.\nBy the way, I’m skipping Chapter 1 because it’s mostly just doing the exercises.</p>\n<!-- omit in toc -->\n<h2 id=\"table-of-contents\" style=\"position:relative;\"><a href=\"#table-of-contents\" aria-label=\"table of contents permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Table of Contents</h2>\n<ul>\n<li><a href=\"#environment-setup\">Environment setup</a></li>\n<li><a href=\"#creating-a-uefi-application-with-edk-ii\">Creating a UEFI application with EDK II</a></li>\n<li><a href=\"#about-building-the-image\">About building the image</a></li>\n<li><a href=\"#summary\">Summary</a></li>\n</ul>\n<h2 id=\"environment-setup\" style=\"position:relative;\"><a href=\"#environment-setup\" aria-label=\"environment setup permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Environment setup</h2>\n<p>I built the development environment with the following setup.</p>\n<ul>\n<li>Ubuntu 20.04 (built with a GUI on Hyper-V)</li>\n<li>Windows 10 (host machine)</li>\n<li>VSCode (host machine)</li>\n</ul>\n<p>The plan is to do development by connecting from VSCode to the Ubuntu instance running on Hyper-V via Remote SSH, and only log in to Ubuntu with the GUI when I need to check behavior in Qemu.</p>\n<p>Some of the QEMU commands explained in the book require 3D acceleration to be enabled.\nIf <code class=\"language-text\">(qemu) gtk initialization failed</code> occurs in a virtual desktop environment, check whether 3D acceleration is enabled.</p>\n<p>For the environment setup, I’m using the following GitHub repository published by the author as the base.</p>\n<p>Reference: <a href=\"https://github.com/uchan-nos/mikanos-build\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Build and run scripts for MikanOS</a></p>\n<p>If your Ubuntu version is different, the steps may not work exactly as written and the amount of trouble increases, so if possible I think it’s best to prepare Ubuntu 20.04 in a virtual machine or WSL.</p>\n<p>I’ve summarized how to connect from VSCode to Ubuntu on a virtual machine via Remote SSH here.</p>\n<p>Reference: <a href=\"https://yukituna.com/3286/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">How to edit files directly on a virtual machine running on Hyper-V from VSCode - Yukituna’s Bookshelf</a></p>\n<h2 id=\"creating-a-uefi-application-with-edk-ii\" style=\"position:relative;\"><a href=\"#creating-a-uefi-application-with-edk-ii\" aria-label=\"creating a uefi application with edk ii permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Creating a UEFI application with EDK II</h2>\n<p>Right from the beginning, it jumped into a technical area I knew absolutely nothing about.</p>\n<p>Reference: <a href=\"https://github.com/tianocore/edk2\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GitHub - tianocore/edk2: EDK II</a></p>\n<p>The <code class=\"language-text\">.EFI</code> file created here seems to be a UEFI application that is called from UEFI BIOS.\nMy understanding is that EDK II is something like an SDK for creating UEFI applications.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">MemoryMap</span> <span class=\"token punctuation\">{</span>\n  UINTN buffer_size<span class=\"token punctuation\">;</span>\n  VOID<span class=\"token operator\">*</span> buffer<span class=\"token punctuation\">;</span>\n  UINTN map_size<span class=\"token punctuation\">;</span>\n  UINTN map_key<span class=\"token punctuation\">;</span>\n  UINTN descriptor_size<span class=\"token punctuation\">;</span>\n  UINT32 descriptor_version<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\nEFI_STATUS <span class=\"token function\">GetMemoryMap</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">struct</span> <span class=\"token class-name\">MemoryMap</span><span class=\"token operator\">*</span> map<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>map<span class=\"token operator\">-></span>buffer <span class=\"token operator\">==</span> <span class=\"token constant\">NULL</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> EFI_BUFFER_TOO_SMALL<span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  map<span class=\"token operator\">-></span>map_size <span class=\"token operator\">=</span> map<span class=\"token operator\">-></span>buffer_size<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> gBS<span class=\"token operator\">-></span><span class=\"token function\">GetMemoryMap</span><span class=\"token punctuation\">(</span>\n      <span class=\"token operator\">&amp;</span>map<span class=\"token operator\">-></span>map_size<span class=\"token punctuation\">,</span>\n      <span class=\"token punctuation\">(</span>EFI_MEMORY_DESCRIPTOR<span class=\"token operator\">*</span><span class=\"token punctuation\">)</span>map<span class=\"token operator\">-></span>buffer<span class=\"token punctuation\">,</span>\n      <span class=\"token operator\">&amp;</span>map<span class=\"token operator\">-></span>map_key<span class=\"token punctuation\">,</span>\n      <span class=\"token operator\">&amp;</span>map<span class=\"token operator\">-></span>descriptor_size<span class=\"token punctuation\">,</span>\n      <span class=\"token operator\">&amp;</span>map<span class=\"token operator\">-></span>descriptor_version<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>I didn’t really understand what it was doing, so for the time being I followed the code.\nHere, <code class=\"language-text\">GetMemoryMap()</code> stores the memory map in a <code class=\"language-text\">MemoryMap</code> structure named <code class=\"language-text\">memmap</code>.</p>\n<p><code class=\"language-text\">GetMemoryMap()</code> uses <code class=\"language-text\">gBS->GetMemoryMap()</code> to obtain the memory map at the time the function is called.</p>\n<p>The second argument, given as <code class=\"language-text\">(EFI_MEMORY_DESCRIPTOR*)map->buffer</code>, is where the function stores the memory map it retrieves.\nThe stored data is defined as the <code class=\"language-text\">EFI_MEMORY_DESCRIPTOR</code> structure in <code class=\"language-text\">edk2/MdePkg/Include/Uefi/UefiSpec.h</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token comment\">///</span>\n<span class=\"token comment\">/// Memory descriptor version number.</span>\n<span class=\"token comment\">///</span>\n<span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">define</span> <span class=\"token macro-name\">EFI_MEMORY_DESCRIPTOR_VERSION</span> <span class=\"token expression\"><span class=\"token number\">1</span></span></span>\n\n<span class=\"token comment\">///</span>\n<span class=\"token comment\">/// Definition of an EFI memory descriptor.</span>\n<span class=\"token comment\">///</span>\n<span class=\"token keyword\">typedef</span> <span class=\"token keyword\">struct</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">///</span>\n  <span class=\"token comment\">/// Type of the memory region.</span>\n  <span class=\"token comment\">/// Type EFI_MEMORY_TYPE is defined in the</span>\n  <span class=\"token comment\">/// AllocatePages() function description.</span>\n  <span class=\"token comment\">///</span>\n  UINT32                Type<span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">///</span>\n  <span class=\"token comment\">/// Physical address of the first byte in the memory region. PhysicalStart must be</span>\n  <span class=\"token comment\">/// aligned on a 4 KiB boundary, and must not be above 0xfffffffffffff000. Type</span>\n  <span class=\"token comment\">/// EFI_PHYSICAL_ADDRESS is defined in the AllocatePages() function description</span>\n  <span class=\"token comment\">///</span>\n  EFI_PHYSICAL_ADDRESS  PhysicalStart<span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">///</span>\n  <span class=\"token comment\">/// Virtual address of the first byte in the memory region.</span>\n  <span class=\"token comment\">/// VirtualStart must be aligned on a 4 KiB boundary,</span>\n  <span class=\"token comment\">/// and must not be above 0xfffffffffffff000.</span>\n  <span class=\"token comment\">///</span>\n  EFI_VIRTUAL_ADDRESS   VirtualStart<span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">///</span>\n  <span class=\"token comment\">/// NumberOfPagesNumber of 4 KiB pages in the memory region.</span>\n  <span class=\"token comment\">/// NumberOfPages must not be 0, and must not be any value</span>\n  <span class=\"token comment\">/// that would represent a memory page with a start address,</span>\n  <span class=\"token comment\">/// either physical or virtual, above 0xfffffffffffff000.</span>\n  <span class=\"token comment\">///</span>\n  UINT64                NumberOfPages<span class=\"token punctuation\">;</span>\n  <span class=\"token comment\">///</span>\n  <span class=\"token comment\">/// Attributes of the memory region that describe the bit mask of capabilities</span>\n  <span class=\"token comment\">/// for that memory region, and not necessarily the current settings for that</span>\n  <span class=\"token comment\">/// memory region.</span>\n  <span class=\"token comment\">///</span>\n  UINT64                Attribute<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span> EFI_MEMORY_DESCRIPTOR<span class=\"token punctuation\">;</span></code></pre></div>\n<p>In the end, the memory map obtained here was saved by <code class=\"language-text\">SaveMemoryMap()</code> as a CSV file named <code class=\"language-text\">memmmap</code>.\nRun the following commands directly under <code class=\"language-text\">edk2/Build/OSLoaderX64/DEBUG_CLANG38/X64/OSLoaderPkg/Loader/DEBUG</code>, where the built image file is created, to inspect the contents of the image file.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">mkdir</span> -o mnt\n<span class=\"token function\">sudo</span> <span class=\"token function\">mount</span> -o loop disk.img mnt\n<span class=\"token function\">cat</span> mnt/memmap\n\n<span class=\"token comment\">#//</span>\n\nunmount mnt</code></pre></div>\n<p>For now, if I can at least confirm the contents of this memory map, that means I’ve finished the material up through Chapter 2.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">Index, Type, Type<span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span>, PhysicalStart, NumberOfPages, Attribute\n<span class=\"token number\">0</span>, <span class=\"token number\">3</span>, EfiBootServicesCode, 00000000, <span class=\"token number\">1</span>, F\n<span class=\"token number\">1</span>, <span class=\"token number\">7</span>, EfiConventionalMemory, 00001000, 9F, F\n<span class=\"token number\">2</span>, <span class=\"token number\">7</span>, EfiConventionalMemory, 00100000, <span class=\"token number\">700</span>, F\n<span class=\"token number\">3</span>, A, EfiACPIMemoryNVS, 00800000, <span class=\"token number\">8</span>, F\n<span class=\"token number\">4</span>, <span class=\"token number\">7</span>, EfiConventionalMemory, 00808000, <span class=\"token number\">8</span>, F\n<span class=\"token number\">5</span>, A, EfiACPIMemoryNVS, 00810000, F0, F\n<span class=\"token number\">6</span>, <span class=\"token number\">4</span>, EfiBootServicesData, 00900000, B00, F\n<span class=\"token number\">7</span>, <span class=\"token number\">7</span>, EfiConventionalMemory, 01400000, 3AB36, F\n<span class=\"token number\">8</span>, <span class=\"token number\">4</span>, EfiBootServicesData, 3BF36000, <span class=\"token number\">20</span>, F\n<span class=\"token number\">9</span>, <span class=\"token number\">7</span>, EfiConventionalMemory, 3BF56000, 270C, F\n<span class=\"token number\">10</span>, <span class=\"token number\">1</span>, EfiLoaderCode, 3E662000, <span class=\"token number\">2</span>, F\n<span class=\"token number\">11</span>, <span class=\"token number\">4</span>, EfiBootServicesData, 3E664000, <span class=\"token number\">219</span>, F\n<span class=\"token number\">12</span>, <span class=\"token number\">3</span>, EfiBootServicesCode, 3E87D000, B7, F\n<span class=\"token number\">13</span>, A, EfiACPIMemoryNVS, 3E934000, <span class=\"token number\">12</span>, F\n<span class=\"token number\">14</span>, <span class=\"token number\">0</span>, EfiReservedMemoryType, 3E946000, 1C, F\n<span class=\"token number\">15</span>, <span class=\"token number\">3</span>, EfiBootServicesCode, 3E962000, 10A, F\n<span class=\"token number\">16</span>, <span class=\"token number\">6</span>, EfiRuntimeServicesData, 3EA6C000, <span class=\"token number\">5</span>, F\n<span class=\"token number\">17</span>, <span class=\"token number\">5</span>, EfiRuntimeServicesCode, 3EA71000, <span class=\"token number\">5</span>, F\n<span class=\"token number\">18</span>, <span class=\"token number\">6</span>, EfiRuntimeServicesData, 3EA76000, <span class=\"token number\">5</span>, F\n<span class=\"token number\">19</span>, <span class=\"token number\">5</span>, EfiRuntimeServicesCode, 3EA7B000, <span class=\"token number\">5</span>, F\n<span class=\"token number\">20</span>, <span class=\"token number\">6</span>, EfiRuntimeServicesData, 3EA80000, <span class=\"token number\">5</span>, F\n<span class=\"token number\">21</span>, <span class=\"token number\">5</span>, EfiRuntimeServicesCode, 3EA85000, <span class=\"token number\">7</span>, F\n<span class=\"token number\">22</span>, <span class=\"token number\">6</span>, EfiRuntimeServicesData, 3EA8C000, 8F, F\n<span class=\"token number\">23</span>, <span class=\"token number\">4</span>, EfiBootServicesData, 3EB1B000, 4DA, F\n<span class=\"token number\">24</span>, <span class=\"token number\">7</span>, EfiConventionalMemory, 3EFF5000, <span class=\"token number\">4</span>, F\n<span class=\"token number\">25</span>, <span class=\"token number\">4</span>, EfiBootServicesData, 3EFF9000, <span class=\"token number\">6</span>, F\n<span class=\"token number\">26</span>, <span class=\"token number\">7</span>, EfiConventionalMemory, 3EFFF000, <span class=\"token number\">1</span>, F\n<span class=\"token number\">27</span>, <span class=\"token number\">4</span>, EfiBootServicesData, 3F000000, A1B, F\n<span class=\"token number\">28</span>, <span class=\"token number\">7</span>, EfiConventionalMemory, 3FA1B000, <span class=\"token number\">1</span>, F\n<span class=\"token number\">29</span>, <span class=\"token number\">3</span>, EfiBootServicesCode, 3FA1C000, 17F, F\n<span class=\"token number\">30</span>, <span class=\"token number\">5</span>, EfiRuntimeServicesCode, 3FB9B000, <span class=\"token number\">30</span>, F\n<span class=\"token number\">31</span>, <span class=\"token number\">6</span>, EfiRuntimeServicesData, 3FBCB000, <span class=\"token number\">24</span>, F\n<span class=\"token number\">32</span>, <span class=\"token number\">0</span>, EfiReservedMemoryType, 3FBEF000, <span class=\"token number\">4</span>, F\n<span class=\"token number\">33</span>, <span class=\"token number\">9</span>, EfiACPIReclaimMemory, 3FBF3000, <span class=\"token number\">8</span>, F\n<span class=\"token number\">34</span>, A, EfiACPIMemoryNVS, 3FBFB000, <span class=\"token number\">4</span>, F\n<span class=\"token number\">35</span>, <span class=\"token number\">4</span>, EfiBootServicesData, 3FBFF000, <span class=\"token number\">201</span>, F\n<span class=\"token number\">36</span>, <span class=\"token number\">7</span>, EfiConventionalMemory, 3FE00000, 8D, F\n<span class=\"token number\">37</span>, <span class=\"token number\">4</span>, EfiBootServicesData, 3FE8D000, <span class=\"token number\">20</span>, F\n<span class=\"token number\">38</span>, <span class=\"token number\">3</span>, EfiBootServicesCode, 3FEAD000, <span class=\"token number\">20</span>, F\n<span class=\"token number\">39</span>, <span class=\"token number\">4</span>, EfiBootServicesData, 3FECD000, <span class=\"token number\">9</span>, F\n<span class=\"token number\">40</span>, <span class=\"token number\">3</span>, EfiBootServicesCode, 3FED6000, 1E, F\n<span class=\"token number\">41</span>, <span class=\"token number\">6</span>, EfiRuntimeServicesData, 3FEF4000, <span class=\"token number\">84</span>, F\n<span class=\"token number\">42</span>, A, EfiACPIMemoryNVS, 3FF78000, <span class=\"token number\">88</span>, F\n<span class=\"token number\">43</span>, <span class=\"token number\">6</span>, EfiRuntimeServicesData, FFC00000, <span class=\"token number\">400</span>, <span class=\"token number\">1</span></code></pre></div>\n<h2 id=\"about-building-the-image\" style=\"position:relative;\"><a href=\"#about-building-the-image\" aria-label=\"about building the image permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About building the image</h2>\n<p>I didn’t really understand the part where the created EFI file is built and then emulated in Qemu, because there was not much explanation in the book, so I wrote up my understanding here.</p>\n<p>In the book, the EFI file is built by using the <code class=\"language-text\">build</code> command directly under the <code class=\"language-text\">edk2</code> directory.</p>\n<p>The build target information is written in <code class=\"language-text\">edk2/Conf/target.txt</code>.</p>\n<p>This time, I used a folder called <code class=\"language-text\">OSLoaderPkg</code> as the workspace for the UEFI application I created myself.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\">#  PROPERTY              Type       Use         Description</span>\n<span class=\"token comment\">#  ----------------      --------   --------    -----------------------------------------------------------</span>\n<span class=\"token comment\">#  ACTIVE_PLATFORM       Filename   Recommended Specify the WORKSPACE relative Path and Filename</span>\n<span class=\"token comment\">#                                               of the platform description file that will be used for the</span>\n<span class=\"token comment\">#                                               build. This line is required if and only if the current</span>\n<span class=\"token comment\">#                                               working directory does not contain one or more description</span>\n<span class=\"token comment\">#                                               files.</span>\nACTIVE_PLATFORM       <span class=\"token operator\">=</span> OSLoaderPkg/OSLoaderPkg.dsc</code></pre></div>\n<p>Here, <code class=\"language-text\">OSLoaderPkg.dsc</code> is defined as follows.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token comment\">#@range_begin(defines)</span>\n<span class=\"token punctuation\">[</span>Defines<span class=\"token punctuation\">]</span>\n  PLATFORM_NAME                  <span class=\"token operator\">=</span> OSLoaderPkg\n  PLATFORM_GUID                  <span class=\"token operator\">=</span> d3f11f4e-71e9-11e8-a7e1-33fd4f7d5a3e\n  PLATFORM_VERSION               <span class=\"token operator\">=</span> <span class=\"token number\">0.1</span>\n  DSC_SPECIFICATION              <span class=\"token operator\">=</span> 0x00010005\n  OUTPUT_DIRECTORY               <span class=\"token operator\">=</span> Build/OSLoader<span class=\"token variable\"><span class=\"token variable\">$(</span>ARCH<span class=\"token variable\">)</span></span>\n  SUPPORTED_ARCHITECTURES        <span class=\"token operator\">=</span> X64\n  BUILD_TARGETS                  <span class=\"token operator\">=</span> DEBUG<span class=\"token operator\">|</span>RELEASE<span class=\"token operator\">|</span>NOOPT\n<span class=\"token comment\">#@range_end(defines)</span>\n\n<span class=\"token comment\">#@range_begin(library_classes)</span>\n<span class=\"token punctuation\">[</span>LibraryClasses<span class=\"token punctuation\">]</span>\n  UefiApplicationEntryPoint<span class=\"token operator\">|</span>MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf\n  UefiLib<span class=\"token operator\">|</span>MdePkg/Library/UefiLib/UefiLib.inf\n<span class=\"token comment\">#@range_end(library_classes)</span>\n\n  BaseLib<span class=\"token operator\">|</span>MdePkg/Library/BaseLib/BaseLib.inf\n  BaseMemoryLib<span class=\"token operator\">|</span>MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf\n  DebugLib<span class=\"token operator\">|</span>MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf\n  DevicePathLib<span class=\"token operator\">|</span>MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf\n  MemoryAllocationLib<span class=\"token operator\">|</span>MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\n  PcdLib<span class=\"token operator\">|</span>MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\n  PrintLib<span class=\"token operator\">|</span>MdePkg/Library/BasePrintLib/BasePrintLib.inf\n  UefiBootServicesTableLib<span class=\"token operator\">|</span>MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf\n  UefiRuntimeServicesTableLib<span class=\"token operator\">|</span>MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf\n\n<span class=\"token comment\">#@range_begin(components)</span>\n<span class=\"token punctuation\">[</span>Components<span class=\"token punctuation\">]</span>\n  OSLoaderPkg/Loader.inf\n<span class=\"token comment\">#@range_end(components)</span></code></pre></div>\n<p>With this setting, the EFI file built by EDK II is placed in <code class=\"language-text\">OUTPUT_DIRECTORY = Build/OSLoader$(ARCH)</code>, so it ends up being saved under <code class=\"language-text\">edk2/Build/OSLoaderX64/DEBUG_CLANG38/X64/OSLoaderPkg/Loader/DEBUG/</code>.</p>\n<p>Next, by running <code class=\"language-text\">osbook/devtools/run_qemu.sh</code> in the same directory as <code class=\"language-text\">Loader.efi</code>—<code class=\"language-text\">edk2/Build/OSLoaderX64/DEBUG_CLANG38/X64/OSLoaderPkg/Loader/DEBUG/</code>—the built EFI file is emulated in Qemu.</p>\n<p>The contents of <code class=\"language-text\">osbook/devtools/run_qemu.sh</code> looked like this. It calls <code class=\"language-text\">make_image.sh</code> using the execution directory information passed in as arguments.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token shebang important\">#!/bin/sh -ex</span>\n\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">[</span> <span class=\"token variable\">$#</span> -lt <span class=\"token number\">1</span> <span class=\"token punctuation\">]</span>\n<span class=\"token keyword\">then</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"Usage: <span class=\"token variable\">$0</span> &lt;.efi file> [another file]\"</span>\n    <span class=\"token builtin class-name\">exit</span> <span class=\"token number\">1</span>\n<span class=\"token keyword\">fi</span>\n\n<span class=\"token assign-left variable\">DEVENV_DIR</span><span class=\"token operator\">=</span><span class=\"token variable\"><span class=\"token variable\">$(</span><span class=\"token function\">dirname</span> <span class=\"token string\">\"<span class=\"token variable\">$0</span>\"</span><span class=\"token variable\">)</span></span>\n<span class=\"token assign-left variable\">EFI_FILE</span><span class=\"token operator\">=</span><span class=\"token variable\">$1</span>\n<span class=\"token assign-left variable\">ANOTHER_FILE</span><span class=\"token operator\">=</span><span class=\"token variable\">$2</span>\n<span class=\"token assign-left variable\">DISK_IMG</span><span class=\"token operator\">=</span>./disk.img\n<span class=\"token assign-left variable\">MOUNT_POINT</span><span class=\"token operator\">=</span>./mnt\n\n<span class=\"token variable\">$DEVENV_DIR</span>/make_image.sh <span class=\"token variable\">$DISK_IMG</span> <span class=\"token variable\">$MOUNT_POINT</span> <span class=\"token variable\">$EFI_FILE</span> <span class=\"token variable\">$ANOTHER_FILE</span>\n<span class=\"token variable\">$DEVENV_DIR</span>/run_image.sh <span class=\"token variable\">$DISK_IMG</span></code></pre></div>\n<p>Let’s look at the contents of <code class=\"language-text\">make_image.sh</code>.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token shebang important\">#!/bin/sh -ex</span>\n\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">[</span> <span class=\"token variable\">$#</span> -lt <span class=\"token number\">3</span> <span class=\"token punctuation\">]</span>\n<span class=\"token keyword\">then</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"Usage: <span class=\"token variable\">$0</span> &lt;image name> &lt;mount point> &lt;.efi file> [another file]\"</span>\n    <span class=\"token builtin class-name\">exit</span> <span class=\"token number\">1</span>\n<span class=\"token keyword\">fi</span>\n\n<span class=\"token assign-left variable\">DEVENV_DIR</span><span class=\"token operator\">=</span><span class=\"token variable\"><span class=\"token variable\">$(</span><span class=\"token function\">dirname</span> <span class=\"token string\">\"<span class=\"token variable\">$0</span>\"</span><span class=\"token variable\">)</span></span>\n<span class=\"token assign-left variable\">DISK_IMG</span><span class=\"token operator\">=</span><span class=\"token variable\">$1</span>\n<span class=\"token assign-left variable\">MOUNT_POINT</span><span class=\"token operator\">=</span><span class=\"token variable\">$2</span>\n<span class=\"token assign-left variable\">EFI_FILE</span><span class=\"token operator\">=</span><span class=\"token variable\">$3</span>\n<span class=\"token assign-left variable\">ANOTHER_FILE</span><span class=\"token operator\">=</span><span class=\"token variable\">$4</span>\n\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">[</span> <span class=\"token operator\">!</span> -f <span class=\"token variable\">$EFI_FILE</span> <span class=\"token punctuation\">]</span>\n<span class=\"token keyword\">then</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"No such file: <span class=\"token variable\">$EFI_FILE</span>\"</span>\n    <span class=\"token builtin class-name\">exit</span> <span class=\"token number\">1</span>\n<span class=\"token keyword\">fi</span>\n\n<span class=\"token function\">rm</span> -f <span class=\"token variable\">$DISK_IMG</span>\nqemu-img create -f raw <span class=\"token variable\">$DISK_IMG</span> 200M\nmkfs.fat -n <span class=\"token string\">'JISAKU OS'</span> -s <span class=\"token number\">2</span> -f <span class=\"token number\">2</span> -R <span class=\"token number\">32</span> -F <span class=\"token number\">32</span> <span class=\"token variable\">$DISK_IMG</span>\n\n<span class=\"token variable\">$DEVENV_DIR</span>/mount_image.sh <span class=\"token variable\">$DISK_IMG</span> <span class=\"token variable\">$MOUNT_POINT</span>\n<span class=\"token function\">sudo</span> <span class=\"token function\">mkdir</span> -p <span class=\"token variable\">$MOUNT_POINT</span>/EFI/BOOT\n<span class=\"token function\">sudo</span> <span class=\"token function\">cp</span> <span class=\"token variable\">$EFI_FILE</span> <span class=\"token variable\">$MOUNT_POINT</span>/EFI/BOOT/BOOTX64.EFI\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">[</span> <span class=\"token string\">\"<span class=\"token variable\">$ANOTHER_FILE</span>\"</span> <span class=\"token operator\">!=</span> <span class=\"token string\">\"\"</span> <span class=\"token punctuation\">]</span>\n<span class=\"token keyword\">then</span>\n    <span class=\"token function\">sudo</span> <span class=\"token function\">cp</span> <span class=\"token variable\">$ANOTHER_FILE</span> <span class=\"token variable\">$MOUNT_POINT</span>/\n<span class=\"token keyword\">fi</span>\n<span class=\"token function\">sleep</span> <span class=\"token number\">0.5</span>\n<span class=\"token function\">sudo</span> <span class=\"token function\">umount</span> <span class=\"token variable\">$MOUNT_POINT</span></code></pre></div>\n<p>Looking at this script, if <code class=\"language-text\">disk.img</code> already exists it removes it, then creates a 200 MB image file in raw format with <code class=\"language-text\">qemu-img create -f raw $DISK_IMG 200M</code>.</p>\n<p>Reference: <a href=\"https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/virtualization_administration_guide/chap-virtualization_administration_guide-tips_and_tricks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">QEMU-img </a></p>\n<p>Next, <code class=\"language-text\">mkfs.fat</code> formats it as an MS-DOS filesystem, mounts it under the <code class=\"language-text\">mnt</code> directory, and then copies the created EFI file to <code class=\"language-text\">EFI/BOOT/BOOTX64.EFI</code>.</p>\n<p>Reference: <a href=\"http://manpages.ubuntu.com/manpages/trusty/man8/mkfs.fat.8.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Ubuntu Manpage: mkfs.fat - create an MS-DOS filesystem under Linux</a></p>\n<p>This image file is then used, and <code class=\"language-text\">run_image.sh</code> emulates it with the <code class=\"language-text\">qemu-system-x86_64</code> command.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">qemu-system-x86_64 <span class=\"token punctuation\">\\</span>\n    -m 1G <span class=\"token punctuation\">\\</span>\n    -drive <span class=\"token assign-left variable\">if</span><span class=\"token operator\">=</span>pflash,format<span class=\"token operator\">=</span>raw,readonly,file<span class=\"token operator\">=</span><span class=\"token variable\">$DEVENV_DIR</span>/OVMF_CODE.fd <span class=\"token punctuation\">\\</span>\n    -drive <span class=\"token assign-left variable\">if</span><span class=\"token operator\">=</span>pflash,format<span class=\"token operator\">=</span>raw,file<span class=\"token operator\">=</span><span class=\"token variable\">$DEVENV_DIR</span>/OVMF_VARS.fd <span class=\"token punctuation\">\\</span>\n    -drive <span class=\"token assign-left variable\">if</span><span class=\"token operator\">=</span>ide,index<span class=\"token operator\">=</span><span class=\"token number\">0</span>,media<span class=\"token operator\">=</span>disk,format<span class=\"token operator\">=</span>raw,file<span class=\"token operator\">=</span><span class=\"token variable\">$DISK_IMG</span> <span class=\"token punctuation\">\\</span>\n    -device nec-usb-xhci,id<span class=\"token operator\">=</span>xhci <span class=\"token punctuation\">\\</span>\n    -device usb-mouse -device usb-kbd <span class=\"token punctuation\">\\</span>\n    -monitor stdio <span class=\"token punctuation\">\\</span>\n    <span class=\"token variable\">$QEMU_OPTS</span></code></pre></div>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>This is just for my own study, so I’m skipping a detailed explanation.</p>\n<p>I’d like to keep going all the way to the end.</p>","fields":{"slug":"/diyos-mikanos-01-en","tagSlugs":["/tag/自作os/","/tag/みかん本/","/tag/os-en/","/tag/english/"]},"frontmatter":{"date":"2021-09-25","description":"I want to retry Introduction to OS Development from Scratch, which I bought as soon as it was released but left untouched because I couldn't find the time and got discouraged by the difficulty. This time I'll cover environment setup through Chapter 2.","tags":["自作OS","みかん本","OS (en)","English"],"title":"Notes from Working Through Introduction to OS Development from Scratch: Environment Setup Through Chapter 2","socialImage":{"publicURL":"/static/dc4d8b7f8795f3c3d3489d9957d155f2/no-image.png"}}}},"pageContext":{"slug":"/diyos-mikanos-01-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}