カーネルモードとユーザーモード

ニーハオ、たけけんです。
今日も日本からお届けするよ。

今回からの参考書籍は基礎からわかるTCP/IPネットワーク実践プログラミングです。

だがしかし、前書きあたりにソースの再配布は禁止!と明確に書いてあるので、いつものようなソースを引用してのプログラム作成とかそのプログラムを公開とかするのはやめとこうと思います。

ほな、どないしはるんですか~?

ってところだが、本文中で気になったり、引っかかったキーワードをメモっといて、かたっぱしから調べたり、実際にテストして試したりしていこうと思います。
これなら引用でもなんでもないし、かなり勉強になるでしょう。
書籍はあくまでヒントとして使えるのだね。

いい考えだが、読み終わるまでどのくらいかかるのやらだ。

という事で始めの一歩っていうことでカーネルモードです。

カーネルモードとユーザモードの違いを簡単に説明する。
カーネルはカーネルモードで動作、アプリケーションプログラムはユーザモードで動作する。
非常にざっくりな説明だけど、十分な説明でもあります。

どう違うのかをこれから試していきます。
一番簡単な方法というと、ユーザモードではメモリ保護機能があるので、変なところに書き込みをしようとするとセグメントエラー!というのをプログラムを書く方はよく見かけるかと思いますが、それです。

一応検証したんですが、カーネルモードの検証がすごく長くなってしまったので、ユーザモードは端折ります。

ではでは、カーネルをさわるのでソースコードを取ってきましょう。

The Linux Kernel Archives
https://www.kernel.org/

こいつらに決めた!(古い)

https://www.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.32/linux-2.6.32.61.tar.xz
https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.2.59.tar.xz

・・・すったもんだで、カーネルの再構築もやり方も忘れちまいました。

なんとカーネル再構築 CentOSでググったらうちのブログがトップに出てくるよΣd(゚∀゚d)
だけど出てくるページはKVMの日記なので、検索語句とちょっと内容が合ってないのでは・・・

だけどGoogleにこれ違うんでない?なんてことは言わないよ。

本文に

カーネル再構築 CentOSという検索で来ている人がいらっしゃったら
こちらにどうぞ
Linuxのカーネルの再構築をやってみた

という一文を追加しておいた。ふふふ。

なんだか不思議な感じだけど、自分のサイトを参考に作業をしていく。
なにがあってもいいように、VMwareを使ってCentOSを1から構築。
1からといっても、minimalでインスコしてwget vim zsh gcc make xzを入れただけなので、ほんの数分の作業です。

# cd /usr/local/src                                                         [/root]
#                                                                  [/usr/local/src]
# wget https://www.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.32/linux-2.6.32.61.tar.xz

以前はtar.gzだったのが、xzになっていた。
2段階解凍をするよ。

# xz -dv linux-2.6.32.61.tar.xz                                    [/usr/local/src]
# ll                                                               [/usr/local/src]
合計 373924
-rw-r--r--. 1 root root 382894080  6月 10 23:13 2013 linux-2.6.32.61.tar
# tar -xvf linux-2.6.32.61.tar 
# cd linux-2.6.32.61                                               [/usr/local/src]
# pwd                                              [/usr/local/src/linux-2.6.32.61]
/usr/local/src/linux-2.6.32.61

おまけ
make menuconfig するならこいつが必要。
*** Install ncurses (ncurses-devel) and try again.

同じ轍は踏まないぞと、昔の自分のサイトで注意点を調べると

・容量が足りなくてmakeできなかった。
・makeで1時間くらいかかった。

ってとこぐらいかな。
まだまだ夜は長友な事だしゆっくりしとこう。
と思っていたが、長友が始まる前に寝てしまった。

起きたらエラーだった。orz

 

ところでコマンドのソースを探す方法だけど、こんな方法でもOKだ。

# grep -R sys_flock . | grep '\.c'
./fs/locks.c: * sys_flock: - flock() system call.
./kernel/sys_ni.c:cond_syscall(sys_flock);

 

日をまたぐのは久し振りですが、気を取り直して再開といきましょう。
ググっても良く分からんエラーなので、カーネルのバージョンを変えることにしました。

2.6系ではなく、次は3系です。
3系は問題なく起動しました。

# uname -r      [/root]
3.2.59

カーネルをいじったことは今までないので、まずはものまねからやろうと思います。

参考サイト
http://ruffnex.oc.to/kenji/

エコーサーバーからウェブサーバーを作ったときに、ずいぶんとお世話になったKenjiさんのサイトです。

内容はそのまんまなんで、実行結果だけ。
と思ったらコンパイルエラー

net/socket.c: In function ‘wizard_bible’:
net/socket.c:355: error: ‘struct proc_dir_entry’ has no member named ‘owner’

ポンづけの関数だし、問題の部分をコメントアウトするという安易なことをやってみる。
そしてリブート!

kernelh

Jesus!!

当然ながらコメントアウトじゃなくて正攻法で修正するしかないか。
エラー内容でググる。

参考サイト

brantyou的??
error: ‘struct proc_dir_entry’ has no member named ‘owner’的解决方法

中国語のフォントがないのでうまく表示できません。
すいません。対不起。

参考にしてヘッダーファイルを修正する。

# vi include/linux/proc_fs.h                    [/usr/local/src/linux-3.2.59]
struct proc_dir_entry構造体に
struct module *owner;を追加する。

んで、makeしたら、通ったようだ!!
ほっほーい。

# make install                                                                      [/usr/local/src/linux-3.2.59]
sh /usr/local/src/linux-3.2.59/arch/x86/boot/install.sh 3.2.59 arch/x86/boot/bzImage \
                System.map "/boot"

 

 

kernelh_1

JiSUS!

・・・仕方ないので、正攻法の正攻法で2.6系でがんばるぞな。

参考サイト

LKML.ORG

Re: Linux 2.6.32.61 – x86/ptrace/gcc 4.7 build error

この程度の内容で日本語のサイトは出てこないのか。
まあいい。

# make install                                                                                                                               [/usr/local/src/linux-2.6.32.61]
sh /usr/local/src/linux-2.6.32.61/arch/x86/boot/install.sh 2.6.32.61 arch/x86/boot/bzImage \
                System.map "/boot"

できた!!

リブート!

 

kernelh_2

JISUS!!!

 

はぁ・・・もうどれくらい歩いてきたのか。

思い出すたびに切なさ募りそうだから、めんどくさいが投げ出さないぞー。

 

リブート!!

・・・省略。

だめだ・・

もう何回目のリトライだろうか。
載せていないのも結構あるので、かなりの回数をやっちる。
ただちょこちょこソースをいじっているとちょっと慣れてきた感はある。

 

ソースを見ながら書いてみたら手ごたえがあったので、もう何回目のmakeか分からないけど、ちょっと自信ありげにやってみた。

# make install                                                        [/usr/local/src/linux-3.2.59]
sh /usr/local/src/linux-3.2.59/arch/x86/boot/install.sh 3.2.59 arch/x86/boot/bzImage \
                System.map "/boot"

問題なくコンパイルは成功して、リブート。

おおお、起動した!!

 

# ls /proc | grep wizard                                                    [/root]
wizard_bible

 

ぬおおおお!やっとできた!

[root@localhost]# echo TAKEKEN > /proc/wizard_bible                                         [/root]
[root@localhost]#                                                                           [/root]
[root@localhost]# cat /proc/wizard_bible                                                    [/root]
Hello TAKEKEN

[root@localhost]#                                                                           [/root]

・(((p(≧□≦)q)))・

く●長いmakeの時間に耐えてよく頑張った!感動した!!

 

では、参考サイトにwizard_bibleにはバッファオーバーフローの危険があるらしいと書いてあるとおりなので実際にやってみよう~。

[root@localhost]# echo TAKEKEN ~2000文字あるよ~ TAKEKEN > /proc/wizard_bible
[root@localhost]#                                                                           [/root]
[root@localhost]#                                                                           [/root]
[root@localhost]# cat /proc/wizard_bible                                                    [/root]

ちゅどーん。フリーズした。

コンソール画面。

kernelh_4

 

これが、メモリ保護がない場合のセグメントエラーだ。

Windows98とかはよくあった事だね。

rootだからと言っても、I/Oに命令したりするのはプログラムを通すわけだが、ユーザモードで動いているプログラムは全リソースにアクセスできるわけではなく制限されているのね。

だが、カーネルモードで動くプログラムはメモリ保護もなし、すべてのリソースへアクセスすることができる。

と言う感じです。

printfという関数で標準出力に文字を表示させるという事を、今回勉強した一連のことを踏まえて考えてみてもなかなか大変なもんだって事が分かりますですな。

 

Similar Posts:


Leave a Reply

Your email address will not be published. Required fields are marked *