OpenSBIの内部実装(boot~linux kernelを実行するまで)

はじめに OpenSBIとはRISC-V向けに提供されたSBI(Supervisor Binary Interface)仕様の実装で、M-modeでの挙動が実装されている(linux kernelはS-modeとU-modeでの挙動が実装されている)。前回の記事でlinux kernel(v5.3.6)の下でOpenSBIを導入した手順を書い…

<RISC-V版> QEMU+OpenSBI(boot loader)でlinux kernelの起動

はじめに 他のサイトでもいろいろな構成でbuildされているが、今回は、OpenSBIというBoot Loaderを用いて、linux kernel(v5.3.6)を動かしてみた。 /sbin/init以下で動作させるためのスクリプトも用意する必要があるが、これはbusyboxというユーザーランドで…

RISC-Vとx86のsystem callの内部実装の違い(xv6を例に)

はじめに xv6-publicとxv6-riscvはUNIX v6を下敷きに、それぞれx86 versionとRISC-V versionに移植された教育用のOSである。 前回、RISC-Vのprivilege modeの遷移について書いたが、本記事では前回よりも少し具体的に、system callがx86 versionとRISC-V ver…

RISC-Vにおけるprivilege modeの遷移(xv6-riscvを例にして)

はじめに xv6-riscvは、本ブログでも何度か記事にしたことのあるMITの教育用のOSであるxv6(x86 version)のRISC-V versionである(2019/9/11に登場したっぽい)。x86(32bit)のとは違い、RV64(64bit)のOSである。 本記事では、RISC-Vのprivilegeとmode遷移につい…

mmapにおけるMAP_PRIVATEの挙動

はじめに mmap(2)とはmemory mappingを新規に作成するsystem callである。 #include <sys/mman.h> void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off); mmap(2)は下図(Reference[1]のch.49より引用)のようにmapping typeとprivate/shared</sys/mman.h>…

"Understanding the Linux Kernel 3rd.ed."(邦訳:詳解 Linuxカーネル 第3版)だいたい読んだ

これを大体完走した1。バージョンが古すぎとよく言われる本だが、大規模なコードでもまるで技術書を読むのと同じ感覚でコードリーディングできるようになったと感じる。 ソースコードリーディングするとき、関数の頭から順に読むのでなく、お尻から使用され…

Linux KernelにおけるCopy On Write(CoW)の仕組み(概要編)

はじめに Copy On Write(CoW)とは書き込みが実際に起こるまで、複数のプロセスが同じ物理メモリを共有し続ける方法である。もっと端的に言うと、書き込みが発生したら、そこで初めて該当のpageのみ遅延複製する1。Linuxでは、以下の2つの場面2で用いられる:…

xv6におけるforkの挙動について

はじめに xv6でのfork関数について、親プロセスと子プロセスとのパラメタ設定の比較を意識してまとめてみた。 なお、context switch(struct contextが関係してる)やsyscall, iret(struct trapframeが関係してる)の詳細は省くので、switching編を参考にしてく…

vm_area_structの探索関数(find_vma_**関数群)について

はじめに "Understanding the Linux Kernel"(version. 2.6.11)のch.9 Process Address Spaceのvm_area_structを探索する関数群: find_vma(struct mm_struct * mm, unsigned long addr) find_vma_prev(struct mm_struct *mm, unsigned long addr, struct vm_…

xv6におけるfilesystemのLayer(下層編)

はじめに xv6におけるfilesystemの構造についてまとめたい。xv6ではext2とかではなく、もう少し簡素な独自filesystemを採用している1。 今回は、filesystemのデータ構造及び、下図のlayerの下三層つまり、"disk layer", "buffer cache layer", "Logging laye…

ABCIシステムの使い方(応用編)

はじめに ABCIシステムの使い方というタイトルでブログ記事を書いたがまぁまぁ反響があったため、自身が実際にどうスパコンの上で基盤構築したかをアプリケーション依存1の話を極力避けてお話したい。 なお、MPIやOpenMPについては説明しない。これについて…

Linux Kernel(2.6.11)の内部実装のアウトプットまとめ

xv6(MITが開発した教育用OS)と同じく、Understanding the Linux Kernel 3rd.ed.をソースコードリーディングしてまとめた記事を羅列しておく。(これも適宜更新していきたい) Note) この本が取り扱っているバージョンは2.6.11でかなり古い。また、x86のコード…

xv6のアウトプットまとめ

xv6に関して自身のアウトプットをまとめておく。Qiita( https://qiita.com/knknkn1162 )とこのブログに分散しているので、良くないと思った(適宜更新していく予定)。 xv6とはMITがUNIX v6をx86仕様に書き直した教育用OSで、 https://github.com/mit-pdos/xv6…

keyboard, UART, VGAの初期化(xv6を例に)

はじめに 本記事では、xv6においてUART, keyboardがboot時にどの様に初期化されているのかを確認する。ソフトウェアエンジニアにとって一番たいへんなところがマジックナンバー(0x3f8, 115200, 9600など)の意味の理解だと思うので、この数字の出自をなるべく…

A20 gateとkeyboard controller(xv6を例にして)

はじめに xv6でのA20 gateをenableしている過程をソースコードレベルで詳しく追っていく。A20 gateの概要に関しては、reference[8] が詳しいので省略。keyboard controllerについては後述する。 Note) 大目標としてはkeyboard入力の際に、どのような過程をた…

spinlockについて

はじめに spinlockはbusy waitによって実現するlockの手法のことである。busy waitとは、lockを取得できるまでloopで待機するという点で原始的だが、lock/unlockに要するオーバーヘッドを最小限にできるので、Linux kernelでは頻繁に登場する。 内部実装的に…

`path_lookup()`を追ってみる

はじめに Linux kernelにおいて、filesystemの内部のデータ構造はかなり把握しづらい。(virtual) filesystemの実装を読み解く上で重要だが、ややこしい関数として2つあると思う: do_kern_mount path_lookup 前者のdo_kern_mountはmounted filesystem(struc…

initcallとは

はじめに linux kernel1を読んでいると、**_initcall(core_initcallとか__initcallとかが色々なところで定義されている。例えば、sysenterの初期設定(IA32_SYSENTER_(CS|EIP|ESP))をしているarch/i386/kernel/sysenter.cでは、 extern const char vsyscall_i…

ABCIシステムの使い方

ABCIシステムについて GPUの環境を整えるのに、オンプレorクラウドかを状況に応じて選択する場合、双方メリット、デメリットがある。オンプレの場合は伝聞だと、運用がとても大変らしい。対して大手クラウドサービス(AWS, GCPなどでGPUインスタンス)を用いる…

linux kernelでのFPU, MMX, SSEについて

linux kernelでのFPU, MMX, SSEについて 本記事では、linux kernel 2.6.11でのFPU(Float Point Unit)やMMX, SSEがどう設定、使用されているのかを確認する。FPU, MMX SSE命令を使用する際は、使用する際に意図的に#NM(Interrupt7: Device not available exce…

slab allocatorの内部実装

slab allocatorの内部実装 page frameは4K単位の管理なので、比較的小さいメモリ領域を確保するときに効率が悪い。そこで、linux2.6では、slab allocatorという仕組みを用いて小さな領域を効率的にreserved/freeするようになっている。cacheという概念自体は…

e820について

linux kernelのsetupの部分を読んでいて、E820という謎の数字?が気になったのと、ここで得られたデータをboot時に後々利用しているので、少し重点的に調べてみる。 reference http://www.uruk.org/orig-grub/mem64mb.html あるいは、BIOSのdocument: https:/…

linux kernelにおけるtimerについて

linux kernelにおけるtimerについて(Timing Measurementsについて) はじめに user landで見えるtimerは時刻の取得やsiginfoとか、epollといったselect系など関数でのtimeoutの設定で用いられるが、kernel側でのtimerの利用はこれとは大きく異なる1。 本記事…

linux2.6の場合のExceptionと`int $0x80`(system call)の挙動

linux2.6の場合のExceptionとint $0x80の挙動 前の記事でxv6ではどうなのかを述べた。今回はlinux kernel(2.6.11)の場合のexceptionとint $0x80の挙動についてまとめる。今回も長いので、I/O APIC, local APICがからんだinterruptは後回しにしたい。 referen…

xv6の場合のExceptionとInterruptの挙動

ExceptionとInterruptの挙動 linux2.6.11の場合のExceptionとInterruptの挙動をまとめようと思って、xv6との比較を書いていたが分量が多くなりすぎたので、簡単にxv6ではException、Interruptをどう処理しているのかをまとめる。 Reference http://www.cse.i…

`switch_to`を読んでみる

reference Understanding the Linux Kernel ch.3 http://caspar.hazymoon.jp/OpenBSD/annex/gcc_inline_asm.html オペランド制約の部分が非常によくまとまっている 概要 linux kernel 2.6.11より schedule() => context_switch(rq, prev, next); => switch_t…

GDTとIDT周辺の理解(xv6を例に)

Motivation Understanding the Linux Kernelを読もうとしたけど、生半可な気持ちでは臨めなさそうなので、xv6で理解の確認しつつ、linux kernel 2.6ではどうなの?という把握をすれば良さそう。 そこで、Understanding the Linux KernelのChapter 2: Memory …

はてブでコメントし続けるとロジカルシンキングの能力がアホみたいに上がった話

社内数人のグループで1、あるビジネス本を読んだ感想文(気づきとか)をお互いに発表する機会があったのだが、個人的に驚くことがあった。 彼(ら)は本の中の一部を引用して、「ここの言葉は自分にとって良かったので、参考にしたいと思いました」と、まるで偉…

1月の棚卸し

なるべく月末にやったことの棚卸しをしたいと思うので、毎月継続して書いていくつもり1。 1月は7日くらいまでキーボードやVGAとFPGAをつないで、プログラム書いて動作確認したりしていた。しかしながら、会社が始まるとなかなか思うように進捗を生み出せず…

今年の自分の感想

今年考えたこととやったこと、やりたいことの棚卸し。 来年8月で30という歳を考え、なんかやばいやろ、みたいな危機感?みたいなのが生まれた結果、今年は6月から本気出した気がする。多分、一日も欠かさず勉強した。 一年を通しての目標としては、低レイヤ…