linux's archives

CentOS 5にAspire Timeline (3810T)の有線LANドライバを入れる

by ginriki | 11 月 4th, 2009 

今年(2009年)の夏に、Aspire Timeline(3810T)を買いました。
元々Windows Vistaが入っていましたが、ついでにCentOS 5.31を入れてデュアルブートできるようにしました。

ただ、CentOS 5.3には (たぶん、CentOS 5.4にも) Aspire Timelineの有線LANドライバが入ってないので、ドライバを探してきて入れました。

ドライバは、http://partner.atheros.com/Drivers.aspxのAR81Family Linux Driverになります。私がダウンロードしたときは、AR81Family-linux-v1.0.0.10.tar.gzっていうバージョンでした。

いつの間にか、リンク切れになってました(partner.atheros.comのサイト自体なくなったようです)。12/2時点では、ドライバはここにあります。(katty9015さん、情報ありがとうございます)
ファイル名もAR81Family-linux-v1.0.0.10.tar.gzからAR81Family-linux-v1.0.1.0.tar.gzに変わったので、以下の記事を読むときは注意してください。

USBメモリとかでAspire TimelineのCentOS上にAR81Family-linux-v1.0.0.10.tar.gzを入れた後は、以下のようにコンパイル/インストールすれば、有線LANが使えるようになります。

$ tar xzvf AR81Family-linux-v1.0.0.10.tar
$ cd src/
$ make
$ make install       # 要root権限
$ reboot             # 再起動


おまけ (Intel VTの有効化)

Aspire Timeline(3810T)のCPUはIntel VTに対応してるのですが、BIOSで有効化できないため、そのままだとIntel VTが使えません。
とはいえ、CentOSのXenでWindowsが起動できないのも味気ないです。
以下の2つのリンク先を参考にいじれば、BIOSでIntel VTを有効にできます。Acerのサポート外になってしまうので、いじるときは自己責任でお願いします。

  1. 2009/10に、CentOS 5.4がリリースされましたね []

kprobes – カーネルへ動的にプローブ挿入

by ginriki | 7 月 13th, 2009 

Debug Hacksを読んでたら、kprobesっていうデバッグツールの話があった。
自分でモジュール作ってinsmodするだけで、カーネル再コンパイルなしで、ある実行地点でのカーネル内変数を調べるツールだそうで。

プロセスのユーザ空間(=デバッギのユーザ空間)に対してデバッガプロセスがプローブする場合は1

  1. デバッガプロセスがptrace辺りを使ってデバッギのメモリ空間上の指定アドレス上にあるアセンブリ命令をint 3に書き変えて2
  2. デバッギプロセス実行中にそのint 3命令実行して発生したSIGTRAPをデバッガプロセスがフック(=これも事前にptraceで設定する)して
  3. デバッガプロセスがptraceでデバッギプロセスのメモリ空間から値をread

っていう流れが普通だと思う。kprobes.cのコメントを見てみると、kprobesの場合もカーネルの指定命令アドレスにint 3を入れてるらしい。

/*
 * Called after single-stepping.  p->addr is the address of the
 * instruction whose first byte has been replaced by the "int 3"
 * instruction.  To avoid the SMP problems that can occur when we
 * temporarily put back the original opcode to single-step, we
 * single-stepped a copy of the instruction.  The address of this
 * copy is p->ainsn.insn. ...
 * ...
 */

ただ、SMPの関係で色々対策が必要なんだね3。int 3を実行した後、例外ベクタにジャンプしてからどういう手順で処理してるかについてイメージがわかないから、今度ソース読んでみようかな。

あと、kprobesだと見たい変数(とくにローカル変数などCPUアーキテクチャとデバッグ情報からアドレスを割り出す必要のあるもの)のアドレスを探すのが大変だけど、
kprobes+GDBでそこを解決しようとしてるのがtracepointsってやつらしい。ふむふむ。

  1. 以前、デバッガについて書いた記事もどうぞ。 []
  2. int 3はIA-32とかIntel architectureの場合の話です []
  3. デバッギプロセスにプローブする場合に必要なマルチスレッド対策とどの程度一緒なのかは、まだよくわからない。 []

crashコマンド使ってみた

by ginriki | 7 月 13th, 2009 

Kernelのコアダンプファイルを解析するのに、crashコマンドが便利だという話を聞いたので、練習として触ってみました。

手元にCentOS 5のマシンがあるので、それを使います。

解析にあたってkernelのデバッグ情報がいるので、debuginfoのRPMをインストールします1

 $ uname -a
Linux localhost.localdomain 2.6.18-128.1.16.el5 #1 SMP Tue Jun 30 06:10:28 EDT 2009 i686 i686 i386 GNU/Linux

 $ wget http://debuginfo.centos.org/5/i386/kernel-debuginfo-2.6.18-128.1.16.el5.i686.rpm
 $ wget http://debuginfo.centos.org/5/i386/kernel-debuginfo-common-2.6.18-128.1.16.el5.i686.rpm
 $ rpm -ivh kernel-debuginfo-common-2.6.18-128.1.16.el5.i686.rpm kernel-debuginfo-2.6.18-128.1.16.el5.i686.rpm

んで、crashコマンド実行。
SVR4 UNIXのcrashコマンドをベースにGDBを統合したやつだそうで2、GDBになじんでる私には結構使いやすいです。

CODE:
  1. $ crash
  2.       KERNEL: /usr/lib/debug/lib/modules/2.6.18-128.1.16.el5/vmlinux
  3.     DUMPFILE: /dev/crash
  4.         CPUS: 1
  5.         DATE: Mon Jul 13 02:17:05 2009
  6.       UPTIME: 06:52:42
  7. LOAD AVERAGE: 0.16, 0.03, 0.01
  8.        TASKS: 86
  9.     NODENAME: localhost.localdomain
  10.      RELEASE: 2.6.18-128.1.16.el5
  11.      VERSION: #1 SMP Tue Jun 30 06:10:28 EDT 2009
  12.      MACHINE: i686  (1197 Mhz)
  13.       MEMORY: 758.9 MB
  14.          PID: 3848
  15.      COMMAND: "crash"
  16.         TASK: ef67c000  [THREAD_INFO: d9120000]
  17.          CPU: 0
  18.        STATE: TASK_RUNNING (ACTIVE)
  19.  crash> set 1
  20.     PID: 1
  21. COMMAND: "init"
  22.    TASK: c16f5aa0  [THREAD_INFO: c16f6000]
  23.     CPU: 0
  24.   STATE: TASK_INTERRUPTIBLE
  25.  crash> p $tmp = jiffies
  26.   $1 = 24873000
  27.  crash> x modprobe_path
  28.   0xc0680be0 <modprobe_path>:     das
  29.  crash> show convenience
  30.    $tmp = 24873000
  31.    $__ = void
  32.    $_ = (examine_i_type *) 0xc0680be0 "/sbin/modprobe"
  33.  crash> exit

gdbスクリプトをsourceで読み込むこともできる。
まだ、まともな使い方は全然してないけど、Debug Hacksにいろいろ書いてあるので、それを読みながらやる予定。

Debug Hacks -デバッグを極めるテクニック&ツール Debug Hacks -デバッグを極めるテクニック&ツール
レビューを見る
欲しいものリストに追加
価格:3456円 在庫あり。powered by Amazon.co.jp

  1. 最初、yumでinstallしたら、なぜか2.6.18-92.1.6.el5.centos.plusが入りました。kernelバージョンと合ってないので、rpmコマンドで入れなおし。 []
  2. Crash WhitepaperのAbstract参照 []

dmesgによるHDDデバイス名探し

by ginriki | 8 月 10th, 2008 

ひさびさ更新。

今回は、HDDデバイス名をdmesgコマンドで調べる時の事を考えてみます。
dmesgで出力されるメッセージは結構長いので、grepなどの検索を利用したいのですが、HDDがPATA(=IDE)接続のときと、SATA接続のときで、検索パターンを変えないといかんです。そのパターンについて以下に記述。

なお、以下の方法はLinux Kernel2.6系の話です。
Linux Kernel2.4系だと、SATAもhdaとかで認識するらしいので。

* HDDがPATAの場合
dmesg | grep hdを使います。

$ dmesg | grep hd
    ide0: BM-DMA at 0x1810-0x1817, BIOS settings: hda:DMA, hdb:pio
hda: TOSHIBA MK4025GASL, ATA DISK drive
hda: max request size: 128KiB
hda: 78140160 sectors (40007 MB), CHS=65535/16/63, UDMA(100)
hda: cache flushes supported
 hda: hda1
SCSI device sda: 40088160 512-byte hdwr sectors (20525 MB)
SCSI device sda: 40088160 512-byte hdwr sectors (20525 MB)

hda: TOSHIBA MK4025GASL, ATA DISK drive
っていうところで、型番がわかります。

* HDDがSATA接続の場合
HDDはsd~で認識されるので、dmesg | grep sd としたいところですが、
それだと型番が表示されません。とはいえ、grep sdで引っかかる行の直前に型番が表示されるので、
dmesg | grep -B 5 sd
として、grepでマッチした行の前5行分も表示すると良いでしょう。lessで見ながら検索するのもお勧め。

$ dmesg | grep -B 5 sd
ata1.00: ATA-8: Hitachi HDP725050GLA360, GM4OA52A, max UDMA/133
ata1.00: 976773168 sectors, multi 16: LBA48 NCQ (depth 0/32)
ata1.00: configured for UDMA/133
  Vendor: ATA       Model: Hitachi HDP72505  Rev: GM4O
  Type:   Direct-Access                      ANSI SCSI revision: 05
SCSI device sda: 976773168 512-byte hdwr sectors (500108 MB)
sda: Write Protect is off
sda: Mode Sense: 00 3a 00 00
SCSI device sda: drive cache: write back
SCSI device sda: 976773168 512-byte hdwr sectors (500108 MB)
sda: Write Protect is off
sda: Mode Sense: 00 3a 00 00
SCSI device sda: drive cache: write back
 sda: sda1 sda2 sda3
sd 0:0:0:0: Attached scsi disk sda
--
ata4.00: configured for UDMA/133
  Vendor: HL-DT-ST  Model: DVDRAM GH20NS10   Rev: EL00
  Type:   CD-ROM                             ANSI SCSI revision: 05
  Vendor: ATA       Model: ST3750640AS       Rev: 3.AA
  Type:   Direct-Access                      ANSI SCSI revision: 05
SCSI device sdb: 1465149168 512-byte hdwr sectors (750156 MB)
sdb: Write Protect is off
sdb: Mode Sense: 00 3a 00 00
SCSI device sdb: drive cache: write back
SCSI device sdb: 1465149168 512-byte hdwr sectors (750156 MB)
sdb: Write Protect is off
sdb: Mode Sense: 00 3a 00 00
SCSI device sdb: drive cache: write back
 sdb: unknown partition table
sd 3:0:0:0: Attached scsi disk sdb
--
...

まず、注目する箇所は以下、
Vendor: ATA Model: Hitachi HDP72505 Rev: GM4O
Type: Direct-Access ANSI SCSI revision: 05

自分の経験上、Vendor: ATA, Type: Direct-AccessだとHDDなのだと思います。
型番はModel: ~ と出力されるのですが、場合によって型番の末尾が省略されるので注意です。
今回の場合、型番の正式名称は、
ata1.00: ATA-8: Hitachi HDP725050GLA360, GM4OA52A, max UDMA/133
の行のHDP725050GLA360になります。

もうひとつのHDDは省略されておらず、
Vendor: ATA Model: ST3750640AS Rev: 3.AA
Type: Direct-Access ANSI SCSI revision: 05
から、ST3750640ASになります。

SATA HDDがsda等として認識される理由 (SCSIに見える理由)

http://okwave.jp/qa3351535.htmlより引用:

    カーネルのファイルシステムの階層構造の問題で,
    SATAの最下層のデバイスドライバsata-strageなどがその上位のプロトコルドライバとしてscsi_modを指定しているためです。
    つまりアプリから見るとSCSIディスクにみえるのはsata-strageがSCSIプロトコルをエミュレーションしているためです。

    これに対してIDEデバイスはディスクドライバとしてide-diskなどがありますからちゃんとIDEに見えます。

    USBメモリなども同じ理由でSCSIに見える場合が多いと思います。

HDDインターフェイスの名称

Wikipediaによると、
HDDインターフェイスの名称は出現年の古い順に
IDE(製品会社独自の規格名) -> ATA(統一規格名) -> SATA(統一規格名)、PATA(=ATA)
っていうことらしい。
IDEをベースにATA規格ができたから、IDE = ATAと呼ばれるようになったようです。
その後、新規格のSATAが出てきて、昔のATAをPATAと呼ぶようになったと。

ゼロ番地を先頭とするページにマップする

by ginriki | 6 月 28th, 2007 

mmapのflags引数にMAP_FIXEDフラグを指定することで、OSの実装によってはゼロ番地を先頭とするページにマップできます*1

たとえば、i386以降のCPU, Vine Linux 4.0, gcc-4.1.1を使った環境で以下のコードをコンパイルして実行するとゼロ番地にアクセスできます。

#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>

int main(){
int* p = (int*)mmap(0, getpagesize(), PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
*p = 1;

printf("*(int*)%d = %d\n", (int)p, *(int*)0);
return 0;
}

実行すると以下のようになります。

$ gcc main.c
$ ./a.out
*(int*)0 = 1
$

以下、注意点。

Cの仕様上では、start引数に0を指定しても数値の0を指すとは限りません。なぜなら、start引数の型はvoid*であり、Cの仕様ではポインタを書くべきところに書かれた0は、コンパイル時にヌル・ポインタに変換されることが保証されているからです*2(コンパイラがポインタ型の式だと判断できる場合のみ)。

なお、C++でもほとんど同様のようです*3。自分には、CとC++の違いは、C言語の場合、#define NULL (void*)0 か #define NULL 0 どちらでもありうるが、C++だと #define NULL (void*)0 がありえないということしかわかりませんでした。

よって、ハードウェア, OS, C/C++のコンパイラによっては、start引数で渡す値がコンパイル時に0ではない値に変換されているかもしれないので、ソースコードでstart引数に0を指定したからといって、実行時にmmapでマップされたページが必ずしもゼロ番地ではないかも知れないことに注意です。

以上、何の役に立つかわからないけど面白かったのでメモっときます。

ちなみにWindowsの場合、ゼロ番地から64KB分*4のアドレスをユーザプログラムのプログラマがVirtualAlloc APIで確保(予約)することはできません。これは、ヌル・ポインタが指すアドレス先に値を代入しようとしたときに、必ずメモリアクセス違反が発生するようにするために、意図的にそう決まっています*5

ということは、Windowsが動くような環境において、ヌル・ポインタが0と一致する(させる)のは当然だとMicrosoftは考えているのでしょうね。

*1:SUSv3では、「MAP_FIXEDフラグを指定した場合、start引数はマップされるページのヒントとなるアドレスではなく、マップさせたいページのアドレスを意味するようになり、マップに失敗した場合はエラーを返す」としか書いてありません。よって、startに0を指定した場合は必ず失敗するようにmmapを実装しても仕様を満たします。

*2http://www.kouno.jp/home/c_faq/c5.html 5.2項

*3:注解 C++ リファレンスマニュアル 4.6: ISBN 4901280392 といっても、これ古い仕様みたいですけど・・・

*4:Windows2000の場合。Windows98だと4KB分

*5:Advanced Windows 13.2 :ISBN 4-7561-3805-5

ブログで紹介した商品

  • Image of デバッガの理論と実装 (ASCII SOFTWARE SCIENCE Language)