Linuxの最近のブログ記事

Linux memo 2025/08/07 cache cleanup編

● ccache
ccacheの--evict-older-thanオプションは、atimeではなくてmtimeを見るため、「キャッシュ作ったのは昔だけど最近も使った」ようなものまで消してしまう。
Clarify --evict-older-than ・ Issue #1292 ・ ccache/ccache
https://github.com/ccache/ccache/issues/1292
mtimeではなくatimeを見るようにccacheそのものを変更してしまう以外のいい方法がわからない。
サイズあふれしてないことを確認しながら ccache -M 10G などしてサイズ上限で自動的にクリーンナップさせるくらいがよい?

● git lfs
git.lfs.storage (LfsStorageDir)を使っている場合、古いLFSオブジェクトをクリーンナップするよい方法が見つからなかった。

● repo
reop list -p すればrepoで管理するgitのリストを表示してくれるので、これをもとに git -C DIR gc すればよい。
ただ、1つずつgit gcしてると、対象がたくさんあるときに時間がかかる。
そういう場合、一般的には GNU parallel を使うのが良いとされるが、GNU parallel はオプションやら前置後置やらの使いこなしがクソめんどい。
ので、GNU parallelっぽく使える mypara.pl を作って公開してるので、興味ある人は使ってみて。
https://github.com/rarul/tools/blob/master/script/mypara.pl
下記のように、mypara に pipe で行単位で送ると、1行1コマンドとして -j 4 の最大4並列で実行する。
- $ for ff in `repo list -p`; do echo ${ff}; done | xargs mypara -j 4 -c "git -C" -C "gc"
(-p なのか -n なのか、--mirrorの場合はディレクトリ名に".git"が追加でつくとか、そのへんは適当に調整してください)

● bitbake DL_DIR
単純にアクセス時間の古いものを消せばよい。
- $ cd /mnt/share/downloads
- $ find . -type f -atime +60 -delete
- $ find . -type d -empty -delete
まれに「atime記録書き込みするのがイヤだから-noatimeにしている」人がいるが、ことLinuxに関しては、過去に私が記事に書いた通り、relatimeがあるので、あえてnoatimeにする価値は低い。

● bitbake SSTATE_DIR
DL_DIR同様、単純にアクセス時間の古いものを消せばよい。
- $ cd /mnt/local/sstate-cache
- $ find . -type f -atime +60 | xargs rm -f
- $ find . -type d -empty | xargs rmdir
bitbake環境では、sstate-cache-management.py というスクリプトも提供されるが、これは、1つのbitbakeツリーから1つのSSTATE_DIRを利用している場合にのみ利用できる。
複数のbitbakeツリーから1つのSSTATE_DIRを共有している場合には sstate-cache-management.py は役に立たない。
下記も参考に。
26 Conserving Disk Space
https://docs.yoctoproject.org/dev-manual/disk-space.html

Linux memo 2025/01/09 Yocto編

● ビルド関連
- ダウンロード時間の節約をがんばる
- ビルド並列数を適切にする
- sstate chaceを使う
- iceccを使う

● confパラメータ
- PARALLEL_MAKE ?= "-j 4 -l 12"
- BB_NUMBER_THREADS ?= "4"
--- 上記の掛け算になるので最大16並列になる
--- 1ジョブあたり1GiBくらいメモリを平気で使う
--- 過大な値が初期値に記載されてることが多いので要注意
--- よくばってもスワップで遅くなったりOOMで失敗したりする
--- 深さ優先ビルドのほうが効率良いのでPARALLEL_MAKEを大きくするのがよいと思う
--- "-l 12"でload average制限もつけておくと安全かもしれない
--- - ninjaの場合に -l も引き継ぐ場合と引き継がない場合とがある?(詳細未確認)
--- 「?=」で記載しとくとexportで環境変数で上書きできるので便利
--- - 実は引き継いでほしい変数を宣言しておかないといけない?
--- - 「export BB_ENV_PASSTHROUGH_ADDITIONS="SSTATE_DIR "」など?
- BB_NUMBER_PARSE_THREADS ?= "4" --- parse時はあまり負荷意識する必要ないので特に設定しなくてよいと思う
- PACKAGE_CLASSES ?= "package_ipk" --- rpmからipkにするとビルドは早くなるらしい
--- いまいち効果を確認できず。要追加検証。
- DL_DIR ?= "${TOPDIR}/downloads" --- 複数ツリーでダウンロードフォルダを共通化する
- SSTATE_DIR ?= "${TOPDIR}/sstate-cache" --- 複数ツリーでsstate cacheフォルダを共通化する
- SSTATE_MIRRORS ?= "file://.* http://someserver.tld/share/sstate/" --- リモートや複数PCでsstate cacheを共有する
- INHERIT += "own-mirrors"
- SOURCE_MIRROR_URL = "http://example.com/my-source-mirror"
--- DL_DIRになかったときはここも確認する、PREMIRRORSとほぼ同じだがPREMIRRORSよりも便利らしい
- BB_SERVER_TIMEOUT ?= "20" --- 仕事なくなったbitbake serverが終了するまでの待ち時間、bitbakeコマンドを頻繁に実行するなら大きめの方が良い?
- BB_PRESSURE_MAX_CPU = "200000" --- PSI(Pressure Stall Information)のCPUで追加job実行の制限をする
--- CPUの(論理)個数をNとして、N >> 2 だと仮定して、「2 * 1000000 / N"」 くらいか、と思う
--- 詳細はこのへんを見て
- BB_PRESSURE_MAX_MEMORY --- Pressure Stall(PSI)のmemoryはピーキーなので「スワップ発生中」判定くらいしか使いにくいと思う
- BB_PRESSURE_MAX_IO --- Pressure Stall(PSI)のioは負荷の程度を判断する目的では使い物にならないと思う
- INHERIT += "rm_work" --- 中間ファイルを消してくれるのでディスク容量節約になる

● bitbake基本
- bitbake -c taskname recipe-name
--- "taskname"で普段使うのはこのへんか?
--- fetch patch configure compile install deploy image
--- rm_work --- 中間ファイルを消す
--- clean --- outputを削除する
--- cleansstate --- build時に作ったsstate cacheも削除する
--- cleanall --- ダウンロードしたファイルも削除する
- -f --- 強制実行
- -s --- レシピ一覧
- bitbake -c cleansstate world --- すべてのレシピを指定
- bitbake -c populate_sdk recipe-name --- SDKを作る
- bitbake --runall=fetch recipe-name --- すべてのレシピのfetchのみ実行する
- bitbake -c menuconfig virtual/kernel --- menuconfig実行する

● bitbake応用
- bitbake -e recipe-name --- すると変数名が出る?
- bitbake-layers show-layers --- レイヤー一覧を表示
- bitbake-layers show-recipes --- レシピ一覧を表示
- bitbake-layers show-appends --- bbappend一覧を表示
- oe-pkgdata-util find-path /lib/libc.so.6 --- ファイルを提供するレシピを探す
- bitbake-getvar -r recipe-name VARIABLE --- 変数を参照する箇所をデバッグ表示する
- bitbake -g -u recipie-name target-name --- 依存を調査するためのグラフィカルツール
- bitbake -c devshell recipie-name --- ビルドエラーなどのデバッグ用のdevshellを立ち上げる
--- buildhistory-diff
- bitbake-layers create-layer -p PRIORITY LAYER
--- レイヤーは理解できてないのでこれあまり以上書けない、、

● レシピ基本
- PACKAGES --- レシピが提供するパッケージ名、test.bbがあると「"test-dbg test-staticdev test-dev test-doc test-locale test"」が提供される
- PROVIDERS --- レシピが提供するプロバイダ名、要はbbが提供する成果物のこと、test.bbがあると「test 」が提供される
- DEPENDS --- このレシピのビルドのために先にビルドする必要がある依存パッケージを書く
- RDEPENDS --- このレシピの実行のために必要となる依存パッケージを書く
- SRC_URI --- 「file://」「https://」 あたりを使う、sshの場合は「protocol=ssh;」を追加する形になる?
- SRCREV --- git sha1とかを入れる、「SRCREV = "${AUTOREV}"」でブランチ名オンリーにできるが毎回fetchして最新の変更を追随してしまうので推奨されていない

● レシピ変数
ほぼ下記ここからパクった、、
https://qiita.com/rg125_suzuki/items/702e90084e12e0fdf6de#%E3%81%9D%E3%81%AE%E4%BB%96
- ${S} --- ソースコードの展開先
--- gitの場合明示的に「S = "${WORKDIR}/git"」とする必要がある
- ${BPN} --- 基本レシピ名、zlib-native-1.2.11-r0の場合、zlib
- ${PN} --- fixつきレシピ名、zlib-native-1.2.11-r0の場合、zlib-native
- ${PV} --- バージョン、zlib-native-1.2.11-r0の場合、1.2.11
- ${PR} --- リビジョン、zlib-native-1.2.11-r0の場合、r0
- ${BP} --- ${BPN}-${PV}、zlib-native-1.2.11-r0の場合、zlib-1.2.11
- ${PF} --- ${PN}-${PV}-${PV}、zlib-native-1.2.11-r0の場合、zlib-native-1.2.11-r0
- ${TOPDIR} --- ビルドトップディレクトリ、pock/buil dなど
- ${TMPDIR} --- ${TOPDIR}/tmp
- ${WORKDIR} --- レシピの作業ディレクトリ、poky/build/tmp/work/x86_64-linux/zlib-native/1.2.11-r0 など
- ${D} --- ${WORKDIR}/image
- ${B} --- このレシピを処理するときの一時インストール先?デフォルトは ${S} と同じ?
--- ${S}がsrc、${B}がconfigureしたときのobj、${D}がインストール先、という関係?

● レシピ拡張
- レシピを書き換えるのではなくてレイヤーで重ねるべき、とドキュメントに書かれてる
- bbappendはバージョン固有であるべき、とドキュメントに書かれてる
- example_1.0.bb を example_1.0.bbappend で拡張する
- example_1.%.bbappendは、example_1.0.bb にも example_1.1.bb にも効く
- パッチファイルなどを足すときは.bbappendにこんなのを書く
--- FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
--- SRC_URI += " file://custom-modification-0.patch "
- タスクを拡張するときは.bbappendにこんなのを書く
--- do_install:append() {
--- install -d ${D}${sysconfdir}
--- }

● 仮想パッケージ
- PROVIDES = "virtual/libgl" --- 複数レシピが同じ仮想名を提供できる
- PREFERRED_PROVIDER_virtual/libgl = "mesa" --- 仮想パッケージを選ぶ?
- PREFERRED_VERSION_linux-yocto = "5.14%" --- 特定バージョンを選択する、%はワイルドカード

● レシピ応用
- .bbclass --- レシピのルールのテンプレートみたいなやつ、わざわざ自分でカスタム.bbclassを作るケースはほぼないかと
- base.bbclass kernel.bbclass autotools.bbclass cmake.bbclass meson.bbclass useradd.bbclass などがある
- inherit

● 変数代入
- "=" --- 変数を使用するときに展開(makeと同じ?)
- ":=" -- - 即座に展開(makeと同じ?)
- "+=" --- 後置スペースあり追加
- "=+" --- 前置スペースあり追加
- ".=" --- 後置スペースなし追加
- "=." --- 前置スペースなし追加
- "?=" --- 未割り当てのときに割り当てる
- "??=" --- 未割り当てのままのときにのみ反映されるデフォルト値、ややこしいので使わないほうがいいと思う
- VARIABLE:override = "some_value"
--- 変数展開時に先頭に追加する
--- 「VARIABLE_override」という書き方があったが古い構文なので今後は使わない
- IMAGE_INSTALL:append = " dropbear" --- 末尾にスペースなし追加
- FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" --- 先頭にスペースなし追加
- IMAGE_INSTALL:remove = "i2c-tools" --- 変数内のすべての出現を削除
- KERNEL_DEVICETREE:beaglebone = "am335x-bone.dtb"
--- OVERRIDES内に「beaglebone」があるときのみ代入される
--- 優先代入されるので「beaglebone」がある場合は「KERNEL_DEVICETREE = ""」は無視される

● 変数フラグ
- 主にタスクに条件を足すことができる
- do_compile[dirs] = "${B}" --- タスクを実行する前に生成されるべきディレクトリ
- do_settime[noexec] = "1" --- タスクの実行を無効にする
- do_menuconfig[nostamp] = "1" --- タスク実行時にstampファイルを作らない、のでタスクが常に実行される
- do_patch[depends] = "quilt-native:do_populate_sysroot" --- タスク間の依存を追加

● イメージ作成
- IMAGE_INSTALL --- イメージに入れる
- IMAGE_BASENAME --- イメージファイル名
- IMAGE_FSTYPES --- イメージタイプ、ext4 squashfs などに処理できる?

● FAQ
- Q: DEPENDS と RDEPENDS の違いがわからん
--- A: DEPENDSはビルド時依存、RDEPENDSは実行時依存(だからIMAGE_INSTALLにも効く?)
- Q: ビルドエラーログってどこ?
--- A: モジュール毎の temp/ 以下の "log.do_compile"、"run.do_compile"はそのまま実行可能、どちらもsymlink
- Q: include と require の違いは?
--- A: includeはファイルがなくてもエラーじゃない、requireはパースエラー
- Q: ちょっと変更しただけなのにモジュールやファイルがないというビルドエラーが出る
--- A: 既存のレシピで依存やinstallの記載漏れがあるせいと思われる、bitbakeレシピはチェックが厳格なのでこういうのが起こりやすい

● 参考サイト
Yocto build 時間を10時間から10分に高速化した話 - Qiita
https://qiita.com/naohikowatanabe/items/868eefed28cefec20ff8
【yocto】レシピ内変数の早見表 - Qiita
https://qiita.com/rg125_suzuki/items/702e90084e12e0fdf6de
lockfileでdo_compileをシリアライズするという裏技
https://stackoverflow.com/questions/71885775/mutually-exclusive-bitbake-recipes-tasks

● ドキュメント
12 Variables Glossary / The Yocto Projec
https://docs.yoctoproject.org/ref-manual/variables.html
Yocto Project and OpenEmbedded system development training (PDF注意)
https://bootlin.com/doc/training/yocto/yocto-slides.pdf
このへんにサンプルレシピの具体的な例のURLもぜひほしい

● 所感
Yoctoなにもわからない
Yoctoはプログラマ向けではなくてディストリビュータ向けなので開発には向かないと思う
追加のハマりどころがあれば追記する予定
2025/1/31(Fri): 便利そうなコマンド類を追記、誤字脱字訂正

「Binary Hacks Rebooted」読んだ

Amazonアフィへのリンク

約17年前に発売された「Binary Hacks」の名前を冠する続編本。一般的に「低レイヤー」と呼ばれることの多い、コンピュータソフトウェアの中でも特にOSやCPUに近い部分の技術を、章ごとに1つずつ紹介するという内容になっている。

「Binary Hacks」はそれなりに反響のあった本だったため、その名前を冠するだけで、それ相応に注目を集めることになる。本を読んだ限りでは、名前に恥じることのない程度には濃い内容に仕上がっている。まぁ逆に、こんな内容の濃い本を好き好んで読もうと思うような人がいったいどれだけいるのかというあたりにも疑問を持つ。20年ほど前と比べると、今やこの日本でこういった内容のソフトウェア技術を必要とする仕事やらは本当に減ってしまったなというのが個人的な印象だ。

低レイヤーは技術の進化が早いわけではないとはいえ、20年近くも時代が進むとそれ相応に変わっていくわけで、その内容を雑多的に情報として知れるというのは実際のとこ個人的には非常にありがたい。書籍として出版されることが減ってきているという時代に、しかも需要がどんどん減ってる日本語での技術情報提供でというあたり、儲かりもしないのにこれだけのレベルでまとめ上げてくれた各位には本当に感謝したい。

著者らは「*年後にさらにこの本の続編が出ることを期待して」のような記載を残している。これこそ、こういう領域に熱意を持って力を注ぎこむような人が今後も続くのかどうか、もっと言えば、こんな領域のソフトウェア技術開発を未来の時代に行っているほど日本(なのか日本語なのか)がグローバルに競争力を維持できているのかどうか、という話なのかなと思う。

前作と比べるとページ数が約1.5倍になっている。改めて前作を斜め読みするに、あまり細かく丁寧に説明するような文章にはなっていなくて、それに対し本作は文章をかなり丁寧に書いている事が多いので、その分がページ数の差なのかなと感じた。600ページ超えとなるともはや大型本よね。「サクッと読む」には少々重いというのが若干残念なところか。

というわけで、低レイヤー技術を対象に日本語で書かれた非常にレアな本で、その領域に片足を突っ込んでる人は迷わず買っておけというところ。逆に、低レイヤーに興味がない人には全くささらないと思う。

下記は本の内容で気になったところをメモがてらに。

HACK#6 共有ライブラリの検索の実例
P39「AT_SECUREタグを持つエントリが含まれていた場合」
今まではsuなどのときにLD_LIBRARY_PATHが無効になる条件がわからなかったけど、補助ベクトルが効いていることを知れてよかった。
過去の記事のどこかに「わからない」と自分で書いた記憶があるんだけど、探しても見つからなかったので、訂正ができない。。

HACK#10 TLSのしくみを理解する
P58「TLSアクセスモデル」
gdbでattachしている最中にThread Local Storageな変数へアクセスする方法がいつもわからずに苦労していた。このあたりの記載を頼りに調査すれば、今どきのgdbからのアクセス方法を確立できそう。

HACK#17 LIEFを使ってELFバイナリを書き換える
P92あたり
まさに最近はシンボルの書き換えがクソめんどいから、こういう専用のツールがあることを知れてよかった。ただPython製というのはどうなんだろ。特にクロス環境にて、いずれにしてもlibelfに依存することを考えれば、Pythonに追加対応させるためのツール整備も最近なら大した事ない?

HACK#38 cgroupでプロセスのリソースを管理する
P248 「IOCOST」
I/O Schedulerで制御することしか知らなかった私からすると、こんな他の手段もあるんだなぁと知れてよかった。けど、本書での紹介っぷりからすると、必ずしも思い通りにI/O量を制御できるわけではなさげ?I/O Schedulerでも制御が難しいし、やっぱりI/O制御は難しいという話なのか?

HACK#43 /proc/PID/rootからコンテナ内のファイルに直接アクセスする
docker内のファイルへ外から簡単にアクセスする方法、ずっとこれのやり方が知りたかった。わからなかったので、わざわざdocker cp使って毎回中から外へ大量のコピーをしてしまっていた。

HACK#49 ftraceを使ってカーネル内で起こっていることをトレースする
P341あたり、
KernelShark trace-cmd、あたりは過去に使ってみたことはあるんだけど、これ、目的を定めて使わないと逆に迷走するなと感じた。GUIで可視化すると一部のエライ幹部に受けが良くて、かえって性能改善活動のジャマになって(以下略

セキュリティの大章は全般的にツールを使った力技的な話が多くて「HACKしている」感があまりしないと感じた。数値表現の大章はいわゆる数値計算の分野だというイメージが強くて「まぁ知らなくてもいいかな」と読み飛ばし気味になってしまった。

Linux memo 2024/05/13 tty share編

● 前置き
画面を動画形式で他の人へ共有するとどうしても遅延に悩まされる。
terminal上での操作を共有したいという場合ならば tty の出力をそのまま共有すればいいのではないか、というアイディアが出てくる。

● 同一ホストで共有する場合
ほぼ下記の記事ですべて語られているけど、
tty script コマンドでLinuxサーバ作業を他者に共有
https://qiita.com/kikudai/items/66ff7155623d635d10c2

- 配信したい人のマシンをA、ターミナルをa、
- 視聴したい人のマシンをB、ターミナルをb、
として、bで閲覧するためのterminalを実行し、ttyコマンドを実行して、その結果「/dev/pts/22」などをメモる。
これを配信者に伝え、aの上で、
- script -fq /dev/pts22
を実行し、aの上でそのまま作業すればよい。終わったら、aでexitする
(bash終了と同時にscriptも終了)
(注意:scriptという名前のコマンドがありそれを使っている)
下記のような記事もあるけど、straceは明らかに過剰で負荷が高いと思われる。
ターミナル画面を勝手に共有して他人の作業を覗いてみる
https://qiita.com/nashiox/items/f9b026b7433fcf984d45

● 同一ホスト別ユーザの場合
難しいことは考えずに、先と同じ方法で同一ユーザでttyをつないだあとに、suなどすればよいと思う。

● 異なるホストの場合
まず、aの別ターミナルとなるa2を開いて下記を実行する。
- mkfifo /tmp/testsharetty
- cat /tmp/testsharetty | nc -l 10333
次に、bで下記を実行する
- nc -N 192.168.123.45 10333
最後に、aで下記を実行する
- script -fq /tmp/testsharetty
mkfifoとnc(netcat)を介することで、TCPごしに相手に見せれる。
serverとclientは入れ替えできると思う。
グローバルに公開していい?認証?それは知らん。。

● 複数人宛に同時に配信したい場合
上の方法で、mkfifoしたunix domain sockerから1回readするごとに、
TCP socket serverにつなぎに来た人全員に1回ずつwriteする、
ということを行うサーバプログラムを作れば良い。
...うん、ちょっとがんばれば作れそうだね(あとは誰か頼む

● あとで再生したい場合
"script"コマンドで取得したログは、in/outのタイミングが記録されておらず、これをterminalに食わせても超高速で流れていくだけとなる。
なので、下記の記事で紹介されている ttyrec ttycast を使うのが素直かと思う。
ターミナル操作をウェブで配信する
https://qiita.com/ohtaman/items/775b3831754336c75208

● その他
帯域が狭い・だけど遅延は減らしたい、みたいな場合は、ssh -C でsshセッション越しが楽だと思う。

Linux memo 2023/12/30 glibc errno

Pofixではerrnoはthread safeとされていて、Linux(というかglibc)もthread safeだが、世の中にはそうでないシステムもあるらしく、そのせいでerrnoを使おうとすると「thread safeかどうか確認しろ」と無慈悲な指摘をするヘンテコな解析システムがあり、そいつを分からせてやるために無駄な調査を行うハメになった。

glibcのこのへんを見ると良い。
/csu/errno.c
/csu/errno-loc.c
/stdlib/errno.h

glibcがthread localに対応したのは下記かららしい。裏付けできなかったがおそらくこのタイミングでerrnoも対応したと思われる。
glibc-2.3 (2002-10-02) thread local
https://sourceware.org/legacy-ml/libc-alpha/2002-10/msg00048.html

Linuxがいわゆる昔のLinuxThreadsからネイティブスレッド(NPTL)に変更されたのはLinux-2.6.0からで、Linux-2.6.0は 18 December, 2003 にリリースされている。
https://kernelnewbies.org/LinuxVersions

errnoをgdb上から確認するために__errno_location()を直接呼ぶ方法も参考に。

Linux memo 2023/08/12 gdb,C++あたり

● gdb上でerrnoを表示する方法
(gdb) print *((int*(*)())__errno_location)()
(ただしglibc限定)
関数ポインタのキャストの型なにもわからない

● gdb中にシグナル受けて止まってうぜぇ
define nosignals
handle SIGPIPE noprint
handle SIGPIPE nostop
end
使いたいときほど設定忘れててすぐに使えずに困ることがあまりに多すぎたのでメモっとく

● ときどきSIGSEGVするプログラムをgdbで捕まえたい
define sigsegvrun
nosignals
break _exit
commands
run
end
end
時々**するプログラムを起こるまで繰り返し実行する用途に応用は利くと思う。

● debug情報が別ファイルになってる場合のgdbの設定方法
$ objcopy --add-gnu-debuglink=test.debug test
で、testというファイルにtest.debugを見に行けという情報を .gnu_debuglinkセクションに記録する
(gdb) set debug-file-directory ./debug
さらに別ディレクトリ(./debug/)にdebug情報入りelfファイルがある場合の設定方法
安定のmasamiさんブログからのコピペですすみません、、
elfファイルのdebugセクション分割とgdbの分割されたデバッグ情報のサポート機能めも
https://kernhack.hatenablog.com/entry/2016/07/18/161802

● Effective Morden C++ 項目7の補足
Effective Morden C++ 項目7「オブジェクト作成時の () と {} の違い」
には、ctorを呼ぶときは () ではなくて {} のほうがよいとしつつ、それが通用しない例をつあげている
- A) auto型変数で受ける場合
- B) initializer_listを引数に取るctorを持つclassの場合
B)の代表例として std::vector<>を提示している。

が、本に記載のない例として std::string(size_type, charT) もある。
- std::string('a', 6); // "aaaaaa" size==6
- std::string{'a', 6}; // {0x61, 0x06} size==2
参考:basic_string::コンストラクタ - cpprefjp C++日本語リファレンス

ちなみに英語でのカッコはこう呼ぶらしい
- () parentheses , round
- {} braces , curly
- [] brackets , square

Amazonアフィリンク

Linux上でのPCM音の入出力の標準となっているALSAについての入門書。音をデジタルデータとして扱うための導入、ALSAの役割とその基本的なAPIについて、ALSAを使ったサンプルプログラミングの解説、という構成になっている。

プログラミングというタイトルになってはいるものの、音をハードウェアから出力する部分を扱うため、比較的低レイヤーなプログラムの話になるし、同時に音をどのような形でデジタル表現しているかについての知識を要する内容になっている。たしかに入門書的な説明の本とはいえ、このへんの分野のことを学ぶんだという心構えは最低限必要かと思う。

プログラミングという触れ込みの本ではあるが、サンプルコードを見る限り、著者はどうもコーディングに慣れていないように見受ける。分野が分野なだけに、信号処理やリアルタイム処理やDSPといったハードよりの分野から流れてきたのかなと推測される。サンプルプログラムは、処理のフローを理解するのにはよいが、細かなコーディングの手癖はマネしない方がよい。

ハイレゾやらUSB Audio Device Classやらの話が登場するが、ハイレゾは本書ではほとんど関係ないし(ビットレート計算くらい)、また現代ではalsaがUSB限定というわけでもないので、このへんは差し引いて読んだほうがよい。

入門書にケチを付けても仕方ないのだけど、実践的な内容にまでは触れられていない。いつでもどこからでもデータを拾い放題な音声ファイルをALSAのクロック任せで出力すれば良いケースは一番シンプルな例で、現実は、音声ってストリームなリアルタイムのデータなので、アンダーラン・オーバーランやレイテンシやASRC(asynchronous sample rate convert)なんかを気にしないといけないのだけど、さすがにそういう内容を求めるのは酷か?とはいえ、P79のNoteにあるniceで優先度をあげようの部分なんか、ごまかすにしてももう少し書きようがあるだろうにと思ってしまう。ここはSCHED_FIFOのキーワードくらいは記載すべき。

と酷評気味に書いてしまったが、ALSAをていねいに解説したものなんて、書籍でもネット上の記事でも皆無に近いので、そういう意味では非常に貴重な本となっている。逆に、ALSAなんて公式ドキュメント読めばいいだろ(当然英語)、というくらいの心構えがある人はやっぱりあえて読まなくても良いとなってしまうか。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちLinuxカテゴリに属しているものが含まれています。

次のカテゴリはPCハードウェアです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

ウェブページ

Powered by Movable Type 7.9.0