Я пытаюсь отредактировать файл внутри /proc/devices
- дерево, чтобы быть точным, и я не могу сделать так, я добираюсь:
"разрешение, отклоненное" или "ошибка ввода/вывода".
Я попробовал все возможные комбинации редакторов, chown
, chmod
и даже sudo dd
. Я также знаю, что местоположение хорошей памяти пишет в 7000c400
в шестнадцатеричном числе. Я должен заменить 4 байта там, есть ли любой метод, который может помочь мне достигнуть этого.
Править: Чего я пытаюсь достигнуть путем попытки этого?
У меня есть плата Jetson-TK1, и шина i2c установлена на значение по умолчанию 400kHz
, но я хочу выполнить его в 100kHz
. Я думаю, что могу сделать это путем изменения структуры дерева устройств и перекомпиляции, но перекомпиляция является намного большей головной болью, поскольку ядро, которое я использую, не является стандартным (Nvidia не обеспечивает это).
Я считал где-нибудь, что в Linux почти все в форме файла. Так ища его, я нашел файл, который содержит 4 байта, который оценивает к 400000
, Я думаю, изменяя этот файл, изменил бы частоту.
Теперь настоящая проблема, я не мог изменить ее (я думаю, что я - достаточно достойный пользователь и насколько я понимаю, если существует что-то в памяти, и у меня есть все виды паролей, я должен смочь изменить ее. То то, что я порчу что-то, не является вопросом). Я попробовал все возможные методы, известные мне (как я добавил в вопросе). Таким образом, как я делаю это.
Я изучил это главным образом для забавы и для изучения (и надо надеяться для представителя!). Мне жаль, что у меня не могло быть еще некоторого времени для проигрывания с ioctl
(благодаря Sneetsher для предложения) и с тем, что я сделал до сих пор для создания более изящного решения, но щедрость собирается истечь и маловероятно, что я могу сделать все вовремя, таким образом, я отправляю это решение, "как это" (по крайней мере на данный момент).
Я не знаю, которые являются последствиями изменения чего-то в /proc/device-tree
, таким образом, если Вы действительно знаете то, что Вы делаете, продолжайте читать.
Эта конкретная реализация этого решения требует рабочего ядра> 3.10. Это включает компиляцию пользовательского модуля ядра и выполнение a 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
строка должна быть заменена a 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
)bash
сценарий: ./switch.sh
cat /proc/device-tree
видеть результат/proc/
псевдо файловая система: когда Вы чтение-запись на любом /proc/file
Вы не получаете доступ к реальному файлу или реальной памяти, но Вы вызываете некоторую определенную функцию ядра (в зависимости от файла), который действует как файл. Это возвращает данные при чтении файла установите данные, если Вы пишете в файл. И если не будет никакой функции, определяемой записи для определенного файла, то писание в файл ничего не изменит.
В этом случае /proc/device-tree
путь состоит в том, чтобы считать дерево устройств, предоставленное рабочему ядру в то время как его начальная загрузка. (никакое разрешение записи)
Кроме того, в настоящее время, дерево устройств является конфигурацией только для чтения, Вы не можете обновить его после начальной загрузки. И для Вашего конкретного случая, значения, настраивающие Ваш i2c
читаются и используются когда i2c
зондируется ('установленный'). Если Вы хотите реконфигурировать i2c
, Вам нужно, как сказано joshumax, для использования корректного ioctl
на i2c
устройство (в /dev/
где некоторая определенная "запись драйвера" определяется),
Еще одно решение состоит в том, чтобы создать новое дерево устройств, настроив I2C
устройство, как Вы хотите. И спросите, ядро (проверьте загрузчик, который Вы используете) использовать дерево устройств, которое Вы просто скомпилировали.
Вам будет нужно rootly использование полномочий sudo для этого. Попробуйте это: можно использовать gdb (Отладчик GNU) работающий как корень для управления содержанием памяти. Они могут заинтересовать Вас:
http://sourceware.org/gdb/current/onlinedocs/gdb/
https://stackoverflow.com/questions/3305164/how-to-modify-memory-contents-using-gdb