[{"data":1,"prerenderedAt":2044},["ShallowReactive",2],{"/blog/20210415":3},{"id":4,"title":5,"body":6,"createdAt":2029,"description":2030,"extension":2031,"meta":2032,"navigation":257,"path":2033,"published":257,"seo":2034,"stem":2035,"tags":2036,"titme":2043,"updatedAt":2029},"content/blog/20210415.md","「ゼロからのOS自作入門」 04日目",{"type":7,"value":8,"toc":2017},"minimal",[9,13,26,29,32,40,43,48,51,74,77,83,87,90,93,169,222,225,544,550,553,555,558,561,644,647,656,659,666,669,762,765,771,774,778,781,793,874,878,881,884,999,1002,1006,1012,1015,1053,1086,1116,1119,1125,1128,1130,1133,1136,1143,1146,1192,1196,1205,1213,1218,1221,1556,1560,1563,1821,1824,1923,1982,1985,2005,2008,2010,2013],[10,11,12],"h2",{"id":12},"参考文献",[14,15,16],"ul",{},[17,18,19],"li",{},[20,21,25],"a",{"href":22,"rel":23},"https://qiita.com/yamoridon/items/4905765cc6e4f320c9b5",[24],"nofollow","Mac で始める「ゼロからのOS自作入門」 - Qiita",[27,28],"hr",{},[10,30,31],{"id":31},"試行錯誤メモ",[33,34,35,39],"p",{},[20,36,38],{"href":37},"/blog/20210405","前回","は、ブートローダーからカーネルを直接呼び出すことを学びました。",[33,41,42],{},"今回は、Makefile を利用したビルドと、カーネルでのピクセル描画の効率化を勉強していきます。",[44,45,47],"h3",{"id":46},"makefile","Makefile",[33,49,50],{},"学生時代に Linux を使っていたので Makefile の存在自体は知っているものの、実際に自分で書いたことはないので雰囲気だけ知ってる状態。",[14,52,53,56,59,62,65,68,71],{},[17,54,55],{},"ビルドに使用する変数を定義できる（今回は TARGET/OBJS/CXXFLAGS/LDFLAGS が変数）。",[17,57,58],{},"実行部分は「ターゲット」「必須項目」「レシピ」から構成される。",[17,60,61],{},"make コマンドを実行するとデフォルトでは all が走る。",[17,63,64],{},"ターゲットや必須項目は基本的にファイル名を指定するが .PHONY によって疑似ターゲットも指定できる。",[17,66,67],{},"依存関係やファイルの更新状態によって必須項目がチェックされて、再帰的にターゲットが実行される。",[17,69,70],{},"ファイル名のパターンマッチング（％.o や ％.cpp）もできる。",[17,72,73],{},"定義済み変数（必須項目の先頭を表す $\u003C やターゲット全体を表す $@ など）もある。",[33,75,76],{},"なるほどー。",[78,79],"img",{"width":80,"src":81,"style":82},"70%","/resources/20210415/makefile.png","border: 1px solid grey",[44,84,86],{"id":85},"day04a-のビルド","day04a のビルド",[33,88,89],{},"前回までの知見を踏まえて、書籍のソースコード類に少し手を入れながらビルドを実行していきます。",[33,91,92],{},"具体的には、lld@11 でもカーネルが起動するように、リンク時に elf ファイルのゼロ埋めオプション(-z separate-code)をつけることと、\nEDK で SystemV AMD64 ABI になるようにマクロを指定します。",[94,95,100],"pre",{"className":96,"code":97,"language":98,"meta":99,"style":99},"language-diff shiki shiki-themes slack-dark","--- a/Makefile    2021-04-08 19:36:25.000000000 +0900\n+++ b/Makefile    2021-04-08 20:30:05.000000000 +0900\n@@ -3,7 +3,7 @@ OBJS = main.o\n \n CXXFLAGS += -O2 -Wall -g --target=x86_64-elf -ffreestanding -mno-red-zone \\\n             -fno-exceptions -fno-rtti -std=c++17\n-LDFLAGS  += --entry KernelMain -z norelro --image-base 0x100000 --static\n+LDFLAGS  += --entry KernelMain -z norelro --image-base 0x100000 --static -z separate-code\n \n \n .PHONY: all\n","diff","",[101,102,103,111,117,123,129,135,141,147,153,158,163],"code",{"__ignoreMap":99},[104,105,108],"span",{"class":106,"line":107},"line",1,[104,109,110],{},"--- a/Makefile    2021-04-08 19:36:25.000000000 +0900\n",[104,112,114],{"class":106,"line":113},2,[104,115,116],{},"+++ b/Makefile    2021-04-08 20:30:05.000000000 +0900\n",[104,118,120],{"class":106,"line":119},3,[104,121,122],{},"@@ -3,7 +3,7 @@ OBJS = main.o\n",[104,124,126],{"class":106,"line":125},4,[104,127,128],{}," \n",[104,130,132],{"class":106,"line":131},5,[104,133,134],{}," CXXFLAGS += -O2 -Wall -g --target=x86_64-elf -ffreestanding -mno-red-zone \\\n",[104,136,138],{"class":106,"line":137},6,[104,139,140],{},"             -fno-exceptions -fno-rtti -std=c++17\n",[104,142,144],{"class":106,"line":143},7,[104,145,146],{},"-LDFLAGS  += --entry KernelMain -z norelro --image-base 0x100000 --static\n",[104,148,150],{"class":106,"line":149},8,[104,151,152],{},"+LDFLAGS  += --entry KernelMain -z norelro --image-base 0x100000 --static -z separate-code\n",[104,154,156],{"class":106,"line":155},9,[104,157,128],{},[104,159,161],{"class":106,"line":160},10,[104,162,128],{},[104,164,166],{"class":106,"line":165},11,[104,167,168],{}," .PHONY: all\n",[94,170,172],{"className":96,"code":171,"language":98,"meta":99,"style":99},"--- a/Main.c   2021-04-08 19:36:25.000000000 +0900\n+++ b/Main.c   2021-04-08 19:47:47.000000000 +0900\n@@ -297,7 +297,7 @@ EFI_STATUS EFIAPI UefiMain(\n \n   UINT64 entry_addr = *(UINT64*)(kernel_base_addr + 24);\n \n-  typedef void EntryPointType(UINT64, UINT64);\n+  typedef void __attribute__((sysv_abi)) EntryPointType(UINT64, UINT64);\n   EntryPointType* entry_point = (EntryPointType*)entry_addr;\n   entry_point(gop->Mode->FrameBufferBase, gop->Mode->FrameBufferSize);\n \n",[101,173,174,179,184,189,193,198,202,207,212,217],{"__ignoreMap":99},[104,175,176],{"class":106,"line":107},[104,177,178],{},"--- a/Main.c   2021-04-08 19:36:25.000000000 +0900\n",[104,180,181],{"class":106,"line":113},[104,182,183],{},"+++ b/Main.c   2021-04-08 19:47:47.000000000 +0900\n",[104,185,186],{"class":106,"line":119},[104,187,188],{},"@@ -297,7 +297,7 @@ EFI_STATUS EFIAPI UefiMain(\n",[104,190,191],{"class":106,"line":125},[104,192,128],{},[104,194,195],{"class":106,"line":131},[104,196,197],{},"   UINT64 entry_addr = *(UINT64*)(kernel_base_addr + 24);\n",[104,199,200],{"class":106,"line":137},[104,201,128],{},[104,203,204],{"class":106,"line":143},[104,205,206],{},"-  typedef void EntryPointType(UINT64, UINT64);\n",[104,208,209],{"class":106,"line":149},[104,210,211],{},"+  typedef void __attribute__((sysv_abi)) EntryPointType(UINT64, UINT64);\n",[104,213,214],{"class":106,"line":155},[104,215,216],{},"   EntryPointType* entry_point = (EntryPointType*)entry_addr;\n",[104,218,219],{"class":106,"line":160},[104,220,221],{},"   entry_point(gop->Mode->FrameBufferBase, gop->Mode->FrameBufferSize);\n",[33,223,224],{},"あとは、ブートローダーとカーネルをビルドして QEMU で実行と。(ちゃんと写経するために自分用のディレクトリをようやく作りました。)",[94,226,230],{"className":227,"code":228,"language":229,"meta":99,"style":99},"language-bash shiki shiki-themes slack-dark","# 自分の写経用のディレクトリ\n$ pwd\n/Users/roca/Code/mikanos-local\n\n$ ll\ntotal 0\ndrwxr-xr-x  4 roca  staff  128  4  8 20:44 BIOS\ndrwxr-xr-x  5 roca  staff  160  4  8 19:44 DISK\ndrwxr-xr-x  6 roca  staff  192  4  8 19:35 MikanLoaderPkg\ndrwxr-xr-x  6 roca  staff  192  4  8 19:46 kernel\n\n# ビルドしてバイナリをいい感じにを配置して…。\n$ tree BIOS DISK \nBIOS\n├── OVMF_CODE.fd\n└── OVMF_VARS.fd\nDISK\n├── EFI\n│   └── BOOT\n│       └── BOOTX64.EFI\n└── kernel.elf\n\n# QEMU実行\n$ qemu-system-x86_64 \\\n  -drive if=pflash,file=$HOME/Code/mikanos-local/BIOS/OVMF_CODE.fd \\\n  -drive if=pflash,file=$HOME/Code/mikanos-local/BIOS/OVMF_VARS.fd \\\n  -hda fat:rw:$HOME/Code/mikanos-local/DISK -monitor stdio\n","bash",[101,231,232,238,248,253,259,266,275,303,327,351,373,377,383,400,406,415,424,430,438,450,461,469,474,480,492,510,524],{"__ignoreMap":99},[104,233,234],{"class":106,"line":107},[104,235,237],{"class":236},"sMoaO","# 自分の写経用のディレクトリ\n",[104,239,240,244],{"class":106,"line":113},[104,241,243],{"class":242},"srg1G","$",[104,245,247],{"class":246},"sXcZe"," pwd\n",[104,249,250],{"class":106,"line":119},[104,251,252],{"class":242},"/Users/roca/Code/mikanos-local\n",[104,254,255],{"class":106,"line":125},[104,256,258],{"emptyLinePlaceholder":257},true,"\n",[104,260,261,263],{"class":106,"line":131},[104,262,243],{"class":242},[104,264,265],{"class":246}," ll\n",[104,267,268,271],{"class":106,"line":137},[104,269,270],{"class":242},"total",[104,272,274],{"class":273},"sJ0w9"," 0\n",[104,276,277,280,283,286,289,292,294,297,300],{"class":106,"line":143},[104,278,279],{"class":242},"drwxr-xr-x",[104,281,282],{"class":273},"  4",[104,284,285],{"class":246}," roca",[104,287,288],{"class":246},"  staff",[104,290,291],{"class":273},"  128",[104,293,282],{"class":273},[104,295,296],{"class":273},"  8",[104,298,299],{"class":246}," 20:44",[104,301,302],{"class":246}," BIOS\n",[104,304,305,307,310,312,314,317,319,321,324],{"class":106,"line":149},[104,306,279],{"class":242},[104,308,309],{"class":273},"  5",[104,311,285],{"class":246},[104,313,288],{"class":246},[104,315,316],{"class":273},"  160",[104,318,282],{"class":273},[104,320,296],{"class":273},[104,322,323],{"class":246}," 19:44",[104,325,326],{"class":246}," DISK\n",[104,328,329,331,334,336,338,341,343,345,348],{"class":106,"line":155},[104,330,279],{"class":242},[104,332,333],{"class":273},"  6",[104,335,285],{"class":246},[104,337,288],{"class":246},[104,339,340],{"class":273},"  192",[104,342,282],{"class":273},[104,344,296],{"class":273},[104,346,347],{"class":246}," 19:35",[104,349,350],{"class":246}," MikanLoaderPkg\n",[104,352,353,355,357,359,361,363,365,367,370],{"class":106,"line":160},[104,354,279],{"class":242},[104,356,333],{"class":273},[104,358,285],{"class":246},[104,360,288],{"class":246},[104,362,340],{"class":273},[104,364,282],{"class":273},[104,366,296],{"class":273},[104,368,369],{"class":246}," 19:46",[104,371,372],{"class":246}," kernel\n",[104,374,375],{"class":106,"line":165},[104,376,258],{"emptyLinePlaceholder":257},[104,378,380],{"class":106,"line":379},12,[104,381,382],{"class":236},"# ビルドしてバイナリをいい感じにを配置して…。\n",[104,384,386,388,391,394,397],{"class":106,"line":385},13,[104,387,243],{"class":242},[104,389,390],{"class":246}," tree",[104,392,393],{"class":246}," BIOS",[104,395,396],{"class":246}," DISK",[104,398,128],{"class":399},"sVIqv",[104,401,403],{"class":106,"line":402},14,[104,404,405],{"class":242},"BIOS\n",[104,407,409,412],{"class":106,"line":408},15,[104,410,411],{"class":242},"├──",[104,413,414],{"class":246}," OVMF_CODE.fd\n",[104,416,418,421],{"class":106,"line":417},16,[104,419,420],{"class":242},"└──",[104,422,423],{"class":246}," OVMF_VARS.fd\n",[104,425,427],{"class":106,"line":426},17,[104,428,429],{"class":242},"DISK\n",[104,431,433,435],{"class":106,"line":432},18,[104,434,411],{"class":242},[104,436,437],{"class":246}," EFI\n",[104,439,441,444,447],{"class":106,"line":440},19,[104,442,443],{"class":242},"│",[104,445,446],{"class":246},"   └──",[104,448,449],{"class":246}," BOOT\n",[104,451,453,455,458],{"class":106,"line":452},20,[104,454,443],{"class":242},[104,456,457],{"class":246},"       └──",[104,459,460],{"class":246}," BOOTX64.EFI\n",[104,462,464,466],{"class":106,"line":463},21,[104,465,420],{"class":242},[104,467,468],{"class":246}," kernel.elf\n",[104,470,472],{"class":106,"line":471},22,[104,473,258],{"emptyLinePlaceholder":257},[104,475,477],{"class":106,"line":476},23,[104,478,479],{"class":236},"# QEMU実行\n",[104,481,483,485,488],{"class":106,"line":482},24,[104,484,243],{"class":242},[104,486,487],{"class":246}," qemu-system-x86_64",[104,489,491],{"class":490},"sw3kN"," \\\n",[104,493,495,498,501,505,508],{"class":106,"line":494},25,[104,496,497],{"class":246},"  -drive",[104,499,500],{"class":246}," if=pflash,file=",[104,502,504],{"class":503},"s1e5J","$HOME",[104,506,507],{"class":246},"/Code/mikanos-local/BIOS/OVMF_CODE.fd",[104,509,491],{"class":490},[104,511,513,515,517,519,522],{"class":106,"line":512},26,[104,514,497],{"class":246},[104,516,500],{"class":246},[104,518,504],{"class":503},[104,520,521],{"class":246},"/Code/mikanos-local/BIOS/OVMF_VARS.fd",[104,523,491],{"class":490},[104,525,527,530,533,535,538,541],{"class":106,"line":526},27,[104,528,529],{"class":246},"  -hda",[104,531,532],{"class":246}," fat:rw:",[104,534,504],{"class":503},[104,536,537],{"class":246},"/Code/mikanos-local/DISK",[104,539,540],{"class":246}," -monitor",[104,542,543],{"class":246}," stdio\n",[33,545,546],{},[78,547],{"alt":548,"src":549},"day04a","/resources/20210415/day04a.png",[33,551,552],{},"よーし、day04a = day03c + Makefile が再現できた！",[27,554],{},[44,556,557],{"id":557},"ピクセルを自在に描く",[33,559,560],{},"day03c & day04a では EFI の GOP をそのままカーネルに渡してフレームバッファを描画していたが、\nday04b は独自に定義したフレームバッファ用の構造体定義（frame_buffer_config.hpp）に必要な情報を詰めて参照を渡す方式に変更となった。",[94,562,566],{"className":563,"code":564,"language":565,"meta":99,"style":99},"language-cpp shiki shiki-themes slack-dark","// day04a ローダー側\nEFI_GRAPHICS_OUTPUT_PROTOCOL* gop;\nentry_point(gop->Mode->FrameBufferBase, gop->Mode->FrameBufferSize);\n\n// day04a カーネル側\nextern \"C\" void KernelMain(uint64_t frame_buffer_base,\n                           uint64_t frame_buffer_size) { /* 略 */ }\n\n// ↓\n\n// day04b ローダー側\nstruct FrameBufferConfig config = { /* 略 */ }\nentry_point(&config);\n\n// day04b カーネル側\nextern \"C\" void KernelMain(const FrameBufferConfig& frame_buffer_config) { /* 略 */ }\n","cpp",[101,567,568,573,578,583,587,592,597,602,606,611,615,620,625,630,634,639],{"__ignoreMap":99},[104,569,570],{"class":106,"line":107},[104,571,572],{},"// day04a ローダー側\n",[104,574,575],{"class":106,"line":113},[104,576,577],{},"EFI_GRAPHICS_OUTPUT_PROTOCOL* gop;\n",[104,579,580],{"class":106,"line":119},[104,581,582],{},"entry_point(gop->Mode->FrameBufferBase, gop->Mode->FrameBufferSize);\n",[104,584,585],{"class":106,"line":125},[104,586,258],{"emptyLinePlaceholder":257},[104,588,589],{"class":106,"line":131},[104,590,591],{},"// day04a カーネル側\n",[104,593,594],{"class":106,"line":137},[104,595,596],{},"extern \"C\" void KernelMain(uint64_t frame_buffer_base,\n",[104,598,599],{"class":106,"line":143},[104,600,601],{},"                           uint64_t frame_buffer_size) { /* 略 */ }\n",[104,603,604],{"class":106,"line":149},[104,605,258],{"emptyLinePlaceholder":257},[104,607,608],{"class":106,"line":155},[104,609,610],{},"// ↓\n",[104,612,613],{"class":106,"line":160},[104,614,258],{"emptyLinePlaceholder":257},[104,616,617],{"class":106,"line":165},[104,618,619],{},"// day04b ローダー側\n",[104,621,622],{"class":106,"line":379},[104,623,624],{},"struct FrameBufferConfig config = { /* 略 */ }\n",[104,626,627],{"class":106,"line":385},[104,628,629],{},"entry_point(&config);\n",[104,631,632],{"class":106,"line":402},[104,633,258],{"emptyLinePlaceholder":257},[104,635,636],{"class":106,"line":408},[104,637,638],{},"// day04b カーネル側\n",[104,640,641],{"class":106,"line":417},[104,642,643],{},"extern \"C\" void KernelMain(const FrameBufferConfig& frame_buffer_config) { /* 略 */ }\n",[33,645,646],{},"day04b の注目ポイント。",[648,649,650,653],"ol",{},[17,651,652],{},"C++ 固有文法の「参照型」を使っている点",[17,654,655],{},"WritePixel()の実装をしている点",[33,657,658],{},"WritePixel() では、指定された (x, y) 座標に対して、PixelColor 型（RGB を各 1byte で表現したもの）で指定された色を書き込む関数。",[33,660,661,662,665],{},"任意の座標 (x,y) で表される点は、フレームバッファのバイト列上では ",[101,663,664],{},"4 * (config.pixels_per_scan_line * y + x)","と表されるので、\nその地点のアドレスから、uint8_t のサイズで各色のアドレスにアクセスできる。",[33,667,668],{},"（※ 係数 4 は 1 ピクセルの大きさで、つまり 3 色 * 1 バイト + 未使用の 1 バイトの意味）",[94,670,672],{"className":563,"code":671,"language":565,"meta":99,"style":99},"int WritePixel(const FrameBufferConfig& config,\n               int x, int y, const PixelColor& c) {\n  const int pixel_position = config.pixels_per_scan_line * y + x;\n  if (config.pixel_format == kPixelRGBResv8BitPerColor) {\n    uint8_t* p = &config.frame_buffer[4 * pixel_position];\n    p[0] = c.r;\n    p[1] = c.g;\n    p[2] = c.b;\n  } else if (config.pixel_format == kPixelBGRResv8BitPerColor) {\n    uint8_t* p = &config.frame_buffer[4 * pixel_position];\n    p[0] = c.b;\n    p[1] = c.g;\n    p[2] = c.r;\n  } else {\n    return -1;\n  }\n  return 0;\n}\n",[101,673,674,679,684,689,694,699,704,709,714,719,723,728,732,737,742,747,752,757],{"__ignoreMap":99},[104,675,676],{"class":106,"line":107},[104,677,678],{},"int WritePixel(const FrameBufferConfig& config,\n",[104,680,681],{"class":106,"line":113},[104,682,683],{},"               int x, int y, const PixelColor& c) {\n",[104,685,686],{"class":106,"line":119},[104,687,688],{},"  const int pixel_position = config.pixels_per_scan_line * y + x;\n",[104,690,691],{"class":106,"line":125},[104,692,693],{},"  if (config.pixel_format == kPixelRGBResv8BitPerColor) {\n",[104,695,696],{"class":106,"line":131},[104,697,698],{},"    uint8_t* p = &config.frame_buffer[4 * pixel_position];\n",[104,700,701],{"class":106,"line":137},[104,702,703],{},"    p[0] = c.r;\n",[104,705,706],{"class":106,"line":143},[104,707,708],{},"    p[1] = c.g;\n",[104,710,711],{"class":106,"line":149},[104,712,713],{},"    p[2] = c.b;\n",[104,715,716],{"class":106,"line":155},[104,717,718],{},"  } else if (config.pixel_format == kPixelBGRResv8BitPerColor) {\n",[104,720,721],{"class":106,"line":160},[104,722,698],{},[104,724,725],{"class":106,"line":165},[104,726,727],{},"    p[0] = c.b;\n",[104,729,730],{"class":106,"line":379},[104,731,708],{},[104,733,734],{"class":106,"line":385},[104,735,736],{},"    p[2] = c.r;\n",[104,738,739],{"class":106,"line":402},[104,740,741],{},"  } else {\n",[104,743,744],{"class":106,"line":408},[104,745,746],{},"    return -1;\n",[104,748,749],{"class":106,"line":417},[104,750,751],{},"  }\n",[104,753,754],{"class":106,"line":426},[104,755,756],{},"  return 0;\n",[104,758,759],{"class":106,"line":432},[104,760,761],{},"}\n",[33,763,764],{},"では、いつものようにローダーとカーネルをビルドして実行。",[33,766,767],{},[78,768],{"alt":769,"src":770},"day04b","/resources/20210415/day04b.png",[33,772,773],{},"おー。これで任意のピクセルに任意の色で画像を書けるようになった！",[44,775,777],{"id":776},"c-の仮想関数","C++ の「仮想関数」",[33,779,780],{},"仮想関数とは「サブクラスに実装を強制させるため」の仕組み。",[33,782,783,784,787,788,792],{},"特にベースクラス内のメソッドの内、virtual の修飾子がついて、",[101,785,786],{},"= 0"," となっているものを実装を持っていない ",[789,790,791],"strong",{},"純粋仮想関数"," と呼び、サブクラスで上書き実装（overwrite/オーバーライド）する必要がある\n（ざっくりいうと、インタフェースを定義しているような感じ）。",[94,794,796],{"className":563,"code":795,"language":565,"meta":99,"style":99},"class Base {\n  public:\n    virtual ~Base();\n    void Func();\n    virtual void VFunc1();\n    virtual void VFunc2();\n};\n\nclass Sub: public Base {\n  public:\n    ~Sub();\n    void Func();\n    void VFunc1() override;\n  private:\n    int x;\n};\n\n",[101,797,798,803,808,813,818,823,828,833,837,842,846,851,855,860,865,870],{"__ignoreMap":99},[104,799,800],{"class":106,"line":107},[104,801,802],{},"class Base {\n",[104,804,805],{"class":106,"line":113},[104,806,807],{},"  public:\n",[104,809,810],{"class":106,"line":119},[104,811,812],{},"    virtual ~Base();\n",[104,814,815],{"class":106,"line":125},[104,816,817],{},"    void Func();\n",[104,819,820],{"class":106,"line":131},[104,821,822],{},"    virtual void VFunc1();\n",[104,824,825],{"class":106,"line":137},[104,826,827],{},"    virtual void VFunc2();\n",[104,829,830],{"class":106,"line":143},[104,831,832],{},"};\n",[104,834,835],{"class":106,"line":149},[104,836,258],{"emptyLinePlaceholder":257},[104,838,839],{"class":106,"line":155},[104,840,841],{},"class Sub: public Base {\n",[104,843,844],{"class":106,"line":160},[104,845,807],{},[104,847,848],{"class":106,"line":165},[104,849,850],{},"    ~Sub();\n",[104,852,853],{"class":106,"line":379},[104,854,817],{},[104,856,857],{"class":106,"line":385},[104,858,859],{},"    void VFunc1() override;\n",[104,861,862],{"class":106,"line":402},[104,863,864],{},"  private:\n",[104,866,867],{"class":106,"line":408},[104,868,869],{},"    int x;\n",[104,871,872],{"class":106,"line":417},[104,873,832],{},[44,875,877],{"id":876},"c-の配置-new","C++ の「配置 new」",[33,879,880],{},"まだ OS 自体にメモリ確保の機能がなく、また外部ライブラリに依るメモリ確保の機能もないので、クラスを使用する場合には独自に「メモリの確保＆初期化」を行う必要がある。",[33,882,883],{},"今回のケースだと、配置 new という C++の機能をつかて、予め確保したバイト配列に対してクラスの初期化処理を行うことでクラスを利用可能にしている。",[885,886,887,906],"table",{},[888,889,890],"thead",{},[891,892,893,897,900,903],"tr",{},[894,895,896],"th",{},"変数定義の種類",[894,898,899],{},"配置領域",[894,901,902],{},"メモリ確保",[894,904,905],{},"コンストラクタ",[907,908,909,933,954,973],"tbody",{},[891,910,911,921,927,930],{},[912,913,914,915,918],"td",{},"通常の配置",[916,917],"br",{},[101,919,920],{},"int a = 1;",[912,922,923,924,926],{},"スタック領域",[916,925],{},"（=関数を抜けたら破棄される）",[912,928,929],{},"する",[912,931,932],{},"-",[891,934,935,943,949,951],{},[912,936,937,938,940],{},"malloc による配置（C）",[916,939],{},[101,941,942],{},"User *user = malloc(sizeof(User));",[912,944,945,946,948],{},"ヒープ領域",[916,947],{},"（=関数を抜けても破棄されない）",[912,950,929],{},[912,952,953],{},"呼ばれない",[891,955,956,964,968,970],{},[912,957,958,959,961],{},"new による配置（C++）",[916,960],{},[101,962,963],{},"User user = new User();",[912,965,945,966,948],{},[916,967],{},[912,969,929],{},[912,971,972],{},"呼ばれる",[891,974,975,988,994,997],{},[912,976,977,978,980,983,985],{},"配置 new による配置（C++）",[916,979],{},[101,981,982],{},"char user_buf[sizeof[User]]; ",[916,984],{},[101,986,987],{},"User *user = new(user_buf) User();",[912,989,990,991,993],{},"スタック領域？",[916,992],{},"（≒グローバルだから破棄されないだけ？）",[912,995,996],{},"しない",[912,998,972],{},[33,1000,1001],{},"ナルホドな。このあたりはちゃんと C++の言語仕様を勉強しないとこの後つらそうだなぁ。後で勉強しよう。",[44,1003,1005],{"id":1004},"cclangのvtable","C++(Clang)の「vtable」",[33,1007,1008,1011],{},[789,1009,1010],{},"「仮想関数(virtual function)のポインタ表(table)」"," のこと。クラス継承の際に親子間の仮想関数の解決に使われる対応表みたいなものらしい。",[33,1013,1014],{},"仮想関数を 1 つ以上含むクラス（＆それを継承したクラス）のインスタンスの戦闘には vtable のポインタが埋め込まれる。",[885,1016,1017,1027],{},[888,1018,1019],{},[891,1020,1021,1024],{},[894,1022,1023],{},"関数名",[894,1025,1026],{},"値",[907,1028,1029,1037,1045],{},[891,1030,1031,1034],{},[912,1032,1033],{},"~Base",[912,1035,1036],{},"Base::~Base",[891,1038,1039,1042],{},[912,1040,1041],{},"VFunc1",[912,1043,1044],{},"Base::VFunc1",[891,1046,1047,1050],{},[912,1048,1049],{},"VFunc2",[912,1051,1052],{},"Base::VFunc2",[885,1054,1055,1063],{},[888,1056,1057],{},[891,1058,1059,1061],{},[894,1060,1023],{},[894,1062,1026],{},[907,1064,1065,1073,1080],{},[891,1066,1067,1070],{},[912,1068,1069],{},"~Sub",[912,1071,1072],{},"Sub::~Sub",[891,1074,1075,1077],{},[912,1076,1041],{},[912,1078,1079],{},"Sub::VFunc1",[891,1081,1082,1084],{},[912,1083,1049],{},[912,1085,1052],{},[94,1087,1089],{"className":563,"code":1088,"language":565,"meta":99,"style":99},"Base* ptr = new Sub;\nptr->Func();   // vtable を使わない呼び出し。Base::Func が呼ばれる。\nptr->VFunc1(); // vtable 経由の呼び出し。Sub::VFunc1 が呼ばれる。\nptr->VFunc2(); // vtable 経由の呼び出し。Base::VFunc2 が呼ばれる。\ndelete ptr;\n",[101,1090,1091,1096,1101,1106,1111],{"__ignoreMap":99},[104,1092,1093],{"class":106,"line":107},[104,1094,1095],{},"Base* ptr = new Sub;\n",[104,1097,1098],{"class":106,"line":113},[104,1099,1100],{},"ptr->Func();   // vtable を使わない呼び出し。Base::Func が呼ばれる。\n",[104,1102,1103],{"class":106,"line":119},[104,1104,1105],{},"ptr->VFunc1(); // vtable 経由の呼び出し。Sub::VFunc1 が呼ばれる。\n",[104,1107,1108],{"class":106,"line":125},[104,1109,1110],{},"ptr->VFunc2(); // vtable 経由の呼び出し。Base::VFunc2 が呼ばれる。\n",[104,1112,1113],{"class":106,"line":131},[104,1114,1115],{},"delete ptr;\n",[33,1117,1118],{},"ピクセル描画の関数を抽象化したカーネルを実行する。",[33,1120,1121],{},[78,1122],{"alt":1123,"src":1124},"day04c","/resources/20210415/day04c.png",[33,1126,1127],{},"おー。",[27,1129],{},[44,1131,1132],{"id":1132},"ローダーの改良",[33,1134,1135],{},"今までは、カーネルイメージ全体をそのままメモリ上に配置してエントリポイントのアドレスを参照していたが、\nこの節では ELF 内の各 LOAD セクションの構造を解析して適切にメモリ上に配置したうえでカーネルを実行する。",[33,1137,1138,1139,1142],{},"つまるところ、llvm@10 以降で ",[101,1140,1141],{},"-z separate-code"," をつけてゼロ埋めを復活せて、辻褄を合わせていた部分が不要となる。",[33,1144,1145],{},"まず、ELF ファイルの構造は下記の通り。",[885,1147,1148,1158],{},[888,1149,1150],{},[891,1151,1152,1155],{},[894,1153,1154],{},"構造",[894,1156,1157],{},"補足",[907,1159,1160,1168,1176,1184],{},[891,1161,1162,1165],{},[912,1163,1164],{},"ファイルヘッダ",[912,1166,1167],{},"ファイルの先頭に存在し、ELF 識別子、アーキテクチャ情報および、他の 2 つのヘッダへの情報を持つ。",[891,1169,1170,1173],{},[912,1171,1172],{},"プログラムヘッダ",[912,1174,1175],{},"ファイル上のどの部分(セグメント)がどのような属性で何処に読み込まれるかを保持するヘッダ。",[891,1177,1178,1181],{},[912,1179,1180],{},"セクション本体",[912,1182,1183],{},".text .data .rodata .bss .dynamic など。",[891,1185,1186,1189],{},[912,1187,1188],{},"セクションヘッダ",[912,1190,1191],{},"オブジェクトファイルの論理的な構造を記述する部分。",[1193,1194,1195],"h4",{"id":1195},"参考資料",[14,1197,1198],{},[17,1199,1200],{},[20,1201,1204],{"href":1202,"rel":1203},"https://ja.wikipedia.org/wiki/Executable_and_Linkable_Format",[24],"Executable and Linkable Format - Wikipedia",[1193,1206,1208,1209],{"id":1207},"補足-以前の記事","(補足) ",[20,1210,1212],{"href":1211},"/blog/20210405#%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AE%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB","以前の記事",[1214,1215,1217],"h5",{"id":1216},"z-separate-data-ありの場合","-z separate-data ありの場合。",[33,1219,1220],{},"=> 2つ目の LOADセクションの offset が 0x1000 （=ゼロ埋め分が考慮されている）であり、--image-base を 0x100000 にしたので、エントリポイントの仮想アドレスの 0x0000000000101000 と一致して実行できた。",[94,1222,1226],{"className":1223,"code":1224,"language":1225,"meta":99,"style":99},"language-sh shiki shiki-themes slack-dark","$ readelf -l kernel/kernel.elf\n\nElf file type is EXEC (Executable file)\nEntry point 0x101020\nThere are 5 program headers, starting at offset 64\n\nProgram Headers:\n  Type           Offset             VirtAddr           PhysAddr\n                 FileSiz            MemSiz              Flags  Align\n  PHDR           0x0000000000000040 0x0000000000100040 0x0000000000100040\n                 0x0000000000000118 0x0000000000000118  R      0x8\n  LOAD           0x0000000000000000 0x0000000000100000 0x0000000000100000\n                 0x00000000000001a8 0x00000000000001a8  R      0x1000\n  LOAD           0x0000000000001000 0x0000000000101000 0x0000000000101000\n                 0x00000000000001c9 0x00000000000001c9  R E    0x1000\n  LOAD           0x0000000000002000 0x0000000000102000 0x0000000000102000\n                 0x0000000000000000 0x0000000000000018  RW     0x1000\n  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000\n                 0x0000000000000000 0x0000000000000000  RW     0x0\n\n Section to Segment mapping:\n  Segment Sections...\n   00     \n   01     .rodata \n   02     .text \n   03     .bss \n   04    \n","sh",[101,1227,1228,1241,1245,1271,1282,1311,1315,1323,1337,1351,1365,1379,1393,1406,1419,1435,1448,1462,1476,1487,1491,1505,1513,1521,1531,1541,1551],{"__ignoreMap":99},[104,1229,1230,1232,1235,1238],{"class":106,"line":107},[104,1231,243],{"class":242},[104,1233,1234],{"class":246}," readelf",[104,1236,1237],{"class":246}," -l",[104,1239,1240],{"class":246}," kernel/kernel.elf\n",[104,1242,1243],{"class":106,"line":113},[104,1244,258],{"emptyLinePlaceholder":257},[104,1246,1247,1250,1253,1256,1259,1262,1265,1268],{"class":106,"line":119},[104,1248,1249],{"class":242},"Elf",[104,1251,1252],{"class":246}," file",[104,1254,1255],{"class":246}," type",[104,1257,1258],{"class":246}," is",[104,1260,1261],{"class":246}," EXEC",[104,1263,1264],{"class":399}," (Executable ",[104,1266,1267],{"class":246},"file",[104,1269,1270],{"class":399},")\n",[104,1272,1273,1276,1279],{"class":106,"line":125},[104,1274,1275],{"class":242},"Entry",[104,1277,1278],{"class":246}," point",[104,1280,1281],{"class":273}," 0x101020\n",[104,1283,1284,1287,1290,1293,1296,1299,1302,1305,1308],{"class":106,"line":131},[104,1285,1286],{"class":242},"There",[104,1288,1289],{"class":246}," are",[104,1291,1292],{"class":273}," 5",[104,1294,1295],{"class":246}," program",[104,1297,1298],{"class":246}," headers,",[104,1300,1301],{"class":246}," starting",[104,1303,1304],{"class":246}," at",[104,1306,1307],{"class":246}," offset",[104,1309,1310],{"class":273}," 64\n",[104,1312,1313],{"class":106,"line":137},[104,1314,258],{"emptyLinePlaceholder":257},[104,1316,1317,1320],{"class":106,"line":143},[104,1318,1319],{"class":242},"Program",[104,1321,1322],{"class":246}," Headers:\n",[104,1324,1325,1328,1331,1334],{"class":106,"line":149},[104,1326,1327],{"class":242},"  Type",[104,1329,1330],{"class":246},"           Offset",[104,1332,1333],{"class":246},"             VirtAddr",[104,1335,1336],{"class":246},"           PhysAddr\n",[104,1338,1339,1342,1345,1348],{"class":106,"line":155},[104,1340,1341],{"class":242},"                 FileSiz",[104,1343,1344],{"class":246},"            MemSiz",[104,1346,1347],{"class":246},"              Flags",[104,1349,1350],{"class":246},"  Align\n",[104,1352,1353,1356,1359,1362],{"class":106,"line":160},[104,1354,1355],{"class":242},"  PHDR",[104,1357,1358],{"class":273},"           0x0000000000000040",[104,1360,1361],{"class":273}," 0x0000000000100040",[104,1363,1364],{"class":273}," 0x0000000000100040\n",[104,1366,1367,1370,1373,1376],{"class":106,"line":165},[104,1368,1369],{"class":242},"                 0x0000000000000118",[104,1371,1372],{"class":273}," 0x0000000000000118",[104,1374,1375],{"class":246},"  R",[104,1377,1378],{"class":273},"      0x8\n",[104,1380,1381,1384,1387,1390],{"class":106,"line":379},[104,1382,1383],{"class":242},"  LOAD",[104,1385,1386],{"class":273},"           0x0000000000000000",[104,1388,1389],{"class":273}," 0x0000000000100000",[104,1391,1392],{"class":273}," 0x0000000000100000\n",[104,1394,1395,1398,1401,1403],{"class":106,"line":385},[104,1396,1397],{"class":242},"                 0x00000000000001a8",[104,1399,1400],{"class":273}," 0x00000000000001a8",[104,1402,1375],{"class":246},[104,1404,1405],{"class":273},"      0x1000\n",[104,1407,1408,1410,1413,1416],{"class":106,"line":402},[104,1409,1383],{"class":242},[104,1411,1412],{"class":273},"           0x0000000000001000",[104,1414,1415],{"class":273}," 0x0000000000101000",[104,1417,1418],{"class":273}," 0x0000000000101000\n",[104,1420,1421,1424,1427,1429,1432],{"class":106,"line":408},[104,1422,1423],{"class":242},"                 0x00000000000001c9",[104,1425,1426],{"class":273}," 0x00000000000001c9",[104,1428,1375],{"class":246},[104,1430,1431],{"class":246}," E",[104,1433,1434],{"class":273},"    0x1000\n",[104,1436,1437,1439,1442,1445],{"class":106,"line":417},[104,1438,1383],{"class":242},[104,1440,1441],{"class":273},"           0x0000000000002000",[104,1443,1444],{"class":273}," 0x0000000000102000",[104,1446,1447],{"class":273}," 0x0000000000102000\n",[104,1449,1450,1453,1456,1459],{"class":106,"line":426},[104,1451,1452],{"class":242},"                 0x0000000000000000",[104,1454,1455],{"class":273}," 0x0000000000000018",[104,1457,1458],{"class":246},"  RW",[104,1460,1461],{"class":273},"     0x1000\n",[104,1463,1464,1467,1470,1473],{"class":106,"line":432},[104,1465,1466],{"class":242},"  GNU_STACK",[104,1468,1469],{"class":273},"      0x0000000000000000",[104,1471,1472],{"class":273}," 0x0000000000000000",[104,1474,1475],{"class":273}," 0x0000000000000000\n",[104,1477,1478,1480,1482,1484],{"class":106,"line":440},[104,1479,1452],{"class":242},[104,1481,1472],{"class":273},[104,1483,1458],{"class":246},[104,1485,1486],{"class":273},"     0x0\n",[104,1488,1489],{"class":106,"line":452},[104,1490,258],{"emptyLinePlaceholder":257},[104,1492,1493,1496,1499,1502],{"class":106,"line":463},[104,1494,1495],{"class":242}," Section",[104,1497,1498],{"class":246}," to",[104,1500,1501],{"class":246}," Segment",[104,1503,1504],{"class":246}," mapping:\n",[104,1506,1507,1510],{"class":106,"line":471},[104,1508,1509],{"class":242},"  Segment",[104,1511,1512],{"class":246}," Sections...\n",[104,1514,1515,1518],{"class":106,"line":476},[104,1516,1517],{"class":242},"   00",[104,1519,1520],{"class":399},"     \n",[104,1522,1523,1526,1529],{"class":106,"line":482},[104,1524,1525],{"class":242},"   01",[104,1527,1528],{"class":246},"     .rodata",[104,1530,128],{"class":399},[104,1532,1533,1536,1539],{"class":106,"line":494},[104,1534,1535],{"class":242},"   02",[104,1537,1538],{"class":246},"     .text",[104,1540,128],{"class":399},[104,1542,1543,1546,1549],{"class":106,"line":512},[104,1544,1545],{"class":242},"   03",[104,1547,1548],{"class":246},"     .bss",[104,1550,128],{"class":399},[104,1552,1553],{"class":106,"line":526},[104,1554,1555],{"class":242},"   04\n",[1214,1557,1559],{"id":1558},"z-separate-date-なし","-z separate-date なし",[33,1561,1562],{},"=> 2つ目の LOADセクションの offset が 0x1b0 （=ゼロ埋め分が考慮されてない）であり、--image-base を 0x100000 にしたが、エントリポイントの仮想アドレスの 0x0000000000101000 と一致していないので実行できない。",[94,1564,1566],{"className":227,"code":1565,"language":229,"meta":99,"style":99},"$ readelf -l kernel/kernel.elf\n\nElf file type is EXEC (Executable file)\nEntry point 0x1011d0\nThere are 5 program headers, starting at offset 64\n\nProgram Headers:\n  Type           Offset             VirtAddr           PhysAddr\n                 FileSiz            MemSiz              Flags  Align\n  PHDR           0x0000000000000040 0x0000000000100040 0x0000000000100040\n                 0x0000000000000118 0x0000000000000118  R      0x8\n  LOAD           0x0000000000000000 0x0000000000100000 0x0000000000100000\n                 0x00000000000001a8 0x00000000000001a8  R      0x1000\n  LOAD           0x00000000000001b0 0x00000000001011b0 0x00000000001011b0\n                 0x00000000000001c9 0x00000000000001c9  R E    0x1000\n  LOAD           0x0000000000000380 0x0000000000102380 0x0000000000102380\n                 0x0000000000000000 0x0000000000000018  RW     0x1000\n  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000\n                 0x0000000000000000 0x0000000000000000  RW     0x0\n\n Section to Segment mapping:\n  Segment Sections...\n   00     \n   01     .rodata \n   02     .text \n   03     .bss \n   04\n",[101,1567,1568,1578,1582,1600,1609,1629,1633,1639,1649,1659,1669,1679,1689,1699,1712,1724,1737,1747,1757,1767,1771,1781,1787,1793,1801,1809,1817],{"__ignoreMap":99},[104,1569,1570,1572,1574,1576],{"class":106,"line":107},[104,1571,243],{"class":242},[104,1573,1234],{"class":246},[104,1575,1237],{"class":246},[104,1577,1240],{"class":246},[104,1579,1580],{"class":106,"line":113},[104,1581,258],{"emptyLinePlaceholder":257},[104,1583,1584,1586,1588,1590,1592,1594,1596,1598],{"class":106,"line":119},[104,1585,1249],{"class":242},[104,1587,1252],{"class":246},[104,1589,1255],{"class":246},[104,1591,1258],{"class":246},[104,1593,1261],{"class":246},[104,1595,1264],{"class":399},[104,1597,1267],{"class":246},[104,1599,1270],{"class":399},[104,1601,1602,1604,1606],{"class":106,"line":125},[104,1603,1275],{"class":242},[104,1605,1278],{"class":246},[104,1607,1608],{"class":273}," 0x1011d0\n",[104,1610,1611,1613,1615,1617,1619,1621,1623,1625,1627],{"class":106,"line":131},[104,1612,1286],{"class":242},[104,1614,1289],{"class":246},[104,1616,1292],{"class":273},[104,1618,1295],{"class":246},[104,1620,1298],{"class":246},[104,1622,1301],{"class":246},[104,1624,1304],{"class":246},[104,1626,1307],{"class":246},[104,1628,1310],{"class":273},[104,1630,1631],{"class":106,"line":137},[104,1632,258],{"emptyLinePlaceholder":257},[104,1634,1635,1637],{"class":106,"line":143},[104,1636,1319],{"class":242},[104,1638,1322],{"class":246},[104,1640,1641,1643,1645,1647],{"class":106,"line":149},[104,1642,1327],{"class":242},[104,1644,1330],{"class":246},[104,1646,1333],{"class":246},[104,1648,1336],{"class":246},[104,1650,1651,1653,1655,1657],{"class":106,"line":155},[104,1652,1341],{"class":242},[104,1654,1344],{"class":246},[104,1656,1347],{"class":246},[104,1658,1350],{"class":246},[104,1660,1661,1663,1665,1667],{"class":106,"line":160},[104,1662,1355],{"class":242},[104,1664,1358],{"class":273},[104,1666,1361],{"class":273},[104,1668,1364],{"class":273},[104,1670,1671,1673,1675,1677],{"class":106,"line":165},[104,1672,1369],{"class":242},[104,1674,1372],{"class":273},[104,1676,1375],{"class":246},[104,1678,1378],{"class":273},[104,1680,1681,1683,1685,1687],{"class":106,"line":379},[104,1682,1383],{"class":242},[104,1684,1386],{"class":273},[104,1686,1389],{"class":273},[104,1688,1392],{"class":273},[104,1690,1691,1693,1695,1697],{"class":106,"line":385},[104,1692,1397],{"class":242},[104,1694,1400],{"class":273},[104,1696,1375],{"class":246},[104,1698,1405],{"class":273},[104,1700,1701,1703,1706,1709],{"class":106,"line":402},[104,1702,1383],{"class":242},[104,1704,1705],{"class":273},"           0x00000000000001b0",[104,1707,1708],{"class":273}," 0x00000000001011b0",[104,1710,1711],{"class":273}," 0x00000000001011b0\n",[104,1713,1714,1716,1718,1720,1722],{"class":106,"line":408},[104,1715,1423],{"class":242},[104,1717,1426],{"class":273},[104,1719,1375],{"class":246},[104,1721,1431],{"class":246},[104,1723,1434],{"class":273},[104,1725,1726,1728,1731,1734],{"class":106,"line":417},[104,1727,1383],{"class":242},[104,1729,1730],{"class":273},"           0x0000000000000380",[104,1732,1733],{"class":273}," 0x0000000000102380",[104,1735,1736],{"class":273}," 0x0000000000102380\n",[104,1738,1739,1741,1743,1745],{"class":106,"line":426},[104,1740,1452],{"class":242},[104,1742,1455],{"class":273},[104,1744,1458],{"class":246},[104,1746,1461],{"class":273},[104,1748,1749,1751,1753,1755],{"class":106,"line":432},[104,1750,1466],{"class":242},[104,1752,1469],{"class":273},[104,1754,1472],{"class":273},[104,1756,1475],{"class":273},[104,1758,1759,1761,1763,1765],{"class":106,"line":440},[104,1760,1452],{"class":242},[104,1762,1472],{"class":273},[104,1764,1458],{"class":246},[104,1766,1486],{"class":273},[104,1768,1769],{"class":106,"line":452},[104,1770,258],{"emptyLinePlaceholder":257},[104,1772,1773,1775,1777,1779],{"class":106,"line":463},[104,1774,1495],{"class":242},[104,1776,1498],{"class":246},[104,1778,1501],{"class":246},[104,1780,1504],{"class":246},[104,1782,1783,1785],{"class":106,"line":471},[104,1784,1509],{"class":242},[104,1786,1512],{"class":246},[104,1788,1789,1791],{"class":106,"line":476},[104,1790,1517],{"class":242},[104,1792,1520],{"class":399},[104,1794,1795,1797,1799],{"class":106,"line":482},[104,1796,1525],{"class":242},[104,1798,1528],{"class":246},[104,1800,128],{"class":399},[104,1802,1803,1805,1807],{"class":106,"line":494},[104,1804,1535],{"class":242},[104,1806,1538],{"class":246},[104,1808,128],{"class":399},[104,1810,1811,1813,1815],{"class":106,"line":512},[104,1812,1545],{"class":242},[104,1814,1548],{"class":246},[104,1816,128],{"class":399},[104,1818,1819],{"class":106,"line":526},[104,1820,1555],{"class":242},[1193,1822,1823],{"id":1823},"各ヘッダを表す構造体",[94,1825,1827],{"className":563,"code":1826,"language":565,"meta":99,"style":99},"// ファイルヘッダ を表す構造体\n#define EI_NIDENT 16\n\ntypedef struct {\n  unsigned char e_ident[EI_NIDENT];\n  Elf64_Half    e_type;\n  Elf64_Half    e_machine;\n  Elf64_Word    e_version;\n  Elf64_Addr    e_entry;\n  Elf64_Off     e_phoff;\n  Elf64_Off     e_shoff;\n  Elf64_Word    e_flags;\n  Elf64_Half    e_ehsize;\n  Elf64_Half    e_phentsize;\n  Elf64_Half    e_phnum;\n  Elf64_Half    e_shentsize;\n  Elf64_Half    e_shnum;\n  Elf64_Half    e_shstrndx;\n} Elf64_Ehdr;\n",[101,1828,1829,1834,1839,1843,1848,1853,1858,1863,1868,1873,1878,1883,1888,1893,1898,1903,1908,1913,1918],{"__ignoreMap":99},[104,1830,1831],{"class":106,"line":107},[104,1832,1833],{},"// ファイルヘッダ を表す構造体\n",[104,1835,1836],{"class":106,"line":113},[104,1837,1838],{},"#define EI_NIDENT 16\n",[104,1840,1841],{"class":106,"line":119},[104,1842,258],{"emptyLinePlaceholder":257},[104,1844,1845],{"class":106,"line":125},[104,1846,1847],{},"typedef struct {\n",[104,1849,1850],{"class":106,"line":131},[104,1851,1852],{},"  unsigned char e_ident[EI_NIDENT];\n",[104,1854,1855],{"class":106,"line":137},[104,1856,1857],{},"  Elf64_Half    e_type;\n",[104,1859,1860],{"class":106,"line":143},[104,1861,1862],{},"  Elf64_Half    e_machine;\n",[104,1864,1865],{"class":106,"line":149},[104,1866,1867],{},"  Elf64_Word    e_version;\n",[104,1869,1870],{"class":106,"line":155},[104,1871,1872],{},"  Elf64_Addr    e_entry;\n",[104,1874,1875],{"class":106,"line":160},[104,1876,1877],{},"  Elf64_Off     e_phoff;\n",[104,1879,1880],{"class":106,"line":165},[104,1881,1882],{},"  Elf64_Off     e_shoff;\n",[104,1884,1885],{"class":106,"line":379},[104,1886,1887],{},"  Elf64_Word    e_flags;\n",[104,1889,1890],{"class":106,"line":385},[104,1891,1892],{},"  Elf64_Half    e_ehsize;\n",[104,1894,1895],{"class":106,"line":402},[104,1896,1897],{},"  Elf64_Half    e_phentsize;\n",[104,1899,1900],{"class":106,"line":408},[104,1901,1902],{},"  Elf64_Half    e_phnum;\n",[104,1904,1905],{"class":106,"line":417},[104,1906,1907],{},"  Elf64_Half    e_shentsize;\n",[104,1909,1910],{"class":106,"line":426},[104,1911,1912],{},"  Elf64_Half    e_shnum;\n",[104,1914,1915],{"class":106,"line":432},[104,1916,1917],{},"  Elf64_Half    e_shstrndx;\n",[104,1919,1920],{"class":106,"line":440},[104,1921,1922],{},"} Elf64_Ehdr;\n",[94,1924,1926],{"className":563,"code":1925,"language":565,"meta":99,"style":99},"// プログラムヘッダを表す構造体\ntypedef struct {\n  Elf64_Word  p_type;   // PHDR, LOADER などのセグメント種別\n  Elf64_Word  p_flags;  // フラグ\n  Elf64_Off   p_offset; // オフセット\n  Elf64_Addr  p_vaddr;  // 仮想ADDR\n  Elf64_Addr  p_paddr;\n  Elf64_Xword p_filesz; // ファイルサイズ\n  Elf64_Xword p_memsz;  // メモリサイズ\n  Elf64_Xword p_align;\n} Elf64_Phdr;\n",[101,1927,1928,1933,1937,1942,1947,1952,1957,1962,1967,1972,1977],{"__ignoreMap":99},[104,1929,1930],{"class":106,"line":107},[104,1931,1932],{},"// プログラムヘッダを表す構造体\n",[104,1934,1935],{"class":106,"line":113},[104,1936,1847],{},[104,1938,1939],{"class":106,"line":119},[104,1940,1941],{},"  Elf64_Word  p_type;   // PHDR, LOADER などのセグメント種別\n",[104,1943,1944],{"class":106,"line":125},[104,1945,1946],{},"  Elf64_Word  p_flags;  // フラグ\n",[104,1948,1949],{"class":106,"line":131},[104,1950,1951],{},"  Elf64_Off   p_offset; // オフセット\n",[104,1953,1954],{"class":106,"line":137},[104,1955,1956],{},"  Elf64_Addr  p_vaddr;  // 仮想ADDR\n",[104,1958,1959],{"class":106,"line":143},[104,1960,1961],{},"  Elf64_Addr  p_paddr;\n",[104,1963,1964],{"class":106,"line":149},[104,1965,1966],{},"  Elf64_Xword p_filesz; // ファイルサイズ\n",[104,1968,1969],{"class":106,"line":155},[104,1970,1971],{},"  Elf64_Xword p_memsz;  // メモリサイズ\n",[104,1973,1974],{"class":106,"line":160},[104,1975,1976],{},"  Elf64_Xword p_align;\n",[104,1978,1979],{"class":106,"line":165},[104,1980,1981],{},"} Elf64_Phdr;\n",[1193,1983,1984],{"id":1984},"カーネル実行までの手順",[14,1986,1987,1990,1993,1996,1999,2002],{},[17,1988,1989],{},"一時領域にカーネルファイルを読み込む",[17,1991,1992],{},"カーネルファイル内のプログラムヘッダーを解析",[17,1994,1995],{},"LOAD セクションの仮想アドレスの最小値と最大値を調べる（=実際に実行する部分を配置するメモリ量を計算するため）",[17,1997,1998],{},"メモリの確保",[17,2000,2001],{},"メモリ内に LOAD セクションをコピーし、セグメント上のメモリサイズがファイルサイズより大きい場合はゼロ埋め",[17,2003,2004],{},"実行部分の先頭アドレスをエントリポイントに受け渡して実行！",[33,2006,2007],{},"なるほどなー!!",[27,2009],{},[33,2011,2012],{},"だいぶ、理解するのが難しくなってきた…！　とりあえず細かいところはさておいて先に進もう！　ゴーゴー！",[2014,2015,2016],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sMoaO, html code.shiki .sMoaO{--shiki-default:#6A9955}html pre.shiki code .srg1G, html code.shiki .srg1G{--shiki-default:#DCDCAA}html pre.shiki code .sXcZe, html code.shiki .sXcZe{--shiki-default:#CE9178}html pre.shiki code .sJ0w9, html code.shiki .sJ0w9{--shiki-default:#B5CEA8}html pre.shiki code .sVIqv, html code.shiki .sVIqv{--shiki-default:#E6E6E6}html pre.shiki code .sw3kN, html code.shiki .sw3kN{--shiki-default:#D7BA7D}html pre.shiki code .s1e5J, html code.shiki .s1e5J{--shiki-default:#9CDCFE}",{"title":99,"searchDepth":113,"depth":113,"links":2018},[2019,2020],{"id":12,"depth":113,"text":12},{"id":31,"depth":113,"text":31,"children":2021},[2022,2023,2024,2025,2026,2027,2028],{"id":46,"depth":119,"text":47},{"id":85,"depth":119,"text":86},{"id":557,"depth":119,"text":557},{"id":776,"depth":119,"text":777},{"id":876,"depth":119,"text":877},{"id":1004,"depth":119,"text":1005},{"id":1132,"depth":119,"text":1132},"2021-04-14T15:00:00.000Z","「ゼロからのOS自作入門」 を勉強したときのメモ。","md",{},"/blog/20210415",{"title":5,"description":2030},"blog/20210415",[2037,2038,2039,2040,2041,2042],"ゼロからのOS自作入門","QEMU","UEFI","EDK II","M1","Mac",null,1756192142328]