2008年12月27日

[Linux] Process ID (PID) から CR3 値を得る自作システムコール

カーネル空間内で,プロセスIDからそのプロセスのページディレクトリの物理アドレスを得るシステムコールを作った.

arch/x86/kernel/pid2cr3.c (システムコール本体)

#include <linux/pid2cr3.h>
#include <linux/sched.h>
#include <linux/pid.h>

asmlinkage unsigned long sys_pid2cr3(int pid) {
  struct task_struct *p;
  p = pid_task(find_vpid(pid), PIDTYPE_PID);
  if (p && (p->active_mm != NULL))
    return __pa((unsigned long) (p->active_mm->pgd));
  else
    return 1;
}

/usr/include/linux/pid2cr3.h

#ifndef NR_PID2CR3_H
#define NR_PID2CR3_H

#include <linux/unistd.h>
#include <sys/syscall.h>

#define pid2cr3(pid) syscall(__NR_pid2cr3, pid)

#endif

include/linux/pid2cr3.h

#ifndef NR_PID2CR3_H
#define NR_PID2CR3_H

#include <linux/unistd.h>
#include <linux/linkage.h>

#define pid2cr3(pid) syscall(__NR_pid2cr3, pid)

#endif

あとは適当に.

おまけ Pythonから上記システムコールを使うためのモジュール

#include <Python.h>
#include <linux/pid2cr3.h>

static PyObject * get_cr3(PyObject *self, PyObject *args) {
	int ok, pid;
	ok = PyArg_ParseTuple(args, "i", &pid);
	return PyLong_FromUnsignedLong(pid2cr3(pid));
}

// module method tbl init
static PyMethodDef SpamMethods[] = {
  { "pid2cr3", get_cr3, METH_VARARGS, "get CR3 value from PID" },
  {NULL, NULL, 0, NULL},
};

PyMODINIT_FUNC initpid2cr3(void) {
  PyObject *m;
  m = Py_InitModule("pid2cr3", SpamMethods);
}
posted by dev-man at 19:51| Comment(0) | TrackBack(0) | Linux | このブログの読者になる | 更新情報をチェックする

2008年12月16日

[Linux] メモリに物理アドレスでアクセスする

カーネルをいじっていて,物理アドレスでメモリにアクセスする必要がでた.

かなり強引技だけど,仮想メモリのアドレスをそのまま物理メモリアドレス変換するページテーブルを作成してみた.
# もっとスマートなやりかたないですかねー...?
#include <linux/module.h>
#include <linux/init.h>
#include <asm/page.h>
#include <linux/pagemap.h>


// 物理メモリにアクセスするためのページテーブル
void *linear_pagedir = NULL;


/*
 * 物理メモリにアクセスするためのページテーブルを作成
 * (最初に1回これを呼ぶ)
 */
void
linear_pagedir_init(void) {
	struct page *pagedir_page;
	ulong pde_template, pde;
	int i;
	ulong *pd;

	pagedir_page = alloc_page(GFP_ATOMIC | __GFP_ZERO);
	linear_pagedir = page_address(pagedir_page);
	pd = (ulong *) linear_pagedir;

	pde_template = (1 << 7) + (1 << 1) + (1 << 0);

	for (i = 0; i < 1024; i++) {
		pde = pde_template | (i << 22);
		pd[i] = pde;
	}
}

/*
 * 物理メモリを1ワード読む
 * phys_addr: 読みたい物理アドレス
 * val: 読み出す変数
 *
 * 事前にlinear_pagedir_init()を呼んでおく必要あり.
 */
asmlinkage void
read_phys_mem (ulong phys_addr, ulong *val) {
	ulong tmpcr3 = (ulong) __pa(linear_pagedir);
	asm volatile (
			"mov %%cr3, %%eax\n\t"
			"mov %1, %%cr3\n\t"
			"mov (%2), %%ebx\n\t"
			"mov %%eax, %%cr3\n\t"
			"mov %%ebx, %0"
			: "=r" (*val)
			: "r" (tmpcr3), "r" (phys_addr)
			: "%eax", "%ebx", "cc"
	);
}


/**
 * 物理メモリにアクセスするためのページテーブルを開放
 * (最後に1回これを呼ぶ)
 */
void
linear_pagedir_free(void) {
	if (linear_pagedir == NULL) {
		// no need to free
	} else {
		free_page((ulong)linear_pagedir);
		linear_pagedir = NULL;
	}
}

posted by dev-man at 15:36| Comment(0) | TrackBack(0) | Linux | このブログの読者になる | 更新情報をチェックする

[C言語] gccプリプロセッサにおいて,マクロの引数を展開せずに文字列として出力

#マクロ引数名
で,引数に渡された変数名・定数名などがそのまま文字列になる.

例えば, 
#define ANPAN 1
#define SHOKUPAN 2
#define I_LOVE(pan) printf("i love " #pan)
ここで,
I_LOVE(ANPAN);
とかくと,
printf("i love " "ANPAN"); // prints "i love ANPAN"
に展開されます. ログ出力は定数やenumの値よりもその名前を出したかったりするから,そんな時に便利.
# "i love 1" と表示されても困る.
posted by dev-man at 15:20| Comment(0) | TrackBack(0) | C言語 | このブログの読者になる | 更新情報をチェックする

[JavaScript] 別フレームのonloadイベントをフックする

別フレームで外部のページを表示し,そのonloadイベントをフックしたいときは,frameタグにonload属性を書けば良いみたい.
当該フレームで新しいページがロードされる度に,イベントが発生します.

<frame name="left" onload="alert("ロード完了")" />
posted by dev-man at 15:05| Comment(0) | TrackBack(0) | JavaScript | このブログの読者になる | 更新情報をチェックする

2008年12月04日

[小道具] 英英辞書と ALC を同時に引く

欲しかったので JavaScript で書いてみた.

とのぺでぃあ
http://foofighters/tonopedia/
tonopedia.png

とりあえず研究室内限定公開で.

ぜひ右上の「ブラウザの検索ボックスに追加」をクリック!
posted by dev-man at 13:50| Comment(0) | TrackBack(0) | 小道具 | このブログの読者になる | 更新情報をチェックする

2008年11月25日

Intel Virtualization Technology (Intel VT) のBIOS設定を変えても駄目なら

今日は新鮮なネタがないので若干古いネタ。

BIOS設定画面でIntel Virtualization Technology (Intel VT) を Enabled にしても、反映されない。

よく画面をみてみると・・・
vt.jpg

再起動するだけでなく、一度電源を切る必要があるのですな。
posted by dev-man at 23:27| Comment(0) | TrackBack(0) | 仮想化 | このブログの読者になる | 更新情報をチェックする

[ヒトリゴト] Billy band

今日は実家から下宿に向かう途中、池袋と渋谷でひっさしぶりの買い物。

買ったもの:
・ビリーバンド
・その他もろもろww

IMG_0456-1.JPG


話はかわって、電車に乗ってる時間って、なんだか色々アイディア浮かびますね。
実家から大学に通っていた頃は、通学時間=無駄な時間 だと思って、一人暮らし始めたけど。。。

明日からまた研究がんばるぞー!
posted by dev-man at 00:40| Comment(2) | TrackBack(0) | ヒトリゴト | このブログの読者になる | 更新情報をチェックする

2008年11月04日

[仮想化] GCCのインラインアセンブラからSIDT命令を実行 (Red Pillを実行)

Red Pillの方式でやると,セグメンテーション違反を起こす事があるので,インラインアセンブラから実行する方法.
#include <stdio.h>

struct {
        unsigned short limit;
        unsigned int base;
} __attribute__ ((packed)) idtr;

int main(int argc, char * argv[])
{
  asm ("sidt %0" : "=m" (idtr));
  printf("IDTR base=0x%X limit=0x%X\n",(int)idtr.base, (int)idtr.limit);
}

posted by dev-man at 13:48| Comment(0) | TrackBack(0) | 仮想化 | このブログの読者になる | 更新情報をチェックする

[仮想化] LVM環境でBitvisorを使用する

GRUBのmenu.lstを以下のように記述する.

default=0
timeout=5
splashimage=(hd0,2)/grub/splash.xpm.gz
hiddenmenu
title Fedora (2.6.23.1-42.fc8)
	root (hd0,2)
	kernel /vmlinuz-2.6.23.1-42.fc8 ro root=/dev/VolGroup00/LogVol00 rhgb quiet
	initrd /initrd-2.6.23.1-42.fc8.img
title BitVisor
	root (hd0,2)
	kernel /bitvisor-0.3.elf ro root=/dev/VolGroup00/LogVol00 rhgb quiet
title Other
	rootnoverify (hd0,0)
	chainloader +1

捕捉:

root=/dev/VolGroup00/LogVol00
で指定された領域がファイルシステムの /boot にマッピングされているため,
kernel /bitvisor-0.3.elf
でイメージを指定できる.

ちなみに,なぜかBitvisor上でWindowsが起動しない.
LVMのせいか?

posted by dev-man at 13:29| Comment(0) | TrackBack(0) | 仮想化 | このブログの読者になる | 更新情報をチェックする

2008年10月29日

[仮想化] Thinkpad X60でIntel VTを有効にする

  1. ThinkVAntage System Updateを起動する
  2. ThinkPad BIOS Updateを選択し,アップデート.
  3. アップデート完了後,再起動し,BIOS画面を表示
  4. BIOS画面でVTを有効にして設定を保存

おまけ
画像を回転するFirefoxプラグイン
https://addons.mozilla.org/en-US/firefox/addon/7113

posted by dev-man at 14:02| Comment(0) | TrackBack(0) | 仮想化 | このブログの読者になる | 更新情報をチェックする