Запись в определенную ячейку памяти

Я пытаюсь отредактировать файл внутри /proc/devices- дерево, чтобы быть точным, и я не могу сделать так, я добираюсь:

"разрешение, отклоненное" или "ошибка ввода/вывода".

Я попробовал все возможные комбинации редакторов, chown, chmod и даже sudo dd. Я также знаю, что местоположение хорошей памяти пишет в 7000c400 в шестнадцатеричном числе. Я должен заменить 4 байта там, есть ли любой метод, который может помочь мне достигнуть этого.

Править: Чего я пытаюсь достигнуть путем попытки этого?

  • У меня есть плата Jetson-TK1, и шина i2c установлена на значение по умолчанию 400kHz, но я хочу выполнить его в 100kHz. Я думаю, что могу сделать это путем изменения структуры дерева устройств и перекомпиляции, но перекомпиляция является намного большей головной болью, поскольку ядро, которое я использую, не является стандартным (Nvidia не обеспечивает это).

    Я считал где-нибудь, что в Linux почти все в форме файла. Так ища его, я нашел файл, который содержит 4 байта, который оценивает к 400000, Я думаю, изменяя этот файл, изменил бы частоту.

  • Теперь настоящая проблема, я не мог изменить ее (я думаю, что я - достаточно достойный пользователь и насколько я понимаю, если существует что-то в памяти, и у меня есть все виды паролей, я должен смочь изменить ее. То то, что я порчу что-то, не является вопросом). Я попробовал все возможные методы, известные мне (как я добавил в вопросе). Таким образом, как я делаю это.

5
задан 29 March 2015 в 03:27

3 ответа

Я изучил это главным образом для забавы и для изучения (и надо надеяться для представителя!). Мне жаль, что у меня не могло быть еще некоторого времени для проигрывания с ioctl (благодаря Sneetsher для предложения) и с тем, что я сделал до сих пор для создания более изящного решения, но щедрость собирается истечь и маловероятно, что я могу сделать все вовремя, таким образом, я отправляю это решение, "как это" (по крайней мере на данный момент).

Отказ от ответственности:

Я не знаю, которые являются последствиями изменения чего-то в /proc/device-tree, таким образом, если Вы действительно знаете то, что Вы делаете, продолжайте читать.

Эта конкретная реализация этого решения требует рабочего ядра> 3.10. Это включает компиляцию пользовательского модуля ядра и выполнение a bash сценарий для выполнения своего рода горячего переключателя между /proc/device-tree и пользовательский файл device-tree_new.

Пределы:

  1. После удаления модуля, пользовательского /proc/device-tree это удалено! Другая причина прочитать правовую оговорку снова.
  2. Пользовательское /proc/device-treeбуфер имеет предел 65535 персонажи. Все по 65535 символ является усеченным. Для корректировки размера буфера измените следующее постоянное определение и объявление переменной в исходном коде модуля:

    1. #define MAX_BUFFER_SIZE 65535
    2. static unsigned int proc_buffer_length_v; (так, чтобы это могло содержать число> 65535)

Как это работает:

Сам модуль:

  • удаляет /proc/device-tree
  • создает новый пробел /proc/device-tree с полномочиями 0666

bash сам сценарий:

  1. Загружает модуль
  2. Вписывает /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

Инструкции:

  1. Открытый a Terminal с Ctrl+Alt+t
  2. Создайте новую папку: mkdir <folder_name>
  3. Измените текущий рабочий каталог на новую папку: cd <folder_name>
  4. Создайте эти три файла выше использования тех же самых имен, включенных между двойными кавычками
  5. Создайте пользовательское device-tree файл и имя это device-tree_new
  6. Mark"switch.sh"как исполняемый файл: chmod a+x switch.sh
  7. Скомпилируйте модуль: make (два предупреждения будут брошены gcc)
  8. Запуститесь bash сценарий: ./switch.sh
  9. cat /proc/device-tree видеть результат
3
ответ дан 23 November 2019 в 09:13

/proc/ псевдо файловая система: когда Вы чтение-запись на любом /proc/file Вы не получаете доступ к реальному файлу или реальной памяти, но Вы вызываете некоторую определенную функцию ядра (в зависимости от файла), который действует как файл. Это возвращает данные при чтении файла установите данные, если Вы пишете в файл. И если не будет никакой функции, определяемой записи для определенного файла, то писание в файл ничего не изменит.

В этом случае /proc/device-tree путь состоит в том, чтобы считать дерево устройств, предоставленное рабочему ядру в то время как его начальная загрузка. (никакое разрешение записи)

Кроме того, в настоящее время, дерево устройств является конфигурацией только для чтения, Вы не можете обновить его после начальной загрузки. И для Вашего конкретного случая, значения, настраивающие Ваш i2c читаются и используются когда i2c зондируется ('установленный'). Если Вы хотите реконфигурировать i2c, Вам нужно, как сказано joshumax, для использования корректного ioctl на i2c устройство (в /dev/ где некоторая определенная "запись драйвера" определяется),

Еще одно решение состоит в том, чтобы создать новое дерево устройств, настроив I2C устройство, как Вы хотите. И спросите, ядро (проверьте загрузчик, который Вы используете) использовать дерево устройств, которое Вы просто скомпилировали.

2
ответ дан 23 November 2019 в 09:13

Вам будет нужно rootly использование полномочий sudo для этого. Попробуйте это: можно использовать gdb (Отладчик GNU) работающий как корень для управления содержанием памяти. Они могут заинтересовать Вас:

http://sourceware.org/gdb/current/onlinedocs/gdb/

https://stackoverflow.com/questions/3305164/how-to-modify-memory-contents-using-gdb

1
ответ дан 23 November 2019 в 09:13

Другие вопросы по тегам:

Похожие вопросы: