LINUX.ORG.RU

Всё ли нормально в символьном устройстве?

 , ,


2

5

Вот код. При открытии устройства драйвер получает список процессов. При чтении с устройства в пользовательский буфер копируется часть данных, но я ещё не уверен, использовал *pos для указания откуда начать копировать данные, если их будет очень много, но наверное можно было бы и обойтись и без них.

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/sched.h>
#include <linux/string.h>
MODULE_LICENSE("Dual BSD/GPL");

dev_t dev;
int lock;
unsigned baseminor = 0;
unsigned count = 1;
unsigned scull_major = 0;
char *name = "scull";
struct scull_dev {
	int quantum;
	int qset;
	unsigned long size;
	unsigned int access_key;
	struct semaphore sem;
struct cdev cdev;
};
struct scull_dev *sdev;
char *data;

loff_t scull_llseek ( struct file *file, loff_t pos, int n )
{
}
ssize_t scull_read ( struct file *file, char __user *buf, size_t count, loff_t *pos)
{
	char *p;
	p = data;
	p += *pos;

	int len = strlen ( p );

	len = len > 4096 ? count : len;

	memset ( buf, 0, sizeof buf );
	
	copy_to_user ( buf, p, len ); 

	*pos += len;

	return len;
}
ssize_t scull_write ( struct file *file, const char __user *buf, size_t n, loff_t *lt )
{

}
int scull_open ( struct inode *inode, struct file *filp )
{
	if ( lock ) while ( lock ){};
	lock = 1;
	struct scull_dev *scdev;
	struct task_struct *task;

	scdev = container_of ( inode->i_cdev, struct scull_dev, cdev );
	filp->private_data = scdev;

	data = kmalloc ( 16386, GFP_USER );
	char *p, *h;
	p = data;
	int len = 0;

	for_each_process(task) 
	{
		h = &task->comm[0];
		for ( ; *h != 0 && len < 16384; p++, h++, len++ ) *p = *h;
		*p = 32;
		p++;
		len++;
		if ( len > 16384 ) break;
		printk ( "%s\n", task->comm );
	}
	*p = 0;

	return 0;
}
int scull_release ( struct inode *inode, struct file *file )
{
	kfree ( data );
	lock = 0;
	return 0;
}

struct file_operations scull = {
	.owner = THIS_MODULE,
	.llseek = scull_llseek,
	.read = scull_read,
	.write = scull_write,
	.open = scull_open,
	.release = scull_release
};

static int hello_init ( void )
{
	sdev = kmalloc ( sizeof ( struct scull_dev ), GFP_KERNEL );
	int err;
	int result = alloc_chrdev_region ( &dev, baseminor, count, name );
	scull_major = MAJOR(dev);
	cdev_init ( &sdev->cdev, &scull );
	sdev->cdev.owner = THIS_MODULE;
	sdev->cdev.ops = &scull;
	err = cdev_add ( &sdev->cdev, dev, 1 );
	if ( err )
		printk (KERN_NOTICE "Error %d adding scull%d", err, 0 );
	
}

static void hello_exit ( void )
{
	cdev_del ( &sdev->cdev );
	kfree ( sdev );
	unregister_chrdev_region ( dev, count );
}

module_init ( hello_init );
module_exit ( hello_exit );

memset ( buf, 0, sizeof buf );

Нас заинтересовали Ваши навыки в linux kernel, напишите нам на job@fbi.gov

anonymous
()

memset ( buf, 0, sizeof buf );

Если развернуть ответ анонимуса выше - ты этим очистишь первые 4 или 8 байт буфера, в зависимости от разрядности архитектуры.

Dark_SavanT ★★★★★
()

Слушай, где ты эти гайды по ядру нашел? Хочу побить гайдера за слишком невнятное объяснение о пороге вхождения.

narkoman228
()

А потом еще люди ( o-) говорят в соседней теме, что строгие языки (Rust) не нужны для разработки ядра. Как видно из этого примера, незнание языка C не мешает особо упорным индивидумам писать драйвера для linux. Только результат мы все понимаем.

pftBest ★★★★
()
Ответ на: комментарий от Dark_SavanT

У меня сообщения анонимусов не видно. Заменил на

*buf = 0;

А вот например в потоках для пользовательского простанства есть функция pthread_yield для того чтобы уступить другому процессу. А есть что нибудь такое для ядра?
Чтобы использовать вместо

while ( lock ){};

u0atgKIRznY5
() автор топика
Ответ на: комментарий от narkoman228

Побить

Хочешь превзойти и в знаниях по ядру и си, и в боевом искусстве? Обьясни, что ты имеешь ввиду о пороге вхождения? Я видел только один пример использования символьного драйвера и ещё немного смотрел код какого то драйвера в ядре. Сам додумываю как писать.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

Обьясни, что ты имеешь ввиду о пороге вхождения?

Он имеет в виду, что, прежде чем писать код для ядра, надо изучить нормально язык, на котором оно написано.

Deleted
()
Ответ на: комментарий от u0atgKIRznY5

какой язык ты изучал/использовал ранее? с тем же memset-ом ты пытаешься не первый раз сделать опасные странные вещи

хотя на самом деле там всё до безобразия просто, однако надо как-то въехать в это... может просто поиграть пока что в пользовательской программе с памятью на Си?

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от Dark_SavanT

ещё хуже.

Почему? Я же первому символу присваиваю ноль и всё. Если есть ещё данных, то они добавятся к buf, а в любом другом случае ничего не выводится. А как лучше?

u0atgKIRznY5
() автор топика
Ответ на: комментарий от pftBest

Как видно из этого примера, незнание языка C не мешает особо упорным индивидумам писать драйвера для linux.

Писать-то драйвера можно, но в ядро их все равно же не примут.

Deleted
()
Ответ на: комментарий от u0atgKIRznY5

У тебя в остальном буфере остаются старые данные от кого-то. Потенциальная дыра в безопасности.

Dark_SavanT ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

потому что sizeof buf, это не фига не размер буфера, а всего лишь размер указателя на него, причем возможно, что даже первое значение будет по размеру столько же сколько указатель.

Silerus ★★★★
()
Ответ на: комментарий от Deleted

Ну в ядро то может и не примут, но в какую-нибудь умную кофеварку могут и попасть.

pftBest ★★★★
()
Ответ на: комментарий от pftBest

Для ядра нужны не языки для дебилов, а строгий отсев оных, чтоб держать их подальше от ядра ) Вроде Торвальдс и ко более-менее справляются пока

Harald ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

А есть что нибудь такое для ядра?

Почти. Есть schedule(). Только в отличие от юзерспейса, в ядре его расставляют вручную там, где и правда нужно. А если ты в юзерспейсе что-то такое делаешь, это значит, что код — говно.

post-factum ★★★★★
()
Ответ на: комментарий от post-factum

А если ты в юзерспейсе что-то такое делаешь, это значит, что код — говно.

Не обязательно же. Если нужно поспать, и, в принципе, наплевать сколько – самое то. Например в обработчике реквеста на удаление ресурса: если пользователи ещё живы – поспать (не важно сколько), если нет – удаляем.

Stil ★★★★★
()
Ответ на: комментарий от Stil

Для этого события нужно слать, а не спать как попало в цикле.

post-factum ★★★★★
()
Ответ на: комментарий от post-factum

Альтернатива

while(true){};
Чтобы цикл постоянно не выполнялся, добавить типа такого.
while(true) yield();
После первой проверки, поток уступит другому потоку выполнение.
Я понимаю почему вы так написали. Просто вы знаете как в говне применить такую функцию, а я знаю как в нормальном коде сделать.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

Просто вы знаете как в говне применить такую функцию, а я знаю как в нормальном коде сделать.

Орнул.

Ты свой while true называешь нормальным кодом:

post-factum ★★★★★
()
Ответ на: комментарий от post-factum

Но true это переменная, а не состояние.

Ты свой while true называешь нормальным кодом:

Да, вполне. Это же не сценарии шелла, где while true очначает бесконечность.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

Я имею ввиду, что только за прошлую неделю ты запостил стопитцот сообщений на ЛОР с тупейшими вопросами, а на критику отвечаешь весьма резко.

Хочешь превзойти и в знаниях по ядру и си, и в боевом искусстве?

Хочу сказать, что ты DOING IT WRONG.

narkoman228
()
Ответ на: комментарий от u0atgKIRznY5

Слушай, зачем тебе ядро? Это же занятие для лузеров ноулайферов. Настоящие мужики пилят systemd.

anonymous
()

Не понимаю я людей, которые еще толком Си не осилили и не могут писать без сегфолтов и детских ошибок, но уже лезут своими кривыми руками в кернелспейс

SZT ★★★★★
()
Ответ на: комментарий от mittorn

Да, вот поддерживаю. Чтоб вендекапец побыстрее наступил

SZT ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

Если бы тебе это не мешало, тут бы этого треда не было. Лучше возьми книгу K&R и прорешай там все от корки до корки, потом уже только лезь в ядро

SZT ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

У меня сообщения анонимусов не видно.

80 lvl butthurt.

anonymous
()
Ответ на: комментарий от SZT

Я так нового ничего не найду. Ты бы лучше показал что здесь не так. Знал бы написал? Что мне как совет, так лучше где подробней книжку может знаете, а то я такой незнаю.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от SZT

Укажи знаток на проблему, раз считаете что она есть. Но мне всё равно нужно знать ответы на мои вопросы, вот например, что такое likely и unlikely, я такое вижу в коде ядра, но незнаю что оно значит, такое может в книгах врядли пишут, но если вы знаете, что так сложно ответить, тогда зачем вы тут, если незнаете. Давайте уже по делу говорит, а то взяли моду не по теме советовать что читать, есть тема, обьясни где segfault и детские ошибки, так наглядней будет.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от SZT

А что это у вас на аватарке? Логические 'НЕ ИЛИ' и 'НЕ И'? Я подобное видел в книжке по архитектуре компьютера.

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

Давайте уже по делу говорит, а то взяли моду не по теме советовать что читать, есть тема, обьясни где segfault и детские ошибки, так наглядней будет.

Тебе сколько лет?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Тебе сколько лет?

Создай отдельную тему и задавай вопрос.

u0atgKIRznY5
() автор топика

Честное слово, здесь какие то незнайки собрались, знают только фразу, «изучай си», «ещё си незнает, а уже в ядро полез». Ну а вы то что, ничего внятного я от вас не услышал. Вы тогда кто?

u0atgKIRznY5
() автор топика
Ответ на: комментарий от u0atgKIRznY5

ничего внятного я от вас не услышал

И это нужно понимать буквально.

Не услышал. Значит, плохо слушал.

i-rinat ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

Тебе уже тут указали на проблемы в твоем коде, какой мне смысл повторяться? Здесь не так то, что ты не зная Си пытаешься что-то писать для ядра. Естественно, у тебя ничерта не будет выходить. Изучи Си, и потом уже лезь в ядро. Все очень просто. Ты допускаешь ДЕТСКИЕ ошибки, на которые тебе выше по треду уже указали. Если бы ты знал Си, ты бы таких ДЕТСКИХ ошибок не допускал и не засорял ЛОР этими бессмысленными темами.

SZT ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

А что это у вас на аватарке? Логические 'НЕ ИЛИ' и 'НЕ И'?

Это сумматор

SZT ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

здесь какие то незнайки собрались, знают только фразу, «изучай си», «ещё си незнает, а уже в ядро полез». Ну а вы то что, ничего внятного я от вас не услышал. Вы тогда кто?

Коротко о себе: разработчик Gentoo, разбираюсь в си, пилил простенькие патчи на ядро, глубоко в самом ядре не шарю.

С мнением, что твой код - говно и надо сначала подучить язык, озвученный в данном треде в том числе post-factum(который на минуточку адаптирует сторонние патчи на собственный кастомный билд ядра, гуглить по pf-kernel) согласен.

Кто же ты - мы так и не услышали. Зато услышали набор истеричных выкриков о том, что все вокруг против тебя.

Облом с sizeof - это очень распространенная ошибка новичка. Быть новичком не стыдно. Считать, что более опытные что-то тебе должны по гроб жизни - большая ошибка.

Pinkbyte ★★★★★
()
Ответ на: комментарий от u0atgKIRznY5

учи раст, он тебе за такое по пальцам настучит ... а может и не только по пальцам.

anonymous
()
Ответ на: комментарий от u0atgKIRznY5

Вот ты продолжаешь спрашивать про likely unlikely, но тебе можно только сказать не использовать их. Потому что это функции для оптимизации кода, причем для очень тонкой оптимизации.

Тебе надо сначала сделать свой код корректным и без уязвимостей, а потом уже спрашивать про оптимизации. А для того чтобы писать хороший код надо знать C, а у тебя с этим пока проблемы.

pftBest ★★★★
()
Ответ на: комментарий от u0atgKIRznY5

Коротко о себе: Software Maintenance Engineer (Linux Kernel) в Red Hat, пописываю на сях всякий интересный системный юзерспейс, играю с pf-kernel.

post-factum ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.