riscV clang -> gcc
Table of Contents
clang -> gcc
リナのclangを使って構築された1000行OSをOpenBSDの32Bit用gccでコンパイルしてみると 下記の様にエラーのオンパレードだ。
common.h:16:34: warning: implicit declaration of function '__builtin_is_aligned' ; did you mean '__builtin_isalnum'? [-Wimplicit-function-declaration] #define is_aligned(value, align) __builtin_is_aligned(value, align) ^~~~~~~~~~~~~~~~~~~~ kernel.c:27:10: note: in expansion of macro 'is_aligned' if (!is_aligned(vaddr, PAGE_SIZE)) ^~~~~~~~~~ kernel.c: In function 'virtq_init': common.h:15:34: warning: implicit declaration of function '__builtin_align_up'; did you mean '__builtin_asin'? [-Wimplicit-function-declaration] #define align_up(value, align) __builtin_align_up(value, align) ^~~~~~~~~~~~~~~~~~ kernel.c:97:39: note: in expansion of macro 'align_up' paddr_t virtq_paddr = alloc_pages(align_up(sizeof(struct virtio_virtq), PAG E_SIZE) / PAGE_SIZE); ^~~~~~~~ kernel.c: At top level: kernel.c:173:9: error: variably modified 'disk' at file scope uint8_t disk[DISK_MAX_SIZE]; ^~~~
ワーニングはいいとして、決定的なエラーを調べてみると、 Variably modified array at file scope in C こんなんだ。これはもう、先に出て いるワーニングを潰しておく必要が有るな。
Rustで頑張った人もclangにしか実装されていない、ビルトイン関数を独自実装 されている。移植先に無いのは追加ね。
pub const fn align_up(value: usize, align: usize) -> usize { let r = value % align; if r == 0 { value } else { value + (align - r) } } pub const fn is_aligned(value: usize, align: usize) -> bool { value % align == 0 }
common.hの該当部分を変更した。
#define align_up(v, a) (v % a? v: v + (a - v % a)) #define is_aligned(value, align) (value % align)
run.shのtarの部分をBSDtar様に変更した。
(cd disk && tar -F ustar -cf ../disk.tar *.txt)
kernel.c: In function 'switch_context': kernel.c:363:54: warning: unused parameter 'prev_sp' [-Wunused-parameter] __attribute__((naked)) void switch_context(uint32_t *prev_sp, ~~~~~~~~~~^~~~~~~ kernel.c:364:54: warning: unused parameter 'next_sp' [-Wunused-parameter] uint32_t *next_sp) { ~~~~~~~~~~^~~~~~~ + cd disk + tar -F ustar -cf ../disk.tar hello.txt meow.txt + qemu-system-riscv32 -machine virt -bios default -nographic -serial mon:stdio - -no-reboot -d unimp,guest_errors,int,cpu_reset -D qemu.log -drive id=drive0,file =disk.tar,format=raw,if=none -device virtio-blk-device,drive=drive0,bus=virtio-m mio-bus.0 -kernel kernel.elf OpenSBI v1.5.1 : virtio-blk: capacity is 10240 bytes file: hello.txt, size=83 PANIC: kernel.c:28: unaligned vaddr 80200000
わーい、パニックだぞ。飯の種が出てきたぞ(そう、政府の備蓄米放出を機に、じっくり 農政を考えましょう、みたいな)。
void map_page(uint32_t *table1, uint32_t vaddr, paddr_t paddr, uint32_t flags) \ { if (!is_aligned(vaddr, PAGE_SIZE)) PANIC("unaligned vaddr %x", vaddr);
BUGはオイラーが実装した所に宿るの法則が健在っぽいな。ロジックが逆ちゃいますか?
#define is_aligned(value, align) (!(value % align))
why warning?
Q: Linux上のclang環境で作成されたriscv用の簡易OSをOpenBSDに移植してます。
BSD側は、CC=riscv32-esp-elf-gcc です。
Clang独自の便利拡張として __builtin_align_up
などが追加されているとの事。
実際にOpenBSDでコンパイルすると、下記の様に見事に警告が出ました。
そして、その拡張を利用してる DISK_MAX_SIZE
は、別なエラーとして検出されてます。
__builtin_aline_up
は、gcc上では未定義にもかかわらず、緩い警告止まりになって
ます。これには少々納得がいきません。歴史的な所産なのでしょうか?
A: とても鋭い観察です。以下にあなたの疑問に答える形で、ClangとGCCの挙動の違いや、`_builtinalignup` の取り扱い、さらには変数長配列(VLA)の文脈でのエラーの違いなどを整理します。
—
### ■ `_builtinalignup` は Clang 拡張であり GCC 非対応
まず、`_builtinalignup()` は Clang 特有のビルトイン関数で、GCC には存在しません(2025年時点でも対応していません)。
- Clang ではこのような関数が多数追加されており、C言語仕様を拡張する形で安全性や最適化の支援をしています。
- 例えば `_builtinalignup(value, alignment)` は `value` を `alignment` 境界に切り上げる動作を行います(`value + alignment - 1` を `alignment` で切り下げるようなもの)。
—
### ■ GCCではなぜ「警告止まり」なのか?
GCCでは、`_builtin*` 形式の識別子に対して、**暗黙の宣言(implicit declaration)** を許容して「警告」止まりにするのがデフォルトの挙動です。 これは以下のような歴史的・互換性的な理由によるものです。
#### ◉ 歴史的経緯
- C言語(特にC89)の頃は、関数のプロトタイプ宣言が無くてもコンパイラが暗黙の `int` 型で関数の存在を仮定するという仕様がありました。
- GCCは古いコードとの互換性を保つため、今もこの仕様をある程度保持しています。
- ただし `-Werror=implicit-function-declaration` のように明示的にエラーに変えることは可能です。
#### ◉ Clangではより厳密
- Clangはこのあたりでより**厳格にモダンなC言語の規格**(C99/C11など)を適用する傾向にあり、未宣言関数の使用を**エラー扱い**にすることがあります(特にC99以降は仕様上未定義動作)。
—
### ■ `disk[DISKMAXSIZE]` での「variably modified ‘disk’ at file scope」
こちらも別の重要な点です。これは以下のような理由です:
- `DISKMAXSIZE` が 関数外で使われている(グローバル変数) にもかかわらず、
- そのサイズが **定数式(constant expression)でない**(たとえば `_builtinalignup(…)` のような不明な関数が絡んでいる)ため、
- コンパイラはそれを「\*\*VLA(可変長配列)\*\*と見なすが、グローバルスコープではVLAは禁止されている」という文法エラーを出しています。
#### 具体的には:
uint8t disk[_builtinalignup(…)];
は「`_builtinalignup` が定数式ならOK」ですが、定数式かどうかが曖昧な時点でエラーになるのです。
—
### ■ どうすべきか?
OpenBSD(やGCC系)での移植を考えるなら:
#### ✔ 対応策1:ポータブルなマクロで代替
#define alignup(value, align) (((value) + (align) - 1) & ~((align) - 1))
これは `_builtinalignup` の動作と同等で、すべてのCコンパイラで使えます。
#### ✔ 対応策2:コンパイル時定数を保証する
`DISKMAXSIZE` を以下のように書き換えると、定数式であることを保証できます。
#define DISKMAXSIZE ((128 * 1024 + PAGESIZE - 1) & ~(PAGESIZE - 1))
—
### ■ まとめ
項目 | Clang | GCC |
-------------------- | ------- | --------- |
`_builtinalignup` | あり(拡張) | なし(未定義) |
未宣言関数の扱い | エラー(厳密) | 警告(互換性重視) |
VLAのグローバルスコープ | 禁止 | 禁止(同じ) |
qemu.log
OSを実行すると、qemu.logに膨大なログが出力される。
riscv_cpu_do_interrupt: hart:0, async:0, cause:00000009, epc:0x80200af4, tval:0x00000000, desc=supervisor_ecall
epcを頼りにソースの行を求める。
vm$ riscv32-esp-elf-addr2line 0x80200af4 -e kernel.elf /tmp/risc-V/kernel.c:55
そして、参照。
__asm__ __volatile__("ecall" : "=r"(a0), "=r"(a1) : "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5)\ , "r"(a6), "r"(a7) : "memory");
tvalってのは、syscallのIDだな。キーボードからの入力をひたすら待っているのか。
-d
qemuログが色々な方面から可能である事を知った。インテルとかの糞石にもそれなりの ログが可能だけど、riscvを知った現在、古い石の勉強はもう無駄だ。
vm$ qemu-system-riscv32 -d help Log items (comma separated): out_asm show generated host assembly code for each compiled TB in_asm show target assembly code for each compiled TB op show micro ops for each compiled TB op_opt show micro ops after optimization op_ind show micro ops before indirect lowering int show interrupts/exceptions in short format exec show trace before each executed TB (lots of logs) cpu show CPU registers before entering a TB (lots of logs) fpu include FPU registers in the 'cpu' logging mmu log MMU-related activities pcall x86 only: show protected mode far calls/returns/exceptions cpu_reset show CPU state before CPU resets unimp log unimplemented functionality guest_errors log when the guest OS does something invalid (eg accessing a non-existent register) page dump pages at beginning of user mode emulation nochain do not chain compiled TBs so that "exec" and "cpu" show complete traces strace log every user-mode syscall, its input, and its result tid open a separate log file per thread; filename must contain '%d' vpu include VPU registers in the 'cpu' logging trace:PATTERN enable trace events Use "-d trace:help" to get a list of trace events.
qemu speed check
qemuの実行部分だけをqrun.shにして、それを3秒間だけ実行。出力されたログの 行数を計測してみる。簡易なスピード テストだな。まずはOpenBSD on VMWare
vm$ timeout 3 ./qrun.sh : file: hello.txt, size=19 > qemu-system-riscv32: terminating on signal 15 vm$ wc qemu.log 260932 1826524 29224414 qemu.log 261114 1827798 29244798 qemu.log 253115 1771805 28348910 qemu.log
こちらは、ネイティブなLubuntu。一回じゃあれなんで、3回測定。
sakae@lu:risc-V$ timeout 3 ./qrun.sh > qemu-system-riscv32: terminating on signal 15 from pid 4081 (timeout) sakae@lu:risc-V$ wc qemu.log 531113 3717791 59484647 qemu.log 526046 3682322 58917143 qemu.log 534228 3739596 59833527 qemu.log
i386 ネイティブなOpenBSDでも計測しとく。
102658 718606 11497726 qemu.log 105172 736204 11779294 qemu.log 111794 782558 12520958 qemu.log
MMU
アドレス変換も見ておく。起動したら、おもむろにCtl+a c するとモニターモードに 突入する。もう一度、Ctl+a c すると、OSの実行が継続される。当然ホストCPUの負荷 は上がる。上に見た様に割り込み処理に忙しいですから。
virtio-blk: capacity is 10240 bytes file: hello.txt, size=19 > QEMU 9.2.2 monitor - type 'help' for more information (qemu) stop (qemu) info registers : satp 80080259
下記が変換テーブルのダンプだ。
(qemu) info mem vaddr paddr size attr -------- ---------------- -------- ------- ffffffff ffffffffffffffff 00000000 ------- 01000000 000000008026c000 00001000 rwxu-a- 01001000 000000008026e000 0000f000 rwxu--- 01010000 000000008027d000 00001000 rwxu-ad 10001000 0000000010001000 00001000 rw----- 80200000 0000000080200000 00001000 rwx--a- 80201000 0000000080201000 00010000 rwx---- 80211000 0000000080211000 00001000 rwx--ad 80212000 0000000080212000 00001000 rwx---- 80213000 0000000080213000 00001000 rwx--a- : 83c00000 0000000083c00000 00400000 rwx---- 84000000 0000000084000000 00243000 rwx----
attrを見るとアクセスが有ったとか、書き換えられたとかが分る。本物のOSでは、 これらの情報を上手に利用してるんだな。
interrupt
RISC-V Platform-Level Interrupt Controller (PLIC)の制御方法について
CSRって単一なレジスターと思っていたけど、違うのね。レジスター群ってかバンク なんだな。
riscv OS
README
中学生からわかる現代天文学 なんて本を読んだ。ニュートン誌でも良く取り上げ られるので知ってるはずなんだけど。へぇーってのが出てきて面白い。 例えば星の成分はどうやって知るか? 余りに初歩的なんでニュートン誌では解説 されないのかな?
所どころに出てくるコラムが息抜きにピッタリ。末は博士か大臣かと珍重される 博士。240人に1人の割合で居るそうだ。ひょっとして弁護士より多いんではなかろうか?
学会発表で外国に行く事が多いそうだ。論文を読むだけじゃなくて、顔を突き会わ せて丁々発止とやるのが、何にも勝る事。Ruby会議と一緒だな。
学会発表は長い休みの時が多いそうだ(大学の先生が多いですからね)。家族同伴って のも多くて、遠足なんてのも企画されたりするそうだ。家族サービスしっかりやって 研究に励んで下さい。博士も大変だ脳。
オイラーも仙台に住んでいた時、地元のMacミーティングに女房を連れて行ったことが ある。1泊2日で、岩手の安比高原。現地集合現地解散。野郎共は、夜を徹っしてMac 談義。奥様連中は、温泉に入ったりで、まったりですよ。
記念品でMacSEの鋳型をしたペーパーウェイトを2個貰った。出席者全員への配布。 それが、まだ目の前に有るぞ。
件の本に難しい式が出てた。疑問が有るので聞いてみる。
Q: 天文学の本を読んでいたら、一般相対性理論で重力の正体が判明したって説明が ありました。
時空の歪みはエネルギーと等価。エネルギーは質量と等価。歪みこそが重力ですって 説明。有名な図で、地球が網の上に載ってて、網がへこんでいる。
網をプヨプヨなプリンとすれば、その上に載せたイチゴで、多少プリンがへこむ。 でも、イチゴよりもずっと重いパチンコ玉を載せたら、歪むなんてものじゃなくて 貫通しちゃいますよね。
実際そんな世界を想像すると、ブラックホールとかマルチパース宇宙なんてのが出て くるのかな。
時空の破壊って考えらるものなのでしょうか?
A: とても面白い疑問ですね。そして非常に本質的な問いでもあります。あなたの比喩(プリンとイチゴ、パチンコ玉)は非常にうまく時空の「歪み」とその限界を示しています。
—
### ■ 重力とは「歪み」そのもの
一般相対性理論では、\*\*重力とは「時空の歪み」\*\*そのものだと説明されます。エネルギーや質量があると、時空が歪む。その歪みに従って、他の物体が曲がった経路(=自由落下)を進む。これが「重力の正体」です。
—
### ■ ブラックホールは「時空の極限的な歪み」
パチンコ玉がプリンを突き破るというイメージ、とてもいいですね。まさにこれが**ブラックホール**です。
- 質量がある限界を超えると、\*\*重力による時空の歪みが極限まで達して「特異点」\*\*と呼ばれる場所ができます。
- 特異点では、**時空の曲率(歪み)が無限大**になると考えられます。
- ブラックホールの「事象の地平面」は、外の宇宙から見て、光ですら脱出できない境界。
—
### ■ 「時空の破壊」はあり得るのか?
#### ▶ 定義の問題
「破壊」と言う言葉が何を意味するかによります。
- 時空が計算不能・定義不能になる領域がある → はい、あります。これが「特異点」です。
- 時空そのものが消える/裂ける/終わる → 現代物理学では、確定的に「ある」とは言えませんが、可能性はあります。
—
### ■ いくつかの理論的可能性
#### 1. 特異点は「穴」ではなく「端」かもしれない
- 一般相対性理論では、特異点に到達すると数式が破綻します。
- つまり、**現在の理論の限界**であって、「何が起こるか」はわからない。
#### 2. 量子重力理論では回避される?
- ループ量子重力理論や弦理論では、特異点が「実は存在しない」とする説もあります。
- 代わりに、「バウンス(反跳)」のような現象で、ビッグバンのように新しい宇宙が生まれるという考え方(→「マルチバース」や「サイクル宇宙」)。
#### 3. ワームホール
- 一般相対性理論上の解の1つ。
- 十分に歪んだ時空が、「別の場所」や「別の宇宙」につながる可能性。
- ただし、ワームホールの安定性には「負のエネルギー」など現実には観測されていない条件が必要。
—
### ■ 宇宙の「外側」や「裂ける」とは?
時空が「破れる」や「裂ける」といった直感的な表現は、実際には非常に哲学的です。
- **時空とは中にあるものではなく、構造そのもの**です。
- だから「どこかに穴が空く」というよりは、「その場所の構造が意味を失う」という話です。
—
### ■ 結論:時空は破壊され得るのか?
理論的には、「時空が破壊される」ように見える現象はあり得ます。
- ブラックホール内の特異点
- 宇宙の始まり(ビッグバン)
- 時空が量子レベルで揺らぎ、別の宇宙とつながる仮説
しかし、**その先に何があるか、現在の物理学では答えが出ていません。**
Q: 時空を柔らかいプリンとして考えてましたけど、硬いビスケットとか餅でも比喩として 良い様にも思えます。 時空にこういう概念は有りますか?
A: とても鋭い観察です! 「時空=柔らかいプリン」という比喩は視覚的には便利ですが、それだけでは表現しきれない部分も確かにあります。 \*\*「硬さ」「柔らかさ」\*\*のような概念を、**時空の物理的性質**に結びつけようとする試みは、実際の理論物理の世界でも非常に重要なテーマです。
—
## 🔶 時空に「硬さ」や「柔らかさ」はあるのか?
### 結論からいうと:
> ✅ 時空に「硬さ」や「柔らかさ」に相当する物理的性質を与える理論は存在します。
ただし、「プリン」や「餅」のような**日常的な物質の硬さとはちょっと違う**形で現れます。以下に詳しく説明します。
—
## 🧠 1. 時空の「硬さ」=歪みに対する反応性
一般相対性理論では、時空は**エネルギーや質量によって曲がる/歪む**という性質を持っています。
- 小さな質量 → 少ししか歪まない → 「硬い」?
- 大きな質量 → 大きく歪む → 「柔らかい」?
実際には、\*\*この「歪みやすさ」\*\*は、**アインシュタイン方程式の構造**で決まっています。
アインシュタイン方程式:
\[ G_{\mu\nu} = \frac{8\pi G}{c^4} T_{\mu\nu} \]
ここで:
- $Tμν$:エネルギー運動量テンソル(=時空を歪める源)
- $Gμν$:時空の曲率
この比例係数 \(\frac{8\pi G}{c^4}\) が大きければ「時空は柔らかく」、小さければ「硬い」とも読めます(※あくまで比喩的に)。
—
## 🧬 2. 量子重力理論での「弾性」的な時空
弦理論やループ量子重力などの**量子重力理論**では、時空は連続体ではなく、\*\*構造を持った離散的なもの(量子幾何)\*\*と考えることもあります。
- たとえば「ループ量子重力」では、**空間はスピンネットワークという格子構造**を持ちます。
- これを「ビスケット状」「結晶状」「餅のように伸縮するネットワーク」などと比喩的に表現することも可能です。
—
## 🌀 3. 時空の「粘性」や「剛性」のような概念
近年では、以下のようなアイデアも研究されています。
### ◆ 有効場の理論での「時空の粘性」
- 一部のブラックホールや宇宙背景において、**時空が粘性を持つ流体のようにふるまう**モデルがあります。
- これは「アドS/CFT対応」と呼ばれる理論(ホログラフィー原理)から来ており、時空と熱力学的性質の対応が議論されています。
### ◆ 「弾性宇宙」モデル
- 一部の研究者は、**時空そのものを弾性体としてモデル化**しています。
- 圧力、剪断(シア)、歪みの伝播などを「時空そのもの」の特性として数式化。
- 宇宙の膨張が「弾性体の緩み」に相当する、と解釈する理論もあります。
—
## 🎨 あなたの比喩を整理すると:
比喩 | 時空に対応する概念 |
----- | ------------------------ |
プリン | 柔らかく連続的に変形。重力に従って滑らかに歪む。 |
ビスケット | 硬く割れやすい。ある条件で「裂ける」=特異点? |
餅 | 弾力があり伸び縮みする=量子的構造の比喩に近い |
—
## ✅ まとめ:時空にも「硬さ」や「柔らかさ」に相当する性質はある!
- 古典的には「歪みに対する反応性」
- 現代理論では「量子的構造」「弾性」「粘性」などの拡張された概念
- 日常的な比喩(プリン・餅・ビスケット)は実は**物理学者もよく使う手法**です
—
「重力」はこの宇宙がコンピューターシミュレーションだということの証拠だと物理学者が主張
こういう話なら夜を徹しって出来るぞ。これぐらいにしといたる。