コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2015年10月10日 >>> 2015年9月27日
link もっと後

2015年10月10日

Linuxデバイスドライバを組み込んだときの初期化順序

目次: Linux

Linux用のデバイスドライバを書くときはmodule_init(関数名) と書いて、初期化関数を指定します。

ドライバをカーネルモジュール(*.ko)としてビルドしたときは、insmodした時に初期化関数が実行されます。これは想像に難くないですし、初期化関数にprintkでも入れておけば簡単に確認できます。

では…、ドライバをLinuxカーネルに組み込んだ時は、一体いつ初期化処理が実行されるのでしょうか?Linuxには他のドライバも含まれていますが、実行される順序に決まりはあるでしょうか?

わたくし恥ずかしながら、この辺の仕組みを全く理解していなかったので、コードを調べてみました。既に同じような事を調べている人がいる気がしてなりませんが…まあ良いや。

Linuxの初期化関数

Linuxの初期化は、linux/init/main.cのstart_kernel() から始まります。start_kernel() は山のように初期化を実行していますが、我らがmodule_init() の実行に関係しているのは下記の部分です。

Linuxのエントリ関数から、ドライバの初期化関数まで、その1

start_kernel()
  rest_init()
    kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);

ここでカーネルスレッドが作成され、スレッドのエントリ関数はkernel_init() です。で、続けて追いかけます。

Linuxのエントリ関数から、ドライバの初期化関数まで、その2

kernel_init()
  kernel_init_freeable()
    do_basic_setup()
      do_initcalls()
        do_initcall_level()
          do_one_initcall()
            initcall_levels[level][n]()

このような順で呼ばれます。このinitcall_levelsが今回の話のキモとなります。initcall_levelsは下記のように定義されています。

ドライバの初期化関数群

typedef int (*initcall_t)(void);

extern initcall_t __initcall_start[];
extern initcall_t __initcall0_start[];
extern initcall_t __initcall1_start[];
extern initcall_t __initcall2_start[];
extern initcall_t __initcall3_start[];
extern initcall_t __initcall4_start[];
extern initcall_t __initcall5_start[];
extern initcall_t __initcall6_start[];
extern initcall_t __initcall7_start[];
extern initcall_t __initcall_end[];

static initcall_t *initcall_levels[] __initdata = {
        __initcall0_start,
        __initcall1_start,
        __initcall2_start,
        __initcall3_start,
        __initcall4_start,
        __initcall5_start,
        __initcall6_start,
        __initcall7_start,
        __initcall_end,
};

コードを見る限り、二重配列 __initcall_levelsは __initcalln_startという配列を要素として持っていること、__initcall0_start[0], __initcall0_start[1], __initcall0_start[2], ... の順に関数ポインタが先に呼び出され、その後も同様に __initcall1_start, __initcall2_start, ... と続いて __initcall7_startに入っている関数ポインタは後に呼び出されることがわかります。

しかし肝心の __initcall0_startに何の関数ポインタが入るのか?はわかりません。それもそのはず、実はCのコード上に、これら __initcallx_start配列の定義はありません。別の方法で定義されているのです。

この __initcall0_start〜 __initcall7_start配列は、あるマクロで宣言された初期化関数のポインタを全て持つ配列となります。対応関係は下記の通りです。

  • __initcall0_start: pure_initcall()
  • __initcall1_start: core_initcall()
  • __initcall2_start: postcore_initcall()
  • __initcall3_start: arch_initcall()
  • __initcall4_start: subsys_initcall()
  • __initcall5_start: fs_initcall()
  • __initcall6_start: device_initcall()
  • __initcall7_start: late_initcall()

なぜそうなるか?は後述しますので、とりあえずこんな関係があることだけ頭の隅に置いてください。

おまじないmodule_init() の正体

カーネルモジュールを作るとき、初期化関数を指定するためのおまじないとしてmodule_init(funcname) と書きますが、これは実はマクロでlinux/include/linux/module.hにて、下記のように定義されています。

module_init() マクロの定義

/**
 * module_init() - driver initialization entry point
 * @x: function to be run at kernel boot time or module insertion
 *
 * module_init() will either be called during do_initcalls() (if
 * builtin) or at module insertion time (if a module).  There can only
 * be one per module.
 */
#define module_init(x)  __initcall(x);

#define __initcall(fn) device_initcall(fn)

#define device_initcall(fn)             __define_initcall(fn, 6)

マクロの定義はmodule_init = __initcall = device_initcallとなっていますので、module_init(funcname) はdevice_initcall(funcname) と書くのと同じです。

最後にmodule_init(funcname) は __define_init(funcname, 6) と定義されています。これもマクロでlinux/include/linux/init.hに下記のように定義されています。

__define_init() マクロの定義

#define __define_initcall(fn, id) \r        static initcall_t __initcall_##fn##id __used \
        __attribute__((__section__(".initcall" #id ".init"))) = fn

何だか小難しいですが、簡単に言うとmodule_init(funcname) つまり __define_initcall(funcname, 6) と書いたら、初期化関数funcnameのポインタを値に持つ __initcall_funcname6という名前の変数を宣言し、セクション .initcall6.initに置け、という意味になります。

その変な名前の変数がどこに置かれるのか?は、リンカスクリプトlinux/arch/arm/kernel/vmlinux.ldsに書いてあります。全部は載せられませんので .initcall6.initセクションに言及しているところを見てみます。

リンカスクリプトと __initcall_funcname6の行き先

 .init.data : {
    *(.init.data) *(.meminit.data) *(.init.rodata) *(.meminit.rodata) . = ALIGN(8);
    __clk_of_table = .;
    *(__clk_of_table) *(__clk_of_table_end) . = ALIGN(32);
    __dtb_start = .;
    *(.dtb.init.rodata) __dtb_end = .;
    . = ALIGN(16);
    __setup_start = .;
    *(.init.setup) __setup_end = .;
    __initcall_start = .;
    *(.initcallearly.init) __initcall0_start = .;
    *(.initcall0.init) *(.initcall0s.init) __initcall1_start = .;
    *(.initcall1.init) *(.initcall1s.init) __initcall2_start = .;
    *(.initcall2.init) *(.initcall2s.init) __initcall3_start = .;
    *(.initcall3.init) *(.initcall3s.init) __initcall4_start = .;
    *(.initcall4.init) *(.initcall4s.init) __initcall5_start = .;
    *(.initcall5.init) *(.initcall5s.init) __initcallrootfs_start = .;
    *(.initcallrootfs.init) *(.initcallrootfss.init) __initcall6_start = .;
    *(.initcall6.init) *(.initcall6s.init) __initcall7_start = .; ★★これ★★
    *(.initcall7.init) *(.initcall7s.init) __initcall_end = .;
    __con_initcall_start = .;
    *(.con_initcall.init) __con_initcall_end = .;
    __security_initcall_start = .;
    security_initcall.init) __security_initcall_end = .;
    ...

※本来は改行が入っていませんが、見やすいように適宜改行を入れています。

私はリンカスクリプトに明るくないので、間違っていたらごめんなさいですが、基本的には書いた順でシンボル(変数や関数など)をオブジェクトファイル内に並べてくれる、という理解でこの辺りは大丈夫なはずです。

先ほどの __define_initcall() マクロの定義から __initcall_funcname6変数は、コンパイラが .initcall6.initというセクションに入れて、オブジェクトファイルを生成します。わかりにくいと思うので、例で説明します。

例えば、リンカが今までシンボルを並べてきた結果、現在のアドレスが0x10000になっていたとします。あと .initcall6.initセクションには __initcall_funcname6と __initcall_func2name6の2つのシンボルが含まれているとします。

リンカはまず「__initcall6_start = .;」を見て、現在のアドレス(ドットは現在のアドレスを表す)に0x10000: __initcall6_startを定義します。現在のアドレスは変わりません。

次に「*(.initcall6.init)」を見て、全オブジェクトファイルの .initcall6.initのシンボルを順番に並べ、現在のアドレスを進めます。つまり0x10000: __initcall_funcname6, 0x10004: __initcall_func2name6が並び、現在のアドレスは0x10008になります。「*(.initcall6s.init)」も同様ですが、何もシンボルが入っていないのでスルーします。

最後に「__initcall7_start = .;」を見て、0x10008: __initcall7_startを定義します。

すなわち下記のようなアドレス、シンボルの関係になります。

- Linuxカーネル
  - セクションA
  - セクションB
  - セクション .init.data
      - ...
      - 0x10000: __initcall6_start
      - .initcall6.init内の全シンボル
        (内訳)
        - 0x10000: __initcall_funcname6  = funcname() のポインタ
        - 0x10004: __initcall_func2name6 = func2name() のポインタ
      - 0x10008: .initcall6s.init内の全シンボル
      - __initcall7_start
      - .initcall7.init内の全シンボル
      - ...
  - セクションD
  ...

ここで、序盤の謎であった __initcall6_startの謎が解けます。思い出してほしいのですが、変数 __initcall_xxxx6はdevice_initcall(xxxx, 6) で指定した関数xxxxのポインタを値として持っていました。

リンカスクリプトによって、変数 __initcall_xxxx6の一群を __initcall_funcname6から「連続したアドレスに配置する」ので、C言語から見たときには、__initcall6_startはあたかも関数ポインタの値を持った配列に見えるわけです。

__initcall6_startが持っている値のイメージ

static initcall_t __initcall_funcname6 = funcname;
static initcall_t __initcall_func2name6 = func2name;

initcall_t __initcall6_start[] = {
        __initcall_funcname6, 
        __initcall_func2name6, 
        ..., 
};

ただし、C言語ではこのような書き方はできないし、仮に書けたとしても、

&__initcall6_start[0] == &__initcall_funcname6
&__initcall6_start[1] == &__initcall_func2name6

が成り立たないので、厳密に同じことはできません。

この仕組みはC言語だけでは記述するのは恐らく不可能で、リンカとの連携の賜物と言えるでしょう。

ビルドしたバイナリを見る

論より証拠でLinuxカーネルをビルドして、生成されたvmlinuxをreadelfで調べましょう。

実験に使うカーネルは3.14.44でARM Versatile PBボード向けコンフィグでビルドしたものです。拙作のARM9エミュレータememu(emuemuについてはこちら)の動作確認用に実際に動作させていたバイナリです。

まずは -Sオプションでセクションの一覧を見ます。

$ arm-linux-gnueabihf-readelf -S vmlinux

セクションヘッダ:
  [番] 名前              タイプ          アドレスOff    サイズES Flg Lk Inf Al
  ...
  [21] .init.pv_table    PROGBITS        c039b818 3a3818 0005cc 00   A  0   0  1
  [22] .init.data        PROGBITS        c039bde8 3a3de8 003f6c 00  WA  0   0  8
  [23] .data             PROGBITS        c03a0000 3a8000 027380 00  WA  0   0 32
  ...

アドレスc039bde8からc039ffffまで、サイズ3f6c分のセクション .init.dataが居ることがわかります。vmlinuxをバイナリエディタなどで見る場合はOffの位置、つまり3a3de8を見ると .init.dataのバイナリデータが見られます。

Linuxはビルドしたときに全シンボルのアドレスと、シンボル名の対応表を作成してくれます。アドレスとシンボル名の対応はSystem.mapというファイルに出力されます。

$ grep initcall6 System.map
c039fb08 T __initcall6_start

$ grep initcall7 System.map
c039fc94 T __initcall7_start
c039fcb4 t __initcall_deferred_probe_initcall7

System.mapを見てもわかるように、__initcallx_startの軍団は .init.dataセクションの範囲内に全員収まっていることがわかります。

初期化順序

残りの疑問であるinitcall6内の呼び出し順はどうなるか?については、コンパイルされた順番になるようです。

System.mapの __initcall6_start付近を見ると、

c039fb08 T __initcall6_start
★★★arch/arm/ 以下
c039fb08 t __initcall_fpe_init6

★★★kernel/ 以下
c039fb0c t __initcall_proc_execdomains_init6
c039fb10 t __initcall_ioresources_init6
...
c039fb50 t __initcall_pid_namespaces_init6
c039fb54 t __initcall_utsname_sysctl_init6

★★★mm/ 以下
c039fb58 t __initcall_init_per_zone_wmark_min6
c039fb5c t __initcall_kswapd_init6
...
c039fb70 t __initcall_slab_proc_init6
c039fb74 t __initcall_cpucache_init6

★★★fs/ 以下
c039fb78 t __initcall_fcntl_init6
c039fb7c t __initcall_proc_filesystems_init6
...
c039fbbc t __initcall_init_jffs2_fs6
c039fbc0 t __initcall_init_romfs_fs6

★★★ipc/ 以下
c039fbc4 t __initcall_ipc_init6
c039fbc8 t __initcall_ipc_sysctl_init6

★★★crypto/ 以下
c039fbcc t __initcall_crypto_algapi_init6
c039fbd0 t __initcall_aes_init6

★★★block/ 以下
c039fbd4 t __initcall_proc_genhd_init6
c039fbd8 t __initcall_bsg_init6
c039fbdc t __initcall_noop_init6
c039fbe0 t __initcall_deadline_init6
c039fbe4 t __initcall_cfq_init6

★★★drivers/ 以下
c039fbe8 t __initcall_pl061_gpio_init6
c039fbec t __initcall_fb_console_init6
...
c039fc68 t __initcall_ms_driver_init6  -> module_hid_driverが生成した関数
c039fc6c t __initcall_mr_driver_init6  -> module_hid_driverが生成した関数

★★★net/ 以下
c039fc70 t __initcall_sock_diag_init6
c039fc74 t __initcall_flow_cache_init_global6
...
c039fc90 t __initcall_packet_init6
c039fc94 T __initcall7_start

このようになっています。linux/Makefileを見てみると、

ifeq ($(KBUILD_EXTMOD),)
core-y          += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

このように同じ順で並んでいることがわかります。ざっと見た感じだと、サブディレクトリ内のモジュール達(fs, driversの下)も同様に、Makefileに書いた順で初期化されるようです。

要するに、モジュールBがモジュールAに依存している場合、MakefileにはA → Bの順で書かないとなりません。逆に書いてしまうと、モジュールBが先に初期化され、未初期化のモジュールAを呼び出し、カーネルがクラッシュする悲劇が起きます。

編集者:すずき(2023/04/29 21:40)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2015年10月9日

Appleとファウンドリ

「うわ... 私のiPhone 6sバッテリーもたない?」CPU違いの6sでバッテリーベンチをしてみました を読んで。

元々の原価が低いのか、FinFETで首位に立つべく値引きしたか、事情は知りませんが、廉価版のiPhoneほどSamsung製の搭載比率が大きいところを見ると、TSMCよりSamsungの方がAppleの利ザヤがデカいのでしょう。おそらく。

そういえばQualcommはSnapdragon 810(TSMC 20nm)で発熱問題に泣いて、次のSnapdragon 820はSamsung製らしいですね。16nm世代を採用したら次も泣かされそう…。

メモ: 技術系の話はFacebookから転記しておくことにした。

編集者:すずき(2015/10/10 01:02)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2015年10月5日

MPEG4-AVC / H.264の2つのフォーマット

今や映像の圧縮方式として当たり前となりつつあるMPEG4-AVC(※)には、2つの形式があります。

  • ISO/IEC 14496-1: Annex B - Byte Stream Format
  • ISO/IEC 14496-15: NAL File Format

Byte Stream Formatは、俗に言うスタートコード形式(0x000001を目印としてNALUが始まる)で、コンテナを使わない場合、リアルタイム配信(RTSP)、放送系(MPEG2-TSをコンテナ)で良く使われているようです。

利点としては「欠け」に強いことです。何か問題が発生してデータが欠けてしまっても、スタートコードさえ見つかれば、その地点から処理を再開できます。その分、毎度スタートコードを探す処理が必要がある、先頭が欠けても再生できるように重複して情報を入れる必要があるなど、やや非効率的です。

NAL File Formatは、いわゆるサイズ指定形式(数バイトのサイズの後にNALUが始まる)です。ファイル形式(MP4など)に良く使われているようです。

利点としては「効率的」であることです。余分な情報はコンテナに持たせて、ビットストリームからは取り去りますのでサイズが小さくできます。NALUのサイズも予めわかりますから不要なNALUをスキップする際の負荷も低いです。その分、1バイトでも欠けてしまうと、デコードできなくなってしまう弱さもあります。

実はこの2つを変換するのは面倒で、サイズ指定をスタートコードに置き換えるだけではダメです。そんな単純な変換では、上記のような特徴が出せません…。

(※)AVCはAdvanced Video Codecの略です。この規格はISO/IECとITU-Tの共同規格なので、MPEG4-AVCではなくITU-Tの規格名であるH.264と呼ぶ人も多いですね。

変換ツールの使い方

でも、自分でそのような処理を書く必要はありません。世の中にはナイスガイ達が居て、変換が可能なツールを公開してくれています。ありがたいことです。

まずはffmpegを使う場合ですが、コーデックは変更しないのでcopyを指定して、普段の利用ではあまり見かけないbsfオプションを使って変換します。

なぜmp4toannexbという名前かと言うと、MPEG4-AVCの規格であるISO/IEC 14496-1 Annex BにByte Stream Formatの規格が示されているからではないか?と思われます。

ffmpegを使う場合(NAL File FormatからByte Stream Format)
avconv -i /path/to/hogehoge.mp4 -vcodec copy -bsf:v h264_mp4toannexb hogehoge.h264

Gstreamerを使う場合はh264parseエレメントを使います。ffmpegと比べるとかなり長く感じますが、大したことはしていないです。

例では、改行を入れていますが、実際には改行を入れずに1行で書いてください。もしGstreamer 1.0系を使う場合は、video_00のところをvideo_0と書く必要があったはずです。たぶん。

gstreamerを使う場合(NAL File FormatからByte Stream Format)
 gst-launch filesrc location=/path/to/hogehoge.mp4 ! 
 qtdemux name=dem dem.video_00 ! 
 h264parse ! 
 video/x-h264,stream-format=byte-stream,alignment=au ! 
 filesink location=/path/to/es/hogehoge.h264

普通に動画を楽しんでいる人には、こんな変換は全く縁がありませんが、私にとっては便利なんです。こんなツール達がオープンソースで公開されているというのは、ありがたいことですなー…。

編集者:すずき(2015/10/11 18:12)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2015年10月4日

ちぐはぐなVisual Studioのエディタとコンパイラ

Visual Studio 2015のコンパイラは、未だにBOMを付けないとUTF-8を認識しません。なぜかShift-JISもコンパイルエラーになります(2013ではなりません)。

MSDNライブラリ(サイトへのリンク)でも「コンパイラおよびリンカーでのUnicodeのサポート(... 中略 ...)BOM付きのUTF-8」などと言いきる始末です。イマイチすぎる…。

Visual StudioのIDEはGitに対応したり、エディタがマルチプラットフォームになったり、コミュニティベース開発に力を入れたり、時代の流れに沿って進化していますが、

コンパイラはダメダメ感が漂います。C++0xの対応はllvm, gccの後塵を拝しワーストです。もはやMicrosoftですら単独でC/C++ コンパイラを開発するのは不可能なのかなあ…?

メモ: 技術系の話はFacebookから転記しておくことにした。

編集者:すずき(2015/11/29 03:53)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2015年10月2日

ジージェネレーションフロンティア

SDガンダム ジージェネレーションフロンティアの話。今までのFR設計イベントをメモしておきます。

FR設計イベントの材料一覧
第一弾

FRアカツキ(シラヌイ)/ 誘導機動ビーム砲塔システム
-- URゲーマルク(覚醒)/マザー&チルド・ファンネル
-- URシナンジュ /バズーカ
-- URドム/ジェットストリームアタック
-- URデスティニーガンダム(最大稼働)/パルマフィオキーナ

第二弾

FR νガンダム/連続格闘
-- URクロスボーン・ガンダムX1改・改/ヒートダガー&スクリュー・ウェッブ
-- URサザビー/ファンネル(Ver.2)
-- URジ・O(覚醒)/ビーム・ソード/四刀流 
-- URアルトロンガンダム/ドラゴンハング

第三弾

FRガンダムアヴァランチエクシア/GNソード/ソードモード
-- URストライクルージュ(IWSP)/一斉発射
-- URノイエ・ジール/有線クロー・アーム
-- UR ∀ガンダム/核弾頭
-- URケルディムガンダムGNHW(トランザム)/GNライフルビット

第四弾

FRガンダムデルタカイ/プロト・フィン・ファンネル
-- URグフ・カスタム/ヒート・ワイヤー
-- URガンダムDX(Gファルコン)/ツインサテライトキャノン
-- URデストロイガンダム/ツォーンMk2&スーパースキュラ
-- URデルタガンダム/ビーム・サーベル/二刀流

第五弾

FRガンダムAGE-2ノーマル/MS/ハイパードッズライフル
-- URザクII改/ヒート・ホーク&ダミーバルーン爆弾
-- URトールギスIII/メガキャノン/最大出力
-- URガンダムAGE-1ノーマル/ドッズライフル
-- URラフレシア/親バグ&子バグ

これらのイベントは既に終わっていますが、しばらく経つと再実施されるようです。作り逃したFRキャラクターが居ても、後でまた作れるかもしれませんので、材料となるURキャラクターを、間違って処分してしまわないようにメモしておきます。

しばらくやってみた感想

楽しい点は、小学生の時にハマっていたSDガンダムのカードダス集めの気分が味わえることです。特にFRキャラクター(カードダスのキラキラカードに相当)が当たった時は、出たこれ!って気分で嬉しいですね。

ゲームとしてはつまらないです。もし同じ面を100回以上やる「イベント」を、毎週連発するだけのゲームが面白い!好き!と思う人が居ればオススメしますが…。私は立ちながらか、歩きながらプレイしないと確実に寝ます。

嫌いな点はUIです。いちいちボタンを押さないと進まないのに、ボタンの配置に統一感がありません。片手で遊びづらいです。

編集者:すずき(2015/10/04 03:49)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2015年9月30日

ネットワークドライブ上の実行ファイル

Visual Studio Community 2015をインストールしてみたので、適当なプロジェクトを作成して、デバッグしようとすると「アクセスが拒否されました」と怒られました。なんだ、いつのまにこんなことに…?

どうもプロジェクトをsambaの共有ドライブ上に作成していたのが良くないようで、生成されたexeファイルを直接実行しようとしても「アクセスできません」と怒られてしまいます。

原因

Sambaのデフォルトの設定だとWindows側からファイルを作成すると全てのファイルがパーミッション0755で作成されてしまい、実行ファイルでもないファイルに実行権限が付いてしまいます。

これはLinuxからファイルを見る時に非常にウザいので、私の環境ではSambaの設定にcreate mask = 0644を追加しています。しかし、この設定だとexeファイルもパーミッションが0644で作成されてしまいます。

Sambaはパーミッション0644をWindowsのACLに変換するとき「実行権限が無い」と解釈するため、Windows側が「実行してはいけないファイルを実行するな」と怒っているようです。

対症療法

Linux側から手動でexeファイルのパーミッションを644から755に変更すると、実行できるようになりますが、ビルドの度にパーミッションが644に戻るので、毎回変更しなければならずダルくてやっていられません。

逆にWindows側から実行権を付けようと [プロパティ] - [セキュリティ] - [編集] ボタンから、実行権限を付加しても、ファイルのパーミッションに全く反映されません。

解決方法

この問題に半日悩んでいたのですが、実は非常に簡単な設定がありました。

Sambaの設定にacl allow execute always = yesを加えれば解決しました。このオプションは名前の通り、ファイルは常に実行可能、と解釈するオプションのようです。

なぜか日本語のヘルプが見あたらないのですが、最近追加されたオプションなのでしょうか?まあ、今となってはどうでも良いですが…。

ちなみにSambaの設定ファイルは /etc/samba/smb.confです。もし現在のSambaの設定の一覧を調べたければtestparmコマンドを使ってください。便利です。

編集者:すずき(2015/10/01 03:01)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2015年9月27日

進撃の巨人3D VRシアター

グランフロント大阪(大阪市北区)に、進撃の巨人展に併設の3D VRシアター「哮」を見に来ました。

チケットに書いてあるフォルムからして、ソニーのHMDじゃなさそう、機材はOculus Riftですかね。


上映室を入り口から撮影

上映時間は5分くらいとのこと。見終わったらまた感想でも書きます。

鑑賞後の感想

見てきました。ストーリーは無いに等しいです。立体機動装置って何?くらいを知っていれば楽しめると思います。

映像はキレイとは言えませんが、画が動いていれば、荒さは気になりません。

視点の動きは立体機動にしては大人し目ですが、もしミカサやアルミン並の上下動をされたら、メチャクチャ酔うと思います。おそらく物足りない位がちょうど良いのでしょう…。

映画と違うなーと思うところは、やはり枠の概念がないことでしょうか。振り返ると真後ろの景色が見えるのはとても斬新です。

  • 視聴者が好き勝手に違う場所を見るので、制作側は見せたい部分を強調しづらい
  • 都合の悪い部分を枠の外に追い出せない(視野外を端折る、演出上わざと破綻させる、など)

技術面でも、

  • カメラで撮る方法がない(必ず撮影者が映っちゃう)、半天ならできるかな?
  • 全視野対応の映像を作成、提供する方法が確立されていない

後者はすぐ解決されると思いますが、何かしらの標準ができるまでは、互換性やフォーマット乱立で揉めそうな予感がします。

YouTubeが一部、全視野対応の動画を配信していた気がしますが、あれ半天だったかな?

あと、見る前は、映画館のように暗い部屋で見るのかと思っていたのですが、写真のように明るい部屋での上映でした。Oculusは視界を覆うゴーグルタイプだから、周りの明るさは関係ないんですなー。

ただ、端から見るとかなり怪しい集団です…。なんだこれ。


上映室を入り口から撮影

メモ: 技術系の話はFacebookから転記しておくことにした。

編集者:すずき(2015/10/10 00:11)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2015年10月10日 >>> 2015年9月27日
link もっと後

管理用メニュー

link 記事を新規作成

<2015>
<<<10>>>
----123
45678910
11121314151617
18192021222324
25262728293031

最近のコメント5件

  • link 24年10月1日
    すずきさん (10/06 03:41)
    「xrdpで十分動作しているので、Wayl...」
  • link 24年10月1日
    hdkさん (10/03 19:05)
    「GNOMEをお使いでしたら今はWayla...」
  • link 24年10月1日
    すずきさん (10/03 10:12)
    「私は逆にVNCサーバーに繋ぐ使い方をした...」
  • link 24年10月1日
    hdkさん (10/03 08:30)
    「おー、面白いですね。xrdpはすでに立ち...」
  • link 14年6月13日
    2048player...さん (09/26 01:04)
    「最後に、この式を出すのに紙4枚(A4)も...」

最近の記事20件

  • link 24年10月31日
    すずき (11/04 15:17)
    「[DENSOの最終勤務日] 最終勤務日でした、入門カードや会社のPCを返却してきました。在籍期間はNSITEXE(品川のオフィ...」
  • link 22年7月8日
    すずき (11/02 20:34)
    「[マンガ紹介 - まとめリンク] 目次: マンガ紹介一覧が欲しくなったので作りました。5作品乙女ゲームの破滅フラグしかない悪役...」
  • link 24年10月30日
    すずき (11/02 20:33)
    「[マンガ紹介] 目次: マンガ紹介お気に入りのマンガ紹介シリーズ。最近完結した短めの作品を紹介します。マイナススキル持ち四人が...」
  • link 19年3月28日
    すずき (11/02 13:27)
    「[マンガ紹介] 目次: マンガ紹介お気に入りのマンガ紹介シリーズ。こわもてかわもて(全2巻、2019年)(アマゾンへのリンク)...」
  • link 21年6月20日
    すずき (11/02 13:22)
    「[読書一生分が93万円?] 目次: マンガ紹介書籍通販のhontoがこんなキャンペーンをやっています。honto読書一生分プレ...」
  • link 17年10月27日
    すずき (11/02 13:11)
    「[異世界&最強系漫画の種類] 目次: マンガ紹介少し前にアニメ化されて盛り上がって(おそらく負の方向に…)いた「...」
  • link 24年10月28日
    すずき (10/30 23:49)
    「[Linuxからリモートデスクトップ] 目次: Linux開発用のLinuxマシンの画面を見るにはいろいろな手段がありますが、...」
  • link 23年4月10日
    すずき (10/30 23:46)
    「[Linux - まとめリンク] 目次: Linux関係の深いまとめリンク。目次: RISC-V目次: ROCK64/ROCK...」
  • link 24年10月24日
    すずき (10/25 02:35)
    「[ONKYOからM-AUDIOのUSB DACへ] 目次: PCかれこれ10年以上(2013年3月16日の日記参照)活躍してく...」
  • link 24年7月25日
    すずき (10/25 02:24)
    「[OpenSBIを調べる - デバイスツリーの扱い(別方法)] 目次: LinuxOpenSBIのブート部分を調べます。Ope...」
  • link 24年8月7日
    すずき (10/25 02:23)
    「[Debian独自の挙動をするQEMUとbinfmt_misc] 目次: Linux前回はbinfmt_miscの使い方や動作...」
  • link 24年9月9日
    すずき (10/25 02:22)
    「[GDBの便利コマンド] 目次: LinuxGDBは便利ですが、少し使わないでいるとあっという間にコマンドを忘れます。便利&使...」
  • link 24年10月20日
    すずき (10/25 02:22)
    「[ゲームを買ったら遊びましょう2] 目次: ゲーム前回の振り返り(2022年5月13日の日記参照)から2年半経ちました。所持し...」
  • link 24年8月2日
    すずき (10/25 02:21)
    「[Debian on RISC-V] 目次: LinuxOpenSBI + Linuxの環境まで動いたので、次はLinuxのデ...」
  • link 24年8月6日
    すずき (10/25 02:21)
    「[他アーキテクチャ向けバイナリを実行する仕組みbinfmt_misc] 目次: LinuxRISC-V 64bit用の実行ファ...」
  • link 24年8月27日
    すずき (10/25 02:20)
    「[Milk-V Jupiterが届いた] 目次: RISC-VMilk-V Jupiterが届きました。お値段が非常に安かった...」
  • link 24年9月13日
    すずき (10/25 02:20)
    「[OpenSBIを調べる - OpenSBIとRISC-V ISA extensions] 目次: Linux今回はOpenS...」
  • link 24年10月11日
    すずき (10/25 02:19)
    「[企業のドメイン] 今の企業は公式サイトを持っていなほうが珍しいと思いますが、ドメイン名の使い方は各社でバラバラで面白いです。...」
  • link 24年10月21日
    すずき (10/25 02:18)
    「[OpenPilotを調べる - プロセス間通信msgqの仕組み] 目次: OpenPilot最近はOSSの運転支援ソフトウェ...」
  • link 24年10月6日
    すずき (10/25 02:11)
    「[OpenPilotを調べる - ビルドと実行] 目次: OpenPilot最近はOSSの運転支援ソフトウェアOpenPilo...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www2.katsuster.net
RDFファイル RSS 1.0

最終更新: 11/04 15:17