SlideShare a Scribd company logo
1 of 33
Download to read offline
12ステップで作る組込みOS自作入門
      10thステップ




                @sandai
【参考書籍】
12ステップで作る組込みOS自作入門
【内容】
1ステップずつ、実際に動かしながらプログラムを発展さ
せていく方式で無理なく学べる。OSやハードウェアに詳
しくない方にも理解できるよう
に十分な説明を提供

坂井 弘亮(著)
カットシステム(2010/5)

【税込価格】
4,410円

【サポートページ】
http://kozos.jp/books/makeos/
もくじ
1.OSの役割
2.メモリ管理
3.メモリ管理実装
4.プログラムの実行
5.まとめ
1.OSの役割
コンピュータの3大要素
●   コンピュータの3大要素は以下の3つ
    –   CPU
    –   メモリ
    –   I/O
ノイマン型コンピュータ
●   プログラムをメモリ上に配置し、CPUがメモリ
    上のプログラムを逐次実行することで処理を進
    めていくコンピュータをノイマン型コンピュー
    タと呼ぶ
●   このようにCPUとメモリは必ず必須の要素であ
    り、処理の結果を出力したり入力を得るために
    はI/Oが必要
●   前のページで挙げた3つの要素を管理していく
    のがOSと言える
CPU時間
●   CPUを管理するというのは、つまり複数のタス
    クに対してCPUを割り当てる時間を配分すると
    いうこと
●   CPUをタスクに割り当てて処理している実行時
    間をCPU時間と呼ぶ
●   スレッドの目的はこのCPU時間を複数のタスク
    に自動で配分するため
●   スレッドを実装することでCPUが処理している
    のは自分だけであるかのように、独立してアプ
    リを書くことができる
2.メモリ管理
メモリの衝突
●   動作しているプログラムによってメモリを使い
    分けないと、複数のスレッドで同じアドレス位
    置のメモリを使ってしまう可能性が出てくる
    – メモリの値が衝突して正しく処理できない
●   そこでメモリのアドレスを管理しなくてはなら
    ない
●   メモリの管理には静的なメモリ管理(static)と
    動的なメモリ管理(dynamic)がある
静的なメモリ管理(static)
    メモリ領域を固定で割り当て、実行ファイルの
    作成時に配置を決めてしまうこと
●   たとえばリンカ・スクリプトを利用すること
    で、そのようにメモリ領域を固定で割り当てる
    ことができる
●   この方法は必要なときに獲得するとか不要に
    なったら解放するとか、解放された領域を使い
    まわすといったことができない
動的なメモリ管理(dynamic)
●   プログラムの動作中にメモリの獲得と解放を行
    うようなメモリ管理の仕方
●   メモリの獲得動作をアロケート、開放処理をフ
    リーと呼ぶ
●   動的なメモリ管理としては他にスタックがある
    が、階層的な構造で自由に獲得/解放は行えな
    い
メモリ保護
●   C言語の標準ライブラリにはmalloc()やfree()
    という関数があって、動的にメモリを獲得/解
    放することができる
●   メモリを勝手に使うのではなく、このような
    サービス関数を利用すれば衝突の問題はない
    –   関数内部でメモリ管理が行われるため
●   汎用OSでは複数のプログラムが互いに利用して
    いるメモリを破壊しないよう、それぞれメモリ
    保護する機能が必須
メモリ管理
●   メモリ管理には大きく次の2つに分けられる
    –   可変サイズのメモリ管理
    –   固定サイズのメモリ管理
●   可変サイズのメモリ管理はmalloc()で実装され
    ているメモリ管理方法
    –   自由なサイズのメモリを獲得することが可能
●   C言語でメモリを動的に利用するならmalloc()
    やfree()を利用するのが一般的である
malloc()でのメモリ管理
●   独自にmalloc()を実装するにはどうすべきか、
    malloc()と似た方法で可変サイズの領域を切り
    売りする方法を考えてみる
●   まず固定サイズの領域を確保
    –   char memory_area[128*1024]
●   固定サイズの領域を確保して、これを静的変数
    として可変サイズで利用する
    –   大きな枠を固定して、そのうちを可変で利用するっ
        て感じ
● malloc()で可変サイズのメモリ領域を獲得する
  ときは、memory_area[]から切り出す
● 切り出し用のメモリはメモリ・プールと呼ぶ
可変サイズでのメモリ管理1
●   メモリ管理の方法として、小さいアドレスから
    順に切り出していく方法で考えてみる
●   このような管理方法だと各領域
    をfree()で解放しても再利用で
    きない               10
    –   そもそも領域のサイズをデー
        タとして持っていないので    15
        free()は使えない
                        10
●   メモリ領域をたんに切り出して
    分け与えるような方法ではうま
                        20
    くいかない
可変サイズでのメモリ管理2
●   そこで、領域のサイズや獲得済み・      ヘッダ

    解放済みなどの情報をヘッダとして      10
    領域の先頭に付加させてみる         ヘッダ
●   領域の獲得時はヘッダにサイズなど      15
    の情報を書き込み、ヘッダの直後
                          ヘッダ
    にある実際の利用領域の先頭アドレ      10
    スを返す                  ヘッダ
●   解放時には、free()の引数として与
    えられた領域から逆算すれば、ヘッ      20
    ダの位置を知ることができる
●   が、これだとまだ小さいアドレスか
    ら順に切り出すしか方法がない
可変サイズでのメモリ管理3
●   そこでnextポインタをヘッダに持たせて獲得し
    た領域と解放した領域をリンクリスト管理する
●   こうすることで、解放後     ヘッダ
    の領域の検索が可能のな      10
    るため、再利用すること     ヘッダ
    ができる             15
●   malloc()するときには、
    まず解放済みのリンクリ     ヘッダ
                     10
    ストを検索して、無けれ            NULL
                    ヘッダ
    ばメモリ・プールから切
    り出すといったことがで      20    NULL
    きるようになる
可変サイズでのメモリ管理4
●   今回の例はnextポインタによる片方向リンク
    だったが、実践的にはnextポインタとは逆方向
    の前方ポインタも持たせる
    –   リンクリストの途中からの抜き出しなどのため
    –   前方ポインタはprevと使うことが多い
●   nextとprevの両方を持つリンクリストを双方向
    ンクと呼ぶ
●   双方向リンクで管理された可変サイズのメモリ
    領域を一般にヒープ領域と呼ぶ
可変サイズでのメモリ管理5
●   実際には、この他に解放済み領域を再割当てす
    る際にも必要サイズを切り出したり、隣接する
    解放済み領域の統合や、メモリ・プールも解放
    済みのリンクリストにつなげたりする
●   リンクリスト管理の欠点としては、獲得と解放
    を繰り返すうちにメモリが細分化されすぎてす
    まうこと
    –   フラグメンテーションと呼ぶ
●   とりあえず、今のとこはリンクリスト管理する
    ことで、可変サイズのメモリの割り当てと解放
    ができる、と理解しておけばよい
可変サイズでの管理の欠点
●   リンクリスト管理する場合、メモリ獲得時に検
    索処理が必要となる
●   検索で見つかるまでの時間がどれぐらいかかる
    か、保証ができない
    –   リアルタイムOSだとこれは致命的
●   たとえリアルタイム性を求めないにしても、組
    込み処理では検索のような時間のかかる処理は
    適切でない
●   動的にメモリを管理する場合、可変サイズは使
    用効率は良いが向いていない
固定サイズでの管理
●   そこで固定サイズでのメモリ管理を行う
●   最初からいくつかサイズに分けたメモリ領域を
    確保し、メモリ領域の獲得時には必要とされる
    サイズが入りきる固定領域を与えるようにする
    –   10バイトの領域が必要なら16バイド領域、40バイト
        の領域が必要なら128バイトを与える形式
●   メモリ・プールの未獲得領域はサイズごとにリ
    ンクリストにして管理する
●   メモリ獲得時にはリンクリストの先頭の領域を
    割り当て、解放された領域は再びリンクリスト
    に接続する
    –   メモリ使用効率は悪いが、検索するよりリアルタイ
        ム性は確保できる
3.メモリ管理の実装
プログラムの修正と追加
●   追加ファイル
    –   memory.h,memory.c...メモリ管理ライブラリ
    –   test10_1.c...メモリ管理サンプル
●   修正ファイル
    –   ld.scr...メモリ・プール追加
    –   syscall.h,syscall.c...システム・コール追加
    –   kozos.h,kozos.c...システム・コール追加
    –   main.c...起動するスレッドを修正
    –   Makefile
プログラムの修正内容
●   メモリ管理を実装
    –   自由に使っていいメモリの領域(メモリ・プール)を
        用意して、必要になったらそこから切り出して使え
        るようにしている
    –   再利用しやすいように、メモリ管理はリンクリスト
        管理で行う
    –   事前に16バイト、32バイト、64バイトずつに分けて
        おいた領域をそれぞれいくつか用意し、ヘッダを付
        けて片方向リンクでつなげる
kzmem_init_pool()
static int kzmem_init_pool(kzmem_pool *p)
{
    int i;
    kzmem_block *mp;
    kzmem_block **mpp;
    extern char freearea;
    static char *area = &freearea;

    mp = (kzmem_block *)area;

    mpp = &p->free;
    for(i = 0; i < p->num; i++) {
        *mpp = mp;
        memset(mp, 0, sizeof(*mp));
        mp->size = p->size;
        mpp = &(mp->next);
        mp = (kzmem_block *)((char *)mp + p->size);
        area += p->size;
    }

    return 0;
}
メモリ・プールの初期化の流れ1
●   mp = (kzmem_block *)areaでkzmem_block構造
    体をarea番地に作成しmpに代入
●   mpp = &p->freeは、freeポインタはメモリ・
    プールの先頭にあたる。メモリを獲得するとき
    はここからバイト別に合わせて取得するように
    なる。mppにはその先頭アドレスを代入
●   次にfor文があるが、ここはメモリブロックを
    作成しつつnextポインタをつなげている処理
    –   mmpダブルポインタを利用しているため複雑に感じ
        るが、ポインタを理解してさえいればどうなってい
        るか分かる
メモリ・プールの初期化の流れ2
●   最初の*mpp = mpは&p->free = mpと同じこと
     – for文の2週目からはmp->next = mpと同じ
●   memset()で0クリアして、mp->sizeにブロック
    の大きさを代入
●   mpp = &(mp->next)で次のmpのnextポインタに
    進む
●     mp = (kzmem_block *)((char *)mp + p-
    >size)で新しいkzmem_block構造体を定義
●   area += p->sizeは今回のプログラムでは関係
    がないけれど、他のメモリ・プール初期化関数
    がある場合にはこうして未使用領域の先頭を保
    持しておく必要がある
メモリの獲得と解放
●   獲得
    – 必要なサイズに収まるメモリブロックを探し
      て、先頭のブロックを引き抜くだけ
    – return mp + 1のように、メモリヘッダの後
      続のデータ領域を渡すようにする
●   解放
    – 解放というか、使っているメモリブロックを
      リンクリストの先頭に戻すだけみたい
    – ゼロクリアとかしてないけど、要らないのか
      な
メモリブロックの大きさ
●   今回のプログラムでは16バイト、32バイト、64
    バイトのメモリブロックをそれぞれ別々にリン
    クして複数個作っている
●   16バイトのうち、8バイトはメモリヘッダなの
    で、16バイトのブロックは実質8バイトしか使
    えないし、64バイトでも実質56バイトしかつか
    えない
●   書籍では大きく取り上げていないけれど(さ
    らっと書いてる)、そういうわけなので、実質
    的なデータ領域がいくつかということは把握し
    ておこう
4.プログラムの実行
プログラム実行
/Users/sandai/12step/src/10/os% sudo cu -l /dev/tty.usbserial-FTG6PQ4H
.
.
00ffd178 aaa
00ffd188 bbb
00ffd188 aaaaaaa
00ffd178 bbbbbbb
00ffd1f8 aaaaaaaaaaa
00ffd218 bbbbbbbbbbb
00ffd218 aaaaaaaaaaaaaaa
00ffd1f8 bbbbbbbbbbbbbbb
00ffd1f8 aaaaaaaaaaaaaaaaaaa
.
.
.
00ffd338 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
00ffd2f8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
00ffd2f8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
00ffd338 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
00ffd338 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
00ffd2f8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
test10_1 exit.
test10_1 EXIT.
5.まとめ
まとめ
●   簡単なメモリ管理を実装した
●   他にもいくつか手段があるが、考え方は似たよ
    うなものらしいので、きっちり理解しておきた
    い部分
●   ダブルポインタに苦戦した。なんとなくポイン
    タ理解してるぐらいじゃだめだ。理解したらほ
    んと単純なものなんだけど

More Related Content

Viewers also liked

QEMUでARM64bitベアメタルプログラミング
QEMUでARM64bitベアメタルプログラミングQEMUでARM64bitベアメタルプログラミング
QEMUでARM64bitベアメタルプログラミングYuma Ohgami
 
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくばHirotaka Kawata
 
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -Kishi Shundo
 
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)kozossakai
 
【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門sandai
 
やってよかったOS作り
やってよかったOS作りやってよかったOS作り
やってよかったOS作りHidemi Kawai
 
低レイヤー入門
低レイヤー入門低レイヤー入門
低レイヤー入門demuyan
 
ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門Hirotaka Kawata
 
【2000行弱!】x86用自作カーネルの紹介
【2000行弱!】x86用自作カーネルの紹介【2000行弱!】x86用自作カーネルの紹介
【2000行弱!】x86用自作カーネルの紹介Yuma Ohgami
 
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめ
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめWeb系だって低レイヤーがやりたいんだよ! コンパイラことはじめ
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめNisei Kimura
 
C++でできる!OS自作入門
C++でできる!OS自作入門C++でできる!OS自作入門
C++でできる!OS自作入門uchan_nos
 
Ctfのためのpython入門
Ctfのためのpython入門Ctfのためのpython入門
Ctfのためのpython入門shiracamus
 
ハッキング実演
ハッキング実演ハッキング実演
ハッキング実演Ken Ogura
 
CTF超入門 (for 第12回セキュリティさくら)
CTF超入門 (for 第12回セキュリティさくら)CTF超入門 (for 第12回セキュリティさくら)
CTF超入門 (for 第12回セキュリティさくら)kikuchan98
 

Viewers also liked (15)

QEMUでARM64bitベアメタルプログラミング
QEMUでARM64bitベアメタルプログラミングQEMUでARM64bitベアメタルプログラミング
QEMUでARM64bitベアメタルプログラミング
 
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
30日でできない!コンピューター自作入門 - カーネル/VM探検隊@つくば
 
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
組み込み向けC++のやり方を探る - mbedで楽しい組み込みプログラミング -
 
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)
組込みOSを作ってみよう!(オープンソースカンファレンス内セミナー資料)
 
【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門
 
やってよかったOS作り
やってよかったOS作りやってよかったOS作り
やってよかったOS作り
 
低レイヤー入門
低レイヤー入門低レイヤー入門
低レイヤー入門
 
人工知能概論 1
人工知能概論 1人工知能概論 1
人工知能概論 1
 
ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門ゼロから始める自作 CPU 入門
ゼロから始める自作 CPU 入門
 
【2000行弱!】x86用自作カーネルの紹介
【2000行弱!】x86用自作カーネルの紹介【2000行弱!】x86用自作カーネルの紹介
【2000行弱!】x86用自作カーネルの紹介
 
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめ
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめWeb系だって低レイヤーがやりたいんだよ! コンパイラことはじめ
Web系だって低レイヤーがやりたいんだよ! コンパイラことはじめ
 
C++でできる!OS自作入門
C++でできる!OS自作入門C++でできる!OS自作入門
C++でできる!OS自作入門
 
Ctfのためのpython入門
Ctfのためのpython入門Ctfのためのpython入門
Ctfのためのpython入門
 
ハッキング実演
ハッキング実演ハッキング実演
ハッキング実演
 
CTF超入門 (for 第12回セキュリティさくら)
CTF超入門 (for 第12回セキュリティさくら)CTF超入門 (for 第12回セキュリティさくら)
CTF超入門 (for 第12回セキュリティさくら)
 

Recently uploaded

新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Gamesatsushi061452
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsWSO2
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptxsn679259
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイスCRI Japan, Inc.
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video UnderstandingToru Tamaki
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...Toru Tamaki
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルCRI Japan, Inc.
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 

Recently uploaded (10)

新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 

【学習メモ#10th】12ステップで作る組込みOS自作入門

  • 5. コンピュータの3大要素 ● コンピュータの3大要素は以下の3つ – CPU – メモリ – I/O
  • 6. ノイマン型コンピュータ ● プログラムをメモリ上に配置し、CPUがメモリ 上のプログラムを逐次実行することで処理を進 めていくコンピュータをノイマン型コンピュー タと呼ぶ ● このようにCPUとメモリは必ず必須の要素であ り、処理の結果を出力したり入力を得るために はI/Oが必要 ● 前のページで挙げた3つの要素を管理していく のがOSと言える
  • 7. CPU時間 ● CPUを管理するというのは、つまり複数のタス クに対してCPUを割り当てる時間を配分すると いうこと ● CPUをタスクに割り当てて処理している実行時 間をCPU時間と呼ぶ ● スレッドの目的はこのCPU時間を複数のタスク に自動で配分するため ● スレッドを実装することでCPUが処理している のは自分だけであるかのように、独立してアプ リを書くことができる
  • 9. メモリの衝突 ● 動作しているプログラムによってメモリを使い 分けないと、複数のスレッドで同じアドレス位 置のメモリを使ってしまう可能性が出てくる – メモリの値が衝突して正しく処理できない ● そこでメモリのアドレスを管理しなくてはなら ない ● メモリの管理には静的なメモリ管理(static)と 動的なメモリ管理(dynamic)がある
  • 10. 静的なメモリ管理(static) メモリ領域を固定で割り当て、実行ファイルの 作成時に配置を決めてしまうこと ● たとえばリンカ・スクリプトを利用すること で、そのようにメモリ領域を固定で割り当てる ことができる ● この方法は必要なときに獲得するとか不要に なったら解放するとか、解放された領域を使い まわすといったことができない
  • 11. 動的なメモリ管理(dynamic) ● プログラムの動作中にメモリの獲得と解放を行 うようなメモリ管理の仕方 ● メモリの獲得動作をアロケート、開放処理をフ リーと呼ぶ ● 動的なメモリ管理としては他にスタックがある が、階層的な構造で自由に獲得/解放は行えな い
  • 12. メモリ保護 ● C言語の標準ライブラリにはmalloc()やfree() という関数があって、動的にメモリを獲得/解 放することができる ● メモリを勝手に使うのではなく、このような サービス関数を利用すれば衝突の問題はない – 関数内部でメモリ管理が行われるため ● 汎用OSでは複数のプログラムが互いに利用して いるメモリを破壊しないよう、それぞれメモリ 保護する機能が必須
  • 13. メモリ管理 ● メモリ管理には大きく次の2つに分けられる – 可変サイズのメモリ管理 – 固定サイズのメモリ管理 ● 可変サイズのメモリ管理はmalloc()で実装され ているメモリ管理方法 – 自由なサイズのメモリを獲得することが可能 ● C言語でメモリを動的に利用するならmalloc() やfree()を利用するのが一般的である
  • 14. malloc()でのメモリ管理 ● 独自にmalloc()を実装するにはどうすべきか、 malloc()と似た方法で可変サイズの領域を切り 売りする方法を考えてみる ● まず固定サイズの領域を確保 – char memory_area[128*1024] ● 固定サイズの領域を確保して、これを静的変数 として可変サイズで利用する – 大きな枠を固定して、そのうちを可変で利用するっ て感じ ● malloc()で可変サイズのメモリ領域を獲得する ときは、memory_area[]から切り出す ● 切り出し用のメモリはメモリ・プールと呼ぶ
  • 15. 可変サイズでのメモリ管理1 ● メモリ管理の方法として、小さいアドレスから 順に切り出していく方法で考えてみる ● このような管理方法だと各領域 をfree()で解放しても再利用で きない 10 – そもそも領域のサイズをデー タとして持っていないので 15 free()は使えない 10 ● メモリ領域をたんに切り出して 分け与えるような方法ではうま 20 くいかない
  • 16. 可変サイズでのメモリ管理2 ● そこで、領域のサイズや獲得済み・ ヘッダ 解放済みなどの情報をヘッダとして 10 領域の先頭に付加させてみる ヘッダ ● 領域の獲得時はヘッダにサイズなど 15 の情報を書き込み、ヘッダの直後 ヘッダ にある実際の利用領域の先頭アドレ 10 スを返す ヘッダ ● 解放時には、free()の引数として与 えられた領域から逆算すれば、ヘッ 20 ダの位置を知ることができる ● が、これだとまだ小さいアドレスか ら順に切り出すしか方法がない
  • 17. 可変サイズでのメモリ管理3 ● そこでnextポインタをヘッダに持たせて獲得し た領域と解放した領域をリンクリスト管理する ● こうすることで、解放後 ヘッダ の領域の検索が可能のな 10 るため、再利用すること ヘッダ ができる 15 ● malloc()するときには、 まず解放済みのリンクリ ヘッダ 10 ストを検索して、無けれ NULL ヘッダ ばメモリ・プールから切 り出すといったことがで 20 NULL きるようになる
  • 18. 可変サイズでのメモリ管理4 ● 今回の例はnextポインタによる片方向リンク だったが、実践的にはnextポインタとは逆方向 の前方ポインタも持たせる – リンクリストの途中からの抜き出しなどのため – 前方ポインタはprevと使うことが多い ● nextとprevの両方を持つリンクリストを双方向 ンクと呼ぶ ● 双方向リンクで管理された可変サイズのメモリ 領域を一般にヒープ領域と呼ぶ
  • 19. 可変サイズでのメモリ管理5 ● 実際には、この他に解放済み領域を再割当てす る際にも必要サイズを切り出したり、隣接する 解放済み領域の統合や、メモリ・プールも解放 済みのリンクリストにつなげたりする ● リンクリスト管理の欠点としては、獲得と解放 を繰り返すうちにメモリが細分化されすぎてす まうこと – フラグメンテーションと呼ぶ ● とりあえず、今のとこはリンクリスト管理する ことで、可変サイズのメモリの割り当てと解放 ができる、と理解しておけばよい
  • 20. 可変サイズでの管理の欠点 ● リンクリスト管理する場合、メモリ獲得時に検 索処理が必要となる ● 検索で見つかるまでの時間がどれぐらいかかる か、保証ができない – リアルタイムOSだとこれは致命的 ● たとえリアルタイム性を求めないにしても、組 込み処理では検索のような時間のかかる処理は 適切でない ● 動的にメモリを管理する場合、可変サイズは使 用効率は良いが向いていない
  • 21. 固定サイズでの管理 ● そこで固定サイズでのメモリ管理を行う ● 最初からいくつかサイズに分けたメモリ領域を 確保し、メモリ領域の獲得時には必要とされる サイズが入りきる固定領域を与えるようにする – 10バイトの領域が必要なら16バイド領域、40バイト の領域が必要なら128バイトを与える形式 ● メモリ・プールの未獲得領域はサイズごとにリ ンクリストにして管理する ● メモリ獲得時にはリンクリストの先頭の領域を 割り当て、解放された領域は再びリンクリスト に接続する – メモリ使用効率は悪いが、検索するよりリアルタイ ム性は確保できる
  • 23. プログラムの修正と追加 ● 追加ファイル – memory.h,memory.c...メモリ管理ライブラリ – test10_1.c...メモリ管理サンプル ● 修正ファイル – ld.scr...メモリ・プール追加 – syscall.h,syscall.c...システム・コール追加 – kozos.h,kozos.c...システム・コール追加 – main.c...起動するスレッドを修正 – Makefile
  • 24. プログラムの修正内容 ● メモリ管理を実装 – 自由に使っていいメモリの領域(メモリ・プール)を 用意して、必要になったらそこから切り出して使え るようにしている – 再利用しやすいように、メモリ管理はリンクリスト 管理で行う – 事前に16バイト、32バイト、64バイトずつに分けて おいた領域をそれぞれいくつか用意し、ヘッダを付 けて片方向リンクでつなげる
  • 25. kzmem_init_pool() static int kzmem_init_pool(kzmem_pool *p) { int i; kzmem_block *mp; kzmem_block **mpp; extern char freearea; static char *area = &freearea; mp = (kzmem_block *)area; mpp = &p->free; for(i = 0; i < p->num; i++) { *mpp = mp; memset(mp, 0, sizeof(*mp)); mp->size = p->size; mpp = &(mp->next); mp = (kzmem_block *)((char *)mp + p->size); area += p->size; } return 0; }
  • 26. メモリ・プールの初期化の流れ1 ● mp = (kzmem_block *)areaでkzmem_block構造 体をarea番地に作成しmpに代入 ● mpp = &p->freeは、freeポインタはメモリ・ プールの先頭にあたる。メモリを獲得するとき はここからバイト別に合わせて取得するように なる。mppにはその先頭アドレスを代入 ● 次にfor文があるが、ここはメモリブロックを 作成しつつnextポインタをつなげている処理 – mmpダブルポインタを利用しているため複雑に感じ るが、ポインタを理解してさえいればどうなってい るか分かる
  • 27. メモリ・プールの初期化の流れ2 ● 最初の*mpp = mpは&p->free = mpと同じこと – for文の2週目からはmp->next = mpと同じ ● memset()で0クリアして、mp->sizeにブロック の大きさを代入 ● mpp = &(mp->next)で次のmpのnextポインタに 進む ● mp = (kzmem_block *)((char *)mp + p- >size)で新しいkzmem_block構造体を定義 ● area += p->sizeは今回のプログラムでは関係 がないけれど、他のメモリ・プール初期化関数 がある場合にはこうして未使用領域の先頭を保 持しておく必要がある
  • 28. メモリの獲得と解放 ● 獲得 – 必要なサイズに収まるメモリブロックを探し て、先頭のブロックを引き抜くだけ – return mp + 1のように、メモリヘッダの後 続のデータ領域を渡すようにする ● 解放 – 解放というか、使っているメモリブロックを リンクリストの先頭に戻すだけみたい – ゼロクリアとかしてないけど、要らないのか な
  • 29. メモリブロックの大きさ ● 今回のプログラムでは16バイト、32バイト、64 バイトのメモリブロックをそれぞれ別々にリン クして複数個作っている ● 16バイトのうち、8バイトはメモリヘッダなの で、16バイトのブロックは実質8バイトしか使 えないし、64バイトでも実質56バイトしかつか えない ● 書籍では大きく取り上げていないけれど(さ らっと書いてる)、そういうわけなので、実質 的なデータ領域がいくつかということは把握し ておこう
  • 31. プログラム実行 /Users/sandai/12step/src/10/os% sudo cu -l /dev/tty.usbserial-FTG6PQ4H . . 00ffd178 aaa 00ffd188 bbb 00ffd188 aaaaaaa 00ffd178 bbbbbbb 00ffd1f8 aaaaaaaaaaa 00ffd218 bbbbbbbbbbb 00ffd218 aaaaaaaaaaaaaaa 00ffd1f8 bbbbbbbbbbbbbbb 00ffd1f8 aaaaaaaaaaaaaaaaaaa . . . 00ffd338 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 00ffd2f8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 00ffd2f8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 00ffd338 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 00ffd338 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 00ffd2f8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb test10_1 exit. test10_1 EXIT.
  • 33. まとめ ● 簡単なメモリ管理を実装した ● 他にもいくつか手段があるが、考え方は似たよ うなものらしいので、きっちり理解しておきた い部分 ● ダブルポインタに苦戦した。なんとなくポイン タ理解してるぐらいじゃだめだ。理解したらほ んと単純なものなんだけど