2014/03/01 (Sat) 22:52
ここまでsimhのPDP-11エミュレータにUNIX V7をインストールしてきましたが、やはり気になるのは日付関連です。
起動直後の状態はこんな感じになっています。
これを修正しようとするとこうなります。
1970年に戻ってしまいました。いわゆる2000年問題というやつですね。 また、タイムゾーンがEST(アメリカの東部標準時)になっているのも気になります。
今回はこの辺を直してみようと思います。
まず、OSのタイムゾーンの変更を行います。UNIX V7でタイムゾーンを変更するためには、ソースを修正したうえでカーネルを再構築する必要があります。修正するソースコードは/usr/sys/h/param.hです。今使っているSoftware Kitの環境では/mnt/usr/sys/h/param.hにあります(こちらの記事参照)。中身はこんな感じです。
ここの#define TIMEZONEで指定している値を日本時間に直します。
また、DSTFLAGでサマータイムの設定をしています。日本で使う場合は必要ないのでここを0に変えます。修正後は以下のようになります。
修正を行ったらカーネルを再構築します。このとき、makeだけではだめで、make allしてからmakeします。
とりあえずこれでOSは日本時間で動くようになりましたが、今のままではタイムゾーン表示ができません。タイムゾーンの表示のための処理は/usr/src/libc/gen/timezone.cにあります。
カーネルソースと違い、ライブラリやコマンドのソースはもとから入っています。 中身をみるとアメリカの各地区とGMTしかタイムゾーンの定義が入っていません。
これではどうしようもないのでタイムゾーンの定義に日本時間を表すJSTを追加します。
これでソースを再コンパイルします。
timezoneはlibc.aの一部なので、作成したオブジェクトでlibc.aの中身を置き換えます。
最後はdateコマンドの修正です。ソースは/usr/src/cmd/date.cです。問題の処理はgtime()関数にあり、入力された年を無条件で1900年代と扱うようになっています。今回はとりあえず年の値が50以下だったら2000年代と扱うようにします。
これをコンパイルして/bin/dateを置き換えます。
最後にカーネルを置き換えてリブートします。
リブート後のコマンド実行結果はこんな感じです。
date -uは日時をGMTで表示します。9時間差なのでうまくいったようです。
ほかにも2000年問題はあると思いますが、気になったら対処するということで今回はここまで。
[関連記事]
起動直後の状態はこんな感じになっています。
# date Thu Sep 22 05:47:43 EDT 1988
これを修正しようとするとこうなります。
# date 1403011921 Sun Mar 1 19:21:00 EST 1970 #
1970年に戻ってしまいました。いわゆる2000年問題というやつですね。 また、タイムゾーンがEST(アメリカの東部標準時)になっているのも気になります。
今回はこの辺を直してみようと思います。
まず、OSのタイムゾーンの変更を行います。UNIX V7でタイムゾーンを変更するためには、ソースを修正したうえでカーネルを再構築する必要があります。修正するソースコードは/usr/sys/h/param.hです。今使っているSoftware Kitの環境では/mnt/usr/sys/h/param.hにあります(こちらの記事参照)。中身はこんな感じです。
# cat param.h
/* * tunable variables */ #define NBUF 29 /* size of buffer cache */ #define NINODE 200 /* number of in core inodes */ #define NFILE 175 /* number of in core file structures */ #define NMOUNT 8 /* number of mountable file systems */ #define MAXMEM (64*32) /* max core per process - first # is Kw */ #define MAXUPRC 25 /* max processes per user */ #define SSIZE 20 /* initial stack size (*64 bytes) */ #define SINCR 20 /* increment of stack (*64 bytes) */ #define NOFILE 20 /* max open files per process */ #define CANBSIZ 256 /* max size of typewriter line */ #define CMAPSIZ 50 /* size of core allocation area */ #define SMAPSIZ 50 /* size of swap allocation area */ #define NCALL 20 /* max simultaneous time callouts */ #define NPROC 150 /* max number of processes */ #define NTEXT 40 /* max number of pure texts */ #define NCLIST 100 /* max total clist size */ #define HZ 60 /* Ticks/second of the clock */ #define TIMEZONE (5*60) /* Minutes westward from Greenwich */ #define DSTFLAG 1 /* Daylight Saving Time applies in this locality */ #define MSGBUFS 128 /* Characters saved from error messages */ #define NCARGS 5120 /* # characters in exec arglist */ (略)
ここの#define TIMEZONEで指定している値を日本時間に直します。
また、DSTFLAGでサマータイムの設定をしています。日本で使う場合は必要ないのでここを0に変えます。修正後は以下のようになります。
#define TIMEZONE (-9*60) /* Minutes westward from Greenwich */ #define DSTFLAG 0 /* Daylight Saving Time applies in this locality
修正を行ったらカーネルを再構築します。このとき、makeだけではだめで、make allしてからmakeします。
# cd /mnt/usr/sys/conf # make all cd ../sys; cc -c -O *.c; mklib; rm *.o acct.c: (略) # make as -o mch.o mch0.s mch.s ld -o unix -X -i l.o mch.o c.o ../sys/LIB1 ../dev/LIB2 #
とりあえずこれでOSは日本時間で動くようになりましたが、今のままではタイムゾーン表示ができません。タイムゾーンの表示のための処理は/usr/src/libc/gen/timezone.cにあります。
カーネルソースと違い、ライブラリやコマンドのソースはもとから入っています。 中身をみるとアメリカの各地区とGMTしかタイムゾーンの定義が入っていません。
# cd /usr/src/libc/gen # cat timezone.c
/* * The arguments are the number of minutes of time * you are westward from Greenwich and whether DST is in effect. * It returns a string * giving the name of the local timezone. * * Sorry, I don't know all the names. */ static struct zone { int offset; char *stdzone; char *dlzone; } zonetab[] = { 4*60, "AST", "ADT", /* Atlantic */ 5*60, "EST", "EDT", /* Eastern */ 6*60, "CST", "CDT", /* Central */ 7*60, "MST", "MDT", /* Mountain */ 8*60, "PST", "PDT", /* Pacific */ 0, "GMT", 0, /* Greenwich */ -1 }; (略)
これではどうしようもないのでタイムゾーンの定義に日本時間を表すJSTを追加します。
(略) static struct zone { int offset; char *stdzone; char *dlzone; } zonetab[] = { 4*60, "AST", "ADT", /* Atlantic */ 5*60, "EST", "EDT", /* Eastern */ 6*60, "CST", "CDT", /* Central */ 7*60, "MST", "MDT", /* Mountain */ 8*60, "PST", "PDT", /* Pacific */ -9*60, "JST", 0, ← 追加 0, "GMT", 0, /* Greenwich */ -1 }; (略)
これでソースを再コンパイルします。
# cc -c -O timezone.c
timezoneはlibc.aの一部なので、作成したオブジェクトでlibc.aの中身を置き換えます。
# cd /lib # cp libc.a libc.a.org # ar r libc.a /usr/src/libc/gen/timezone.o
最後はdateコマンドの修正です。ソースは/usr/src/cmd/date.cです。問題の処理はgtime()関数にあり、入力された年を無条件で1900年代と扱うようになっています。今回はとりあえず年の値が50以下だったら2000年代と扱うようにします。
(略) gtime() { (略) if (hour==24) { hour=0; day++; } if (hour<0 hour="">23) return(1); timbuf = 0; /* fix y2k */ /*year += 1900;*/ ← ここを修正 if (year > 50){ year += 1900; } else{ year += 2000; } /* fix y2k end */ for(i=1970; i<year; i++) timbuf += dysize(i); /* Leap year */ if (dysize(year)==366 && month >= 3) timbuf++; while(--month) timbuf += dmsize[month-1]; timbuf += day-1; timbuf = 24*timbuf + hour; timbuf = 60*timbuf + mins; timbuf = 60*timbuf + secs; return(0); }
これをコンパイルして/bin/dateを置き換えます。
# cd /usr/src/cmd # cc -o date date.c # mv /bin/date /bin/date.org # cp ./date /bin/
最後にカーネルを置き換えてリブートします。
# cp /mnt/usr/sys/conf/unix /unix # sync;sync;sync; # (Ctrl-E)
リブート後のコマンド実行結果はこんな感じです。
# date 1403012025 Sat Mar 1 20:25:00 JST 2014 # date Sat Mar 1 20:25:02 JST 2014 # date -u Sat Mar 1 11:25:07 GMT 2014
date -uは日時をGMTで表示します。9時間差なのでうまくいったようです。
ほかにも2000年問題はあると思いますが、気になったら対処するということで今回はここまで。
[関連記事]
- [simh-pdp11]UNIX V7からLinuxにメールを送ってみる
- [simh-pdp11]UNIX V7とLinuxでUUCP(2)
- [simh-pdp11]UNIX V7とLinuxでUUCP(1)
- [simh-pdp11]UNIX V7に外部からTELNETできるようにする part2
- [simh-pdp11]UNIX V7に外部からTELNETできるようにする
- [simh-pdp11] UNIX V7をテープイメージからインストールする
- [simh-pdp11] Version 7 Unixをインストールする
- simhをインストールしてみる
ランキングに参加してみました。クリックしていただければ嬉しいです。
にほんブログ村 |
パソコン ブログランキングへ |
PR
Comment
プロフィール
HN:
zui
性別:
非公開
カテゴリー
最新記事
(09/28)
(09/03)
(08/26)
(07/23)
(05/24)
PR
忍者カウンター