/proc/devices
- tree内のファイルを正確に編集しようとしていますが、編集できません。
「許可が拒否されました」または「入出力エラー」。
chown
、chmod
、さらにはSudo dd
のエディターのすべての可能な組み合わせを試しました。 16進数で7000c400
に書き込む正確なメモリの場所も知っています。私はそこに4バイトを置き換える必要がありますが、これを達成するのに役立つ方法がありますか?.
編集:これを試して達成しようとしていることは何ですか?
Jetson-TK1ボードがあり、i2cバスが設定されています400kHz
のデフォルトに設定しますが、100kHz
で実行したいです。デバイスツリー構造と再コンパイルを変更することでそれができると思いますが、使用しているカーネルは標準のものではないため、再コンパイルは非常に大きな頭痛の種です(nvidiaはそれを提供していません)。
Linuxでは、ほとんどすべてのものがファイルの形であると読んでいた。それを探して、400000
と評価される4バイトを含むファイルを見つけました。このファイルを変更すると頻度が変わると思います。
今、本当の問題は、それを変更できなかったことです(私はまともなユーザーだと思います、そして私が理解する限り、メモリに何かがあり、あらゆる種類のパスワードを持っているなら、私はそれを変更できるはずです。私が何かを台無しにするという事実は問題ではありません)。私が知っているすべての可能な方法を試しました(質問に追加しました)。だから私はそれをどのように行うのですか?.
私はこれを主に楽しみと学習のために(そしてできれば担当者のために!)調べました。 ioctl
(提案をしてくれたSneetsherに感謝します)ともっとエレガントなソリューションを作るためにこれまでやったことで遊ぶ時間があればいいのですが、賞金はもうすぐ切れます。時間内にすべてを作成できる可能性は低いため、このソリューションを「現状のまま」投稿しています(少なくとも現時点では)。
何かを/proc/device-tree
に変更することの結果がわからないので、自分が何をしているのか本当にわかっているなら、読み続けてください。
このソリューションのこの特定の実装には、3.10以上の実行中のカーネルが必要です。これには、カスタムカーネルモジュールのコンパイルとbash
スクリプトの実行が含まれ、/proc/device-tree
とカスタムファイルdevice-tree_new
の間で一種のホットスイッチを実行します。
制限:
/proc/device-tree
が削除されます! 免責事項を再度読む別の理由。カスタム/proc/device-tree
のバッファには、65535
文字の制限があります。 65535
文字を超えるものはすべて切り捨てられます。バッファのサイズを調整するには、モジュールのソースコードで次の定数定義と変数宣言を変更します。
#define MAX_BUFFER_SIZE 65535
static unsigned int proc_buffer_length_v;
(数字を保持できるように> 65535
)モジュール自体:
/proc/device-tree
/proc/device-tree
パーミッション付き0666
bash
スクリプト自体:
/proc/device-tree
にdevice-tree_new
のコンテンツを書き込みますこれは、モジュールの "Makefile
" Makefile
です(各make
行の先頭にあるすべての空白は、TAB
文字に置き換える必要があります):
obj-m += proc_module.o
all:
make -C /lib/modules/$(Shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(Shell uname -r)/build M=$(PWD) clean
これは、モジュールの「proc_module.c
」ソースファイルです。
#include <linux/module.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#define DEBUG 1
#define MAX_BUFFER_SIZE 65535
static struct proc_dir_entry* proc_dir_entry_p;
static struct file_operations file_operations_s;
static char* proc_buffer_p;
static unsigned int proc_buffer_length_v;
static unsigned short int read_flag;
int read_proc(struct file* file, char* buffer, size_t count, loff_t* offset) {
if(DEBUG) printk(KERN_INFO "read_proc() called.\n");
if(read_flag)
read_flag = 0;
else {
read_flag = 1;
return 0;
}
copy_to_user(buffer, proc_buffer_p, proc_buffer_length_v);
if(DEBUG) printk(KERN_INFO "Ok. (count = %zu)\n", count);
return proc_buffer_length_v;
}
int write_proc(struct file* file, char* buffer, size_t count, loff_t* offset) {
size_t n;
if(DEBUG) printk(KERN_INFO "write_proc() called.\n");
if(count >= MAX_BUFFER_SIZE) {
if(DEBUG) printk(KERN_INFO "write_proc(): Buffer exceeded!\n");
n = MAX_BUFFER_SIZE;
}
else
n = count;
kfree(proc_buffer_p);
if(DEBUG) printk(KERN_INFO "kfree() called.\n");
if(!(proc_buffer_p = (char*)kmalloc(MAX_BUFFER_SIZE*sizeof(char), GFP_KERNEL))) {
if(DEBUG) printk(KERN_INFO "kmalloc() ko.\n");
return count;
}
if(DEBUG) printk(KERN_INFO "kmalloc() ok.\n");
copy_from_user(proc_buffer_p, buffer, n);
proc_buffer_length_v = n;
if(DEBUG) printk(KERN_INFO "Ok. (count = %zu)\n", count);
return count;
}
static int __init init_f(void) {
if(DEBUG) printk(KERN_INFO "Module inserted.\n");
remove_proc_entry("device-tree", NULL);
if(!(proc_dir_entry_p = proc_create("device-tree", 0666, NULL, &file_operations_s))) {
if(DEBUG) printk(KERN_INFO "Proc entry not created.\n");
return -1;
}
if(DEBUG) printk(KERN_INFO "Proc entry created.\n");
file_operations_s.read = read_proc;
file_operations_s.write = write_proc;
if(!(proc_buffer_p = (char*)kmalloc(1*sizeof(char), GFP_KERNEL))) {
if(DEBUG) printk(KERN_INFO "kmalloc() ko.\n");
return -1;
}
if(DEBUG) printk(KERN_INFO "kmalloc() ok.\n");
proc_buffer_p[0] = '\0';
proc_buffer_length_v = 0;
read_flag = 1;
if(DEBUG) printk(KERN_INFO "Ok.\n");
return 0;
}
static void __exit exit_f(void) {
kfree(proc_buffer_p);
if(DEBUG) printk(KERN_INFO "kfree() called.\n");
proc_remove(proc_dir_entry_p);
if(DEBUG) printk(KERN_INFO "Proc entry removal requested.\n");
if(DEBUG) printk(KERN_INFO "Module removed.\n");
}
module_init(init_f);
module_exit(exit_f);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kos");
MODULE_DESCRIPTION("proc_module");
これは「switch.sh
」bash
スクリプトです。
#!/bin/bash
Sudo rmmod proc_module.ko
Sudo insmod proc_module.ko && cat device-tree_new > /proc/device-tree
Terminal
を開きます Ctrl+Alt+tmkdir <folder_name>
cd <folder_name>
device-tree
ファイルを作成し、device-tree_new
という名前を付けますswitch.sh
」を実行可能としてマーク:chmod a+x switch.sh
make
(gcc
によって2つの警告がスローされます)bash
スクリプトを起動します:./switch.sh
cat /proc/device-tree
は結果を見るために/proc/
は擬似ファイルシステムです。/proc/file
で読み取り/書き込みを行う場合、実際のファイルまたは実際のメモリにはアクセスしませんが、機能する特定のカーネル関数(ファイルに応じて)を呼び出しますファイルとして。ファイルを読み取るとデータを返し、ファイルに書き込むとデータを設定します。また、特定のファイルに対して書き込み関数が定義されていない場合、ファイルへの書き込みは何も変更しません。
この場合、/proc/device-tree
は、起動中に実行中のカーネルに提供されたデバイスツリーを読み取る方法です。 (書き込み許可なし)
また、現在、デバイスツリーは読み取り専用の構成であり、起動後に更新することはできません。また、特定のケースでは、i2c
がプローブ(「インストール」)されたときに、i2c
を構成する値が読み取られて使用されます。 i2c
を再構成する場合は、前述のjoshumaxで、i2c
デバイスで特定の[ドライバーエントリ]が定義されている/dev/
デバイスで正しいioctl
を使用する必要があります。 )
他の解決策の1つは、I2C
デバイスを必要に応じて構成し、新しいデバイスツリーを構築することです。そして、コンパイルしたデバイスツリーを使用するようにカーネルに依頼します(使用しているブートローダーを確認します)。
そのためには、Sudoを使用するルート権限が必要です。これを試してください:rootとして実行されているgdb(GNUデバッガー)を使用して、メモリの内容を操作できます。これらはあなたに興味があるかもしれません:
http://sourceware.org/gdb/current/onlinedocs/gdb/
https://stackoverflow.com/questions/3305164/how-to-modify-memory-contents-using-gdb