オペレーティングシステム(OS)のカーネルが稼働しているアドレス空間のこと。
オペレーティングシステムにも様々なものがあるが、一般的なものは二つの「層」に分けることができる。
そのうち下位の層にあり、よりハードウェアに近い処理、機能を担うのがカーネルで、このカーネルが動作する層をカーネル空間と呼ぶ。
アドレス空間をどのように分けて扱うかは、OSごとに様々である。パーソナルコンピュータ用OSと、組み込み機器用OSとでは、かなり違うことが予想される。
ここでは、このうち組み込み用のものとし、SuperH用のNetBSDの実装を例とする。
SuperHでは、アドレス空間4Giバイトを二分割し、上位2Giバイトをユーザ空間、下位2Giバイトをカーネル空間とする。
SuperHの場合、0x00000000〜0x1fffffffの512Miバイト程度をよく用い、この中に様々なものが割り付けられる。この空間は、MMUの有無、キャッシュの有無等の各条件で、0x80000000〜0xdfffffffの範囲にもマッピングされている。
NetBSDの実装はこの特徴を用いており、下位の領域のうちストアキュー領域以外は特権モード以外では利用できないように設定し、ここをカーネル空間としている。
P3領域であれば、通常のP0/U0領域からのアクセスと何ら変わらない環境となり、またフラッシュメモリの書き換え処理のようにキャッシュがあっては邪魔な場合はP2領域にアクセスすれば良いことになる。
なお、物理的なメモリはユーザ領域、カーネル領域とも同じものであるので、この管理もCPUとOSがすることになる。
カーネル空間のプログラミングは、ユーザ空間とは異なっている。標準関数の一切は、基本的に利用できず、別途カーネル用の関数が用意される。
例えば、printfが使えないカーネルは多い。mallocも、一応使えるが引数などが全く違っている。
カーネル空間用のプログラムを書くときには、その作法を知らねばならない。
ユーザ空間から、カーネル空間に直接アクセスする術は無いのが一般的である。カーネル空間にアクセスすれば、通常はアドレスエラーが発生する。
そこで、カーネル空間にデバイスドライバ等を用意し、このデバイスを経由してカーネル空間にアクセスすることになる。
カーネル空間から、ユーザ空間に直接アクセスできるかどうかは実装による。カーネルそのものであれば特権があるためアクセスは自在であろうが、カーネル空間で動くデバイスドライバとなると、若干権限が落とされており、出来ないことが多いようである。
そこで、ユーザ空間の領域にアクセスするための関数が用意される。この仕様はOSごとに様々であり、互換性はない。
NetBSDでは、copy関数群、fetch関数群、store関数群という関数が用意されている。これらは、FreeBSDでも同様と思われる。
fetch/storeは、1バイト〜1ワードまでの単位でのアクセス手段を提供し、copy関数群はデータ列、文字列単位でのアクセス手段を提供する。
ユーザー空間とカーネル空間をまたぐ、memcpyやstrncpy相当の関数群である。
#include <sys/systm.h>
int copyin(const void *uaddr, void *kaddr, size_t len);
int copyout(const void *kaddr, void *uaddr, size_t len);
int copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done);
int copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done);
具体的な機能は次の通り。
ユーザー空間からカーネル空間にデータを取り込む関数群である。
#include <sys/types.h>
#include <sys/time.h>
#include <sys/systm.h>
#include <sys/resourcevar.h>
int fubyte(const void *base);
int fusword(void *base);
int fuswintr(void *base);
int fuword(const void *base);
具体的な機能は次の通り。
カーネル空間からユーザ空間にデータを格納する関数群である。
#include <sys/time.h>
#include <sys/systm.h>
#include <sys/resourcevar.h>
int subyte(void *base, int byte);
int susword(void *base, int word);
int suswintr(void *base, int word);
int suword(void *base, int word);
具体的な機能は次の通り。