Сообщение Re: Модуль ядра Linux от 05.06.2024 0:07
Изменено 05.06.2024 0:13 aik
Re: Модуль ядра Linux
Здравствуйте, maks1180, Вы писали:
M>Я новичёк в режиме ядра и я взял пример chrdev модуля Linux, работает нормально.
M>При чтении устройста данные пользователю отправляет через put_user, в функции
M>static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset)
Непонятно. device_read есть только в fs/dlm/user.c, но там нет put_user.
M>если я в этой функции попытаюсь записать или прочитать из buffer, то получаю ошибку в ядре,
M>хотя я проверил: указатель buffer валидный и он одинаковый и в режиме ядра и в режиме пользователя.
M>перед вызовом read() в режиме ядра буфер проинициализировал.
Проинициализировал как? Нулями не считается. Запиши туда ненули, а потом что там тебе нужно.
M>Сначала я подумал, что модуль работает не в 0-кольце, но проверил два младших бита регистра CS, всё в порядке, модуль в 0 кольце, программа в 3-м кольце.
M>В чём может быть дело ? Почему в режиме ядра я не могу напрямую обращаться к памяти пользовательского режима ?
Можешь, только памяти может не быть на месте (не выделена ещё или в свопе), и тогда будет page fault, который окей если это пользовательская память (тогда ядро вытащит страницу из свопа или наконец выделит память, и повторит чтение), или не окей, если это память самого ядра — тогда будет краш. Эти все put_user() — они чтоб ядро различало чья это память. Можно попробовать перед чтением вызвать get_user_pages_fast() (а потом не забыть put_page()).
M>Я новичёк в режиме ядра и я взял пример chrdev модуля Linux, работает нормально.
M>При чтении устройста данные пользователю отправляет через put_user, в функции
M>static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset)
Непонятно. device_read есть только в fs/dlm/user.c, но там нет put_user.
M>если я в этой функции попытаюсь записать или прочитать из buffer, то получаю ошибку в ядре,
M>хотя я проверил: указатель buffer валидный и он одинаковый и в режиме ядра и в режиме пользователя.
M>перед вызовом read() в режиме ядра буфер проинициализировал.
Проинициализировал как? Нулями не считается. Запиши туда ненули, а потом что там тебе нужно.
M>Сначала я подумал, что модуль работает не в 0-кольце, но проверил два младших бита регистра CS, всё в порядке, модуль в 0 кольце, программа в 3-м кольце.
M>В чём может быть дело ? Почему в режиме ядра я не могу напрямую обращаться к памяти пользовательского режима ?
Можешь, только памяти может не быть на месте (не выделена ещё или в свопе), и тогда будет page fault, который окей если это пользовательская память (тогда ядро вытащит страницу из свопа или наконец выделит память, и повторит чтение), или не окей, если это память самого ядра — тогда будет краш. Эти все put_user() — они чтоб ядро различало чья это память. Можно попробовать перед чтением вызвать get_user_pages_fast() (а потом не забыть put_page()).
Re: Модуль ядра Linux
Здравствуйте, maks1180, Вы писали:
M>Я новичёк в режиме ядра и я взял пример chrdev модуля Linux, работает нормально.
M>При чтении устройста данные пользователю отправляет через put_user, в функции
M>static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset)
Непонятно. device_read есть только в fs/dlm/user.c, но там нет put_user.
M>если я в этой функции попытаюсь записать или прочитать из buffer, то получаю ошибку в ядре,
M>хотя я проверил: указатель buffer валидный и он одинаковый и в режиме ядра и в режиме пользователя.
M>перед вызовом read() в режиме ядра буфер проинициализировал.
Проинициализировал как? Нулями не считается. Запиши туда ненули, а потом что там тебе нужно. Я всю последнюю фразу не понял
Это вызов в режиме ядра, или инициализировал в режиме ядра?
M>Сначала я подумал, что модуль работает не в 0-кольце, но проверил два младших бита регистра CS, всё в порядке, модуль в 0 кольце, программа в 3-м кольце.
M>В чём может быть дело ? Почему в режиме ядра я не могу напрямую обращаться к памяти пользовательского режима ?
Можешь, только памяти может не быть на месте (не выделена ещё или в свопе), и тогда будет page fault, который окей если это пользовательская память (тогда ядро вытащит страницу из свопа или наконец выделит память, и повторит чтение), или не окей, если это память самого ядра — тогда будет краш. Эти все put_user() — они чтоб ядро различало чья это память. Можно попробовать перед чтением вызвать get_user_pages_fast() (а потом не забыть put_page()).
M>Я новичёк в режиме ядра и я взял пример chrdev модуля Linux, работает нормально.
M>При чтении устройста данные пользователю отправляет через put_user, в функции
M>static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset)
Непонятно. device_read есть только в fs/dlm/user.c, но там нет put_user.
M>если я в этой функции попытаюсь записать или прочитать из buffer, то получаю ошибку в ядре,
M>хотя я проверил: указатель buffer валидный и он одинаковый и в режиме ядра и в режиме пользователя.
M>перед вызовом read() в режиме ядра буфер проинициализировал.
M>Сначала я подумал, что модуль работает не в 0-кольце, но проверил два младших бита регистра CS, всё в порядке, модуль в 0 кольце, программа в 3-м кольце.
M>В чём может быть дело ? Почему в режиме ядра я не могу напрямую обращаться к памяти пользовательского режима ?
Можешь, только памяти может не быть на месте (не выделена ещё или в свопе), и тогда будет page fault, который окей если это пользовательская память (тогда ядро вытащит страницу из свопа или наконец выделит память, и повторит чтение), или не окей, если это память самого ядра — тогда будет краш. Эти все put_user() — они чтоб ядро различало чья это память. Можно попробовать перед чтением вызвать get_user_pages_fast() (а потом не забыть put_page()).