Tru64 UNIXで遊ぼう!(inline編)

Tru64 UNIXでlibarchiveをコンパイル出来るように試行錯誤していたところ、面白いものを見つけました。

github.com

どうやら、Tru64 UNIXの場合は関数指定子inlineを__inlineと定義しているようです。

どういうことなの?

せっかくなのでアセンブラを出力させてみました。

まずは普通のinline版

$ more inline.c

static inline int
max(int i1, int i2) {
        return (i1 > i2) ? i1:i2;
}
 
int
main(int argc, char *argv[])
{
        return max(1,5);
}

コンパイラCompaq C Compilerです。

$ cc -V
Compaq C V6.5-303 (dtk) on HP Tru64 UNIX V5.1B (Rev. 2650)
Compiler Driver V6.5-302 (dtk) cc Driver
$ cc -S inline.c
                                                                                                                                                                                                    
$ more inline.s                                                                                                                                                                                                     
	.set noat
	.set noreorder
	.text
	.arch	generic
	.align 4
	.file 1 "inline.c"
	.loc 1 1
 #      1 static inline int
	.ent 	$$1$max
	.loc 1 1
	.loc 1 2
 #      2 max(int i1, int i2) {
$$1$max:														   # 000002
	.frame  $sp, 0, $26
	.prologue 0
	.context full
	sextl	$17, $17
	sextl	$16, $0
	.loc 1 3
 #      3         return (i1 > i2) ? i1:i2;
	cmplt	$0, $17, $1												   # 000003
	cmovne	$1, $17, $0
	.loc 1 4
 #      4 }
	ret	($26)													   # 000004
	.end 	$$1$max
	unop
	unop
	unop
	.loc 1 1
	.loc 1 6
 #      5  
 #      6 int
	.globl  main
	.ent 	main
	.loc 1 6
	.loc 1 7
 #      7 main(int argc, char *argv[])
main:															   # 000007
	.frame  $sp, 0, $26
	.prologue 0
	.loc 1 9
 #      8 {
 #      9         return max(1,5);
	.context full
	mov	5, $17													   # 000009
	mov	1, $16
	br	$$1$max
	.end 	main
	.loc 1 6

おおう、普通にmaxを呼び出してますね...

では待望の__inline版

$ more __inline.c

static __inline int
max(int i1, int i2) {
        return (i1 > i2) ? i1:i2;
}
 
int
main(int argc, char *argv[])
{
        return max(1,5);
}
$ cc -S __inline.c
                                                                                                                                                                                                  
$ more __inline.s                                                                                                                                                                                                   
	.set noat
	.set noreorder
	.text
	.arch	generic
	.align 4
	.file 1 "__inline.c"
	.loc 1 6
 #      6 int
	.globl  main
	.ent 	main
	.loc 1 6
	.loc 1 7
 #      7 main(int argc, char *argv[])
main:															   # 000007
	.frame  $sp, 0, $26
	.prologue 0
	.loc 1 3
	.context full
	mov	5, $0													   # 000003
	.loc 1 10
 #      8 {
 #      9         return max(1,5);
 #     10 }
	ret	($26)													   # 000010
	.end 	main
	.loc 1 6

おーっ!インライン展開されています!

というわけで、Compaq C Compilerの場合、関数指定子inlineを__inlineと定義すれば、最適化をかけなくてもインライン展開されるということがわかりました〜
(もちろん普通?のinlineの場合でも最適化をかけるとインライン展開される)

ちなみにコンパイラgccを使った場合は、関数指定子inline、__inlineどちらを使っても結果は変わりませんでした〜
(もちろん最適化をかけると、どちらもインライン展開される)

$ gcc -v 
Using built-in specs.
Target: alphaev68-dec-osf5.1b
Configured with: ./configure --enable-languages=c,c++ --enable-threads=posix --disable-nls --without-gnu-ld --with-ld=/usr/ccs/bin/ld --without-gnu-as --with-as=/usr/bin/as --disable-libssp
Thread model: posix
gcc version 4.4.7 (GCC) 
$ /usr/local/bin/gcc -S __inline.c
  
$ more __inline.s                                                                                                                                                                                                   
	.file	1 "__inline.c"
	.verstamp 3 11
	.set noreorder
	.set volatile
	.set noat
	.arch ev6
	.text
	.align 2
	.ent max
$max..ng:
max:
	.frame $15,32,$26,0
	.mask 0x4008000,-32
	lda $30,-32($30)
	stq $26,0($30)
	stq $15,8($30)
	bis $31,$30,$15
	.prologue 0
	bis $31,$16,$2
	bis $31,$17,$1
	stl $2,16($15)
	stl $1,20($15)
	ldl $2,20($15)
	ldl $1,16($15)
	cmple $2,$1,$3
	cmoveq $3,$2,$1
	addl $31,$1,$1
	bis $31,$1,$0
	bis $31,$15,$30
	ldq $26,0($30)
	ldq $15,8($30)
	lda $30,32($30)
	ret $31,($26),1
	.end max
	.align 2
	.globl main
	.ent main
main:
	.frame $15,32,$26,0
	.mask 0x4008000,-32
	ldgp $29,0($27)
$main..ng:
	lda $30,-32($30)
	stq $26,0($30)
	stq $15,8($30)
	bis $31,$30,$15
	.prologue 1
	bis $31,$16,$1
	stq $17,24($15)
	stl $1,16($15)
	lda $16,1($31)
	lda $17,5($31)
	bsr $26,$max..ng
	bis $31,$0,$1
	bis $31,$1,$0
	bis $31,$15,$30
	ldq $26,0($30)
	ldq $15,8($30)
	lda $30,32($30)
	ret $31,($26),1
	.end main

うーむ、libarchiveにこの修正を突っ込んだ人はどこで発見したんですかね?
有名な話なのかな?

Linux、隣は何をするひとぞ

TwitterのTLでよく見かける"どんかん"というキーワード

よく見てみると、発言しているのはlinux kernel developerの人が多いようです。

彼らは何を考え、何を行っているのでしょうか?今晩はその生態を探って見たいと思います...

と、意味深な書き出しをしましたが、きっかけはTLに流れてきたedvakfさんの

というツイートでした。

自分の観測する範囲だとBSDの人は結構な割合で備忘録を残している気がします。

↓BeBOX!
NetBSD/bebox porting notes

↓つつい師匠3連発
The far way to the facilitated eventual NetBSD/news68k port

togetter.com

togetter.com

↓しゅううさんは自分の中ではMIPSの偉い人なので
syuu1228.hatenablog.com

もちろん自分も可能な限り備忘録を残してきました。

togetter.com

nullnilaki.hatenablog.com

nullnilaki.hatenablog.com

自分がこのような記録を残しておく理由は
1.あとでネタにする
2.他人が調べものに来たときに参考になるように
3.人が試行錯誤の結果、失敗したり成功したりする内容は読み物として単純に面白い

からです。

ですが、このようなパッチ投稿の記録などLinuxではあまり見たことがなかったので、まずはLinux界隈でのお作法についてUNIX警察のn_sodaさんに聞いてみました。

そうすると、親切にもsatoru_takeuchiさんが教えてくださいました。
satoru_takeuchiさん、改めましてありがとうございます。

う〜ん、残念ながらLinuxのパッチ投稿記みたいなものは無いみたいです。
みなさんお仕事でカーネル書いているから、必要無いのかもしれませんね...
それとも文化が違うのかしら?

n_sodaさんがLinuxのパッチの書き方の資料を見つけてくださったので、
自分がLinuxにパッチを投げる時が来たら、備忘録を付けつつ頑張ってみたいと思いました!

Tru64 UNIXで遊ぼう!(C99編)

Tru64 UNIXでpkgsrcを動かそうと必死こいて作業していると、面白いエラーに遭遇しました。


libverify.c: In function 'fmt_time':
libverify.c:678: warning: incompatible implicit declaration of built-in function 'llabs'
libverify.c: In function 'read_ssh_file':
libverify.c:2354: error: expected ')' before 'PRIi64'
*** Error code 1
gcc -lssl -lcrypto -L/root/pkgsrc/bootstrap/work/wrk/pkgtools/pkg_install/work/bzip2 -L/root/pkgsrc/bootstrap/work/wrk/pkgtools/pkg_install/work/zlib -L/root/pkgsrc/bootstrap/work/wrk/pkgtools/pkg_install/work/libarchive/.libs -L/root/pkgsrc/bootstrap/work/wrk/pkgtools/pkg_install/work/libfetch -L/root/pkgsrc/bootstrap/work/wrk/pkgtools/pkg_install/work/netpgpverify -L/root/pkgsrc/bootstrap/work/wrk/pkgtools/pkg_install/work/libnbcompat -L/usr/lib -Wl,-R/usr/lib -Wl,-R/root/pkgsrc/bootstrap/pkg/lib -L../lib -o pkg_add main.o perform.o -linstall -lnetpgpverify -larchive -lbz2 -lz -lfetch -lssl -lcrypto -lcrypto -lbz2 -lz -lnbcompat -lnbcompat
strtoull
collect2: ld returned 1 exit status
*** [pkg_add] Error code 1

あれ? Tru64 UNIXCompaq CはC99に対応しているはず...

下記マニュアルにも
Compaq C Version 6.4 provides most of the language-feature support for the new C99 standard
と書いてあります

Tru64 UNIX

しかし、リンカがエラーを吐いているという事は、ライブラリがstrtoullをサポートしていないとしか考えられない?

というわけでCompaq Cのリリースノートを見てみました!
すると衝撃的な事が...

    6.1 New C99 library functions
       
	The Compac C compiler kit ships system header files that declare new
	ANSI/ISO C99 library names such as round, roundf, and roundl (math.h).

	The C99 header files install into /usr/include.dtk.  This directory is
	added to the compiler's #include search path automatically by the cc
	driver so that the header files will be read during "normal" compiles.

	The header files declare ALL of the new C99 names even though many of
	those functions do not yet exist in the libraries of shipping versions
	of Tru64 UNIX.  The names are reserved by the C99 Standard and the
	library functions will become available in future versions of the OS.

工エエエエエエェェェェェェ(゚Д゚)ェェェェェェエエエエエエ工工工

ヘッダファイルはC99に対応したけど、ライブラリは対応してないだと...

C99用の/usr/include.dtk/inttypes.hを見ると

$ more /usr/include.dtk/inttypes.h                                                                                                                                                             
/*
 * *****************************************************************
 * *                                                               *
 * *    Copyright 2001 Compaq Computer Corporation                 *
 * *                                                               *
...
/* begin - fprintf macros for signed integers */
#define PRId8		"d"
#define PRId16		"d"
#define PRId32		"d"
#define PRId64		"ld"
...

なので

#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>
 
int
main(void)
{
  int64_t data = 12345;
 
  printf("data=%"PRId64"\n",data);
  return EXIT_SUCCESS;
  
}

gccは対応していない...
(/usr/include.dtkを見に行かないので...)

$ /usr/local/bin/gcc meso.c                                                                                                                                                                    
meso.c: In function 'main':
meso.c:10: error: expected ')' before 'PRId64'

Compaq Cは対応している
(/usr/include.dtkを見に行く)

$ cc meso.c
$ ./a.out                                                                                                                                                                                      
data=12345

または、C99用の/usr/include.dtk/stdlib.hを見ると

$ more /usr/include.dtk/stdlib.h                                                                                                                                                               
/*
 * ********************************************************************************
 * *                                                                              *
 * *    Copyright 2002 Compaq Information Technologies Group, L.P.                *
...
    extern unsigned long long int strtoull(
    		const char * /*restrict*/ __nptr,
    		char ** /*restrict*/ __endptr,
    		int __base);
....

なので

#include <stdio.h>
#include <stdlib.h>

#define BASE 0

int
main(void)
{
   char *string, *stopstring;
   unsigned long long x;

   string = "255";
   printf("string = %s\n", string);
   x = strtoull(string, &stopstring, BASE);
   printf("strtoull = %llu \n", x);
   return EXIT_SUCCESS;
}

gccもCompaq Cもリンカがエラーを出力

$ /usr/local/bin/gcc foo.c                                                                                                                                                                     
strtoll
collect2: ld returned 1 exit status

$ cc foo.c                  
ld:
Unresolved:
strtoll

2006年リリースのTru64 UNIX 5.1B-4でC99に対応していない状態で
2010年リリースのTru64 UNIX 5.1B-6が最終リリースなので
Tru64 UNIXはC99に対応していない、がファイナルアンサーという事なんでしょうかねぇ?
教えて、教えてエロイ人

     ____________
    ヾミ || || || || || || || ,l,,l,,l 川〃彡|
     V~~''-山┴''''""~   ヾニニ彡|       C99に対応したライブラリを出す・・・・・・!
     / 二ー―''二      ヾニニ┤       出すが・・・
    <'-.,   ̄ ̄     _,,,..-‐、 〉ニニ|       今回 まだ その時と場所の
   /"''-ニ,‐l   l`__ニ-‐'''""` /ニ二|       指定まではしていない
   | ===、!  `=====、  l =lべ=|
.   | `ー゚‐'/   `ー‐゚―'   l.=lへ|~|       そのことを
    |`ー‐/    `ー――  H<,〉|=|       どうか諸君らも
    |  /    、          l|__ノー|       思い出していただきたい
.   | /`ー ~ ′   \   .|ヾ.ニ|ヽ
    |l 下王l王l王l王lヲ|   | ヾ_,| \     つまり・・・・
.     |    ≡         |   `l   \__   我々がその気になれば
    !、           _,,..-'′ /l     | ~'''  対応は
‐''" ̄| `iー-..,,,_,,,,,....-‐'''"    /  |      |    10年後 20年後ということも
 -―|  |\          /    |      |   可能だろう・・・・・・・・・・ということ・・・・!
    |   |  \      /      |      |

Tru64 UNIXで遊ぼう!(開発環境編)

Tru64 UNIXをインストールし終わったら、せっかくなので開発環境を整えましょう。
まずは標準コンパイラCompaq_C_Compilerをインストールします。

とてもありがたいことにHPが無料で公開しています。

HP Software - Developers' Toolkit Supplement - Software Kit Downloads

マニュアルも公開してあります。

Tru64 UNIX

インストールは簡単です。

Compaq_C_Compilerは優秀ですが、gccでなければコンパイルできないアプリケーションが沢山ありますので、gccもインストールします。

方法は

Compiling GCC 4.4.7 on Tru64 5.1B | Astrobaby's random thoughts

に書いてありますが、自分も参考で書いておきます。

Gnu tarをインストールします。

Tru64 UNIX標準のtarでは下記のようなLongLinkエラーが発生して大抵のtar ballの展開に失敗するからです。

バージョンは1.26を使ってください。


次はlibiconvをインストールします。


次はgmpをインストールします。


次はmpfrをインストールします。


次はGnu makeをインストールします。


ここまできたらgccコンパイルを行います。

プロセスのメモリの使用制限に引っかかってコンパイルに失敗しました。

その場合は/etc/sysconfigtabに

proc:
 per_proc_stack_size = 33554432
 per_proc_data_size = 801326592

と書いて回避します。
(リブートが必要)

うまくいけば、gccコンパイルに成功するはずです。

今回はソースからのインストールを行いましたが、面倒くさがり屋さんのためにパッケージも用意してあります。

Index of pub/pkgsrc/misc/tnn/index.html

pkgsrcは素晴らしい!
ただし、パッケージ版gccを使うにしてもGnu tarのインストールは必須です。

Tru64 UNIXで遊ぼう!(インストール編)

今は亡きDECの遺産、OSF/1ことDigital UNIXことTru64 UNIXで遊ぼうというという記事です。

ユーザーが少なくなってきて、記事が散逸し始めているので、基礎的なことをまとめておきます。

インストール編とタイトルに書きましたが、インストールする前に大事なことが1つあります。

Tru64 UNIXはライセンスが無いとまともに動きません。
ヤフオクなどでOSのメディアは時々出品されていますが、ライセンスが付いていないことがほとんどです。
ライセンス付きのTru64 UNIXが出品されていれば、死ぬ気でゲットしましょう。
最低限必要なライセンスはOSF-BASE、OSF-USR、OSF-SVR、OSF-DEVです。

Tru64 UNIXを新し目のハードにインストールする場合は、New Hardware Delivery kits(NHD)というCDが必須です。
Tru64 UNIXメディアセットに同梱されていますが、無い場合はHPが無料で公開しているので、焼いて使いましょう。

Tru64 UNIX New Hardware Delivery Online Documentation

インストールは以下のNHDのCD1枚とTru64 UNIXのインストールCD1枚の計2枚をとっかえひっかえして進めていきます。

インストーラにTru64 UNIXのCDを要求されてもCDドライブに入れてはいけない場合など罠が満載なので、以下のマニュアルを熟読して進めてください。

NHD for Version 5.1B Installation Instructions

インストール時に英語の他に追加で使用する言語を選択できますが、自分の場合は日本語を選択するとグラフィカルインストールに失敗するという罠に陥っていまいました。
グラフィカルインストールを行う場合は追加の言語で日本語を選ばないほうが良いかもしれません。
テキストインストールならば追加の言語で日本語を選択しても問題ありません。
グラフィカルインストールとテキストインストールの切り替えは
SRM画面で

>>set console graphics
>>set console serial

で切り替えできます。

Tru64 UNIXインストーラが標準で割り当てるHDDのパーティションの容量が少ないので、後で悶絶必死です。
(以下の例だと/が384MBしかない)

必ずパーティションは切り直しておきましょう。
(以下の例だとパーティションaが/で15GB、パーティションbがswapで1GB、パーティションgが/usrで10GB、パーティションdがLSMの予備で8GB)

一度インストールが完了すると、リブートがかかり、インストーラが自動でパッチを当て始めます。

パッチ当てが終わると再々度リブートがかかり、インストールは完了です。

とっても高性能だけれど、いまいち影が薄いAdvFSで遊んだり、スピードメーターを出したりして遊びましょう。

Tru64 UNIXの管理コマンドはsysmanです。

登録するユーザーはsuする場合はGroupはsystemにしておきます。

【夢を超えた】Mac版XM6iを使ってNetBSD/x68kを動かすという話【夢の、頂きへ】

急にお金M68Kアーキテクチャコンパイルされたバイナリが必要になることってありますよね。

そんなときあなたならどうしますか?
誰かに借りるにしても、理由を説明して頭を下げないといけない・・何より人間関係が気まずくなるのだけは避けたいものですよね。
そんなあなたにおすすめなのが、即日融資でお金を借りるXM6iにNetBSD/x68kをインストールしてコンパイルする方法です。

XM6iとは?

XM6i - クロスプラットフォーム X68000/X68030 エミュレータだそうです。
XM6i - クロスプラットフォーム X68000/X68030 エミュレータ

X68000/X68030というのは1987年3月28日にシャープが発売したパーソナルコンピューターだそうです。
X68000 - Wikipedia

オープンソースカンファレンス広島のjapan netbsd users groupのブースでは毎年X68000/X68030を使って、すごーい!たーのしー!ことをやっているので、興味がある人は見に行ってみると変なスイッチが入ったり入らなかったりするかもしれません。
OSC2016広島 (2016/11/27) 発表スライド

インストール方法とMac版の問題

配布元のダウンロードページに
http://xm6i.org/download.html

Mac 版について

ver 0.53 から SDL2 を使用しているため、 サウンドなし版、あり版の区別はなくなりました。 
Mac OS X 10.8 でビルドし、10.11 でも動作を確認しています。 それ以外のバージョンについては分かりません。
 

とあったので、ダウンロードして、展開し、バイナリを実行したところ、異常終了してしまいました。

とっても困っていたところ、@LabDrunkerさんに"MacPortsを使ってGCC5を入れて、/opt/local/lib以下のlibstdc++が使われるようにしたら、動くようになりました。"という貴重なアドバイスを頂きました。

どうして、この解決方法に気づいたのか質問してみたところ、

とのご回答をいただきました。ぼんくら物理学者... だと... こいつ…かなりの切れ者...

確かにotoolを使ってxm6iがリンクしている共有ライブラリを調べてみると、/opt/loca/lib以下のlibstdc++が使われているようです。

実験として/opt/localを掘って/usr/libにシンボリックリンクをはってみましたが、xm6iが異常終了してしまいました。

これは@LabDrunkerもおっしゃっていますが、gcc5からlibstdc++ではデフォルトで新しいABIを利用するようになっているためと思われます。(そしてMac版xm6iはgcc5を使ってコンパイルされているためと思われます)

早速MacPortsから、gcc5をインストールしてみました。



問題が解決したので、XM6iが起動するようになりました!

NetBSD/x68kのインストール

早速準備が整ったので、NetBSD/x68kをインストールしてみます。

やり方は、@tsutsuiiさんのページに詳しい方法が書いてありますので、参考にしてください。
NetBSD/x68k on XM6i ver 0.41 - クロスプラットフォーム X68000/X68030 エミュレータ

インストールCD ISOイメージ

http://ftp7.jp.NetBSD.org/pub/NetBSD/iso/6.1.3/ の
iso ディレクトリ内の NetBSD-6.1.3-x68k.iso (約162MB) をダウンロードして c:\XM6i\NetBSD\ に置く。

もちろん、OSのバージョンは適宜読み替えてください。

インストールには数時間かかりますが、きっとうまくいくはず... です...

↓ちなみに失敗例

無事インストールすることが出来ました!

失敗した原因は


です。

よって、ノリでインストールしなければ、インストールに時間はかかるものの問題無くNetBSD/x68k on XM6i Mac版の環境を楽しむことが出来ます!

Mac版XM6iのネットワークの設定は

 Mac OS X 版では Nereid イーサネットエミュレーションのホスト側に bpf(4)
  を使用しており、ホストマシンを介して外部ネットワークとの通信が可能です。
  ただし Mac OS X 側の制約によりホストマシン自身との通信は行えません

とあります。

Mac版のXM6iを試すような人にパソコンを一台しか持っていない人なんていないと思いますので、問題ないと思います。

ああ・・次はpkgsrcだ...

ママー。NetBSDのRAMDISK Kernelの/dev/consoleはどこから来るの?という話

この記事は
NetBSD Advent Calendar 2016 - Qiita 24日目の記事です。
すいません、ておくれました。26日目ということにしてください...

N君がある日RS/6000にNetBSD/ofppcをインストールしようとすると奇妙な事が起こりました。

/dev/consoleが無いというエラーが出てだんまりしています...

調べてみたところ、エラーを出力しているのは
https://nxr.netbsd.org/xref/src/sys/kern/init_main.c#870
のようです。

どういうことなのでしょう?

@tsutsuiiさんにアドバイスを頂きました!

つまりユーザーランド側から/sbin/initが/dev/consoleを開いて文字の読み書きを始めようにも、/dev/consoleが無いのでカーネルが警告を出しているわけですね。
そこで疑問になるのが、RAMDISK Kernelの/dev/consoleはどうやって作っているのだろうか?という事です。

これについても@tsutsuiiさんにアドバイスを頂きました。

なるほど!/dev/consoleが出来るパターンには2パターンあるようです。

というわけで、早速調べてみました!

例えば、NetBSD/i386をCDからbootさせて、/devを見てみると...

とMAKEDEVスクリプトがあります。

また、iso-imageをマウントして中身を見てみると、MAKEDEVスクリプトがあります。

では、別のポートとしてNetBSD/alphaをCDからbootさせて、/devを見てみると...

今度はMAKEDEVスクリプトありません

つまり、

NetBSD/i386は"init(8) が自力で /dev 以下を mfs でマウントして /dev/console その他を自分で作る"パターン
NetBSD/alphaは"makefs(8) -Fのspec ファイルで定義されたデバイスファイルをファイルシステムイメージとして持っている"パターン

になるわけですね。

/sbin/initでMAKEDEVスクリプトから/dev/consoleを作っているところは
https://nxr.netbsd.org/xref/src/sbin/init/init.c?r=1.107#1647
です。

試しに下記のmakefileをいじって、-DMFS_DEV_IF_NO_CONSOLEを外してやれば、
Cross Reference: /src/sbin/init/Makefile
/sbin/initが/dev/consoleを作ることが出来ないので、下記の様になるわけです。

では、このMAKEDEVスクリプトはどこから来ているのでしょうか?

試しに
Cross Reference: /src/etc/MAKEDEV.tmpl

mkdev		console c %cons_chr% 0	600

をコメントしてみると、

のように
warning : no /dev/console
のエラーが出ています。

また、iso-imageをマウントしてMAKEDEVの中身を見てみると、

mkdev		console c %cons_chr% 0	600

がコメントしてあります。

(右枠がソース、左枠がiso-imageのMAKEDEV)

また、NetBSD/alphaも同じように
warning : no /dev/console
のエラーが出ています。

つまり、
"init(8) が自力で /dev 以下を mfs でマウントして /dev/console その他を自分で作る"パターンでも
"makefs(8) -Fのspec ファイルで定義されたデバイスファイルをファイルシステムイメージとして持っている"パターンでも
元ネタは
/src/etc/MAKEDEV.tmpl
だということがわかります。

では、どこで/dev/MAKEDEVスクリプトを作っているのかというと、
NetBSD/i386の場合は、
Cross Reference: /src/distrib/common/Makefile.makedev
になります。

NetBSD/alphaの場合は、/dev/以下をどこで作っているのかというと
Cross Reference: /src/distrib/common/Makefile.makedev
になります。

NetBSD/alphaの場合、
Cross Reference: /src/distrib/alpha/instkernel/ramdisk/Makefile

MAKEDEVTARGETS=	minimal


Cross Reference: /src/etc/etc.alpha/MAKEDEV.conf
で定義されていて、

makedev std bpf

のstdが
Cross Reference: /src/etc/MAKEDEV.tmpl
MAKEDEV.tmplのstdで定義されています。

したがって、NetBSD/ofppcの場合、下記のようなパッチを作れば...
gist.github.com
ほら

warning : no /dev/consoleが出なくなりました〜

でもこの記事は片手落ちです。
続きはお正月休みにでも書こうと思います。