LINUX.ORG.RU

printk из usep space


0

0

Нужно сделать возможным вызывать printk из user space (не 0-кольца). Делать собираюсь через системный вызов по вектору 80 (int 0x80). Уже подготовил почву, все изучил про системные вызовы, осталось только решить самую важную проблему.

asmlinkage int printk(const char *fmt, ...)
{
	va_list args;
	int r;

	va_start(args, fmt);
	r = vprintk(fmt, args);
	va_end(args);

	return r;
}

Проблема в том что printk принимает неопределенное число параметров, и как это передать через системные вызовы для меня остается загадкой. Вариант с передачей через стек еще рассматривается, но боюсь это может быть не безопасно и проблематично. Сегодня возникла такая идея:

Если сделать в качестве системного вызова не весь printk а только vprintk который на сколько я понял уже получает всего два параметра. Я надеюсь что так оно и работает. Но я не смог понять всей логики работы макросов va_start и va_end (Объявлены в файле /include/acpi/platform/acenv.h, правильно ?). Если честно я ваше не смог понять что и как они делают. Поэтому не знаю на сколько правдива идея.

typedef char *va_list;
...
#define va_start(ap, A)         (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))

смотрел все остальные макросы и к сожаление не понял их :( Я даже не понял что в итоге будет находится в переменных которые передаются им: args и fmt, это будут конечные переменные ? как например указатель на ограниченную строку ? или что то неопределенное ?

Если после вызова va_start в args и fmt будут выглядеть как обычные переменные то можно ли разделить вызов va_start на userspace, далее системный вызов (который я сделаю) на vprintk, получаем от него результат и далее продолжая на userspace сделать va_end ?

И кстати, я также не понял как как оно так работает

printk(KERN_ERR "bla bla bla\n");

KERN_ERR «bla bla bla\n» - это че такое ? не строка и строка вместе О_о

ЗЫ. на сколько я понял объявления printk происходит в файле /include/linux/kernel.h. Но какое из трех используется?

#ifdef CONFIG_PRINTK
asmlinkage int vprintk(const char *fmt, va_list args)
	__attribute__ ((format (printf, 1, 0)));
asmlinkage int printk(const char * fmt, ...)
	__attribute__ ((format (printf, 1, 2))) __cold;
...
#else
static inline int vprintk(const char *s, va_list args)
	__attribute__ ((format (printf, 1, 0)));
static inline int vprintk(const char *s, va_list args) { return 0; }
static inline int printk(const char *s, ...)
	__attribute__ ((format (printf, 1, 2)));
...
static inline int __cold printk(const char *s, ...) { return 0; }

Или же это не его объявления и другие приблуды ядра ?

ЗЗЫ. нужен именно printk.



Последнее исправление: Cupper (всего исправлений: 1)

>Уже подготовил почву, все изучил про системные вызовы
изучай дальше.

dimon555 ★★★★★
()
#undef printk
#define printk(fmt,args...)   fprintf(stderr, fmt, args)
arsi ★★★★★
()
Ответ на: комментарий от mv

[code] #undef printk #define printk(fmt,args...) fprintf(stderr, fmt, args) [code]

это ответ на все вопросы ? Я не понимаю что вы имеет в виду.

man 2 syslog

если вы это предлагаете вместо printk то читаем внимательно

ЗЗЫ. нужен именно printk.

Причина в том чтобы не переделывать 100500 запусков функции printk и не изобретать велосипед для того чтобы создать функцию полностью имитирующую поведени printk но на уровне пользователя чтобы потом передать свормированную ей строчку в syslog.

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

Это хреносозидательство. printk не расчитан на использование из юзерспейса. Почему? Нужно долго смотреть на printk и copy_from_user, и тогда истина придёт.

Если таки не в моготу, то делайте это хотя бы через модуль, высовывающий соответствующий интерфейс в юзерспейс. Модуль легко клепается systemtap'ом.

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

Из юзерспейса писать в ядро информацию, чтобы потом читать её из юзерспейса.
Рекурсия однако.

1. Создаешь файл символьного устройства: /dev/my_monster_printk
2. Регистрируешь на .write функцию, которая вызывает printk без
дополнительных параметров (printk(«my monster string\n»);)
3. Строку формируешь в userspace-программе, из нее же делаешь write;
или напрямую echo «my monster string\n» > /dev/my_monster_printk
4. ????
5. PROFIT!!!

после профита

6. За добавление лишних системных вызовов Линус обычно отрывает яйца
7. и твое имя проклинают в списке разработчиков ядра

Готов ли ты к этому?

ttnl ★★★★★
()

какие феерические идеи возникают последнее время в Development, просто диву даюсь

Reset ★★★★★
()

ну напиши модуль с интерфейсом через /dev, /proc или /sys.

Какую задачу ты пытаешься решить?

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

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

6. За добавление лишних системных вызовов Линус обычно отрывает яйца
7. и твое имя проклинают в списке разработчиков ядра

Вот четсно, я такие вещи принимаю только как юмор. Я задал четко определенный вопрос, да он отличается о «основной» массы вопрос задаваемых тут, но пожалуйста отбросьте все предвзятость и отвечайте только с профессиональной точки зрения.

Это хреносозидательство. printk не расчитан на использование из юзерспейса.

обозначим это как «использование не из kernel space».

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

Я задал четко определенный вопрос, да он отличается о «основной» массы вопрос задаваемых тут, но пожалуйста отбросьте все предвзятость и отвечайте только с профессиональной точки зрения.

Я профессионально отвечаю тебе, что твоя идея - нелепое хреносозидательство. От основной массы задаваемых тут вопросов твой ничем не отличается.

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

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

Т.е. ты сам понимаешь, что твоя идея - говно. Что же заставляет тебя продолжать её реализацию? Может ты думаешь, что выставив printk ты решишь основную задачу быстрее и проще? Так я тебя разочарую, неестественные вещи трудно пишутся и ещё труднее поддерживаются.

И по теме: va_start и друзья - документированный хак, основанный на знании реализации определённой конвенции вызова на определённой платформе. Разберись с сишными вызовами и поймёшь в чём магия.

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

> Я задал четко определенный вопрос

4.2

он отличается о «основной» массы вопрос задаваемых тут

4.2

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

>Т.е. ты сам понимаешь, что твоя идея - говно. Что же заставляет тебя продолжать её реализацию?

над первым ПК тоже когда то посмеялись и сказали - «зачем обычным людям компьютеры»

Закрываем тему.

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

Не стого я начал, неважно что я делаю, интересуют ведь меня другие вопросы. В следующем коде

 va_start(args, fmt); r = vprintk(fmt, args); 

на что после va_start будет указывать args ? ведь *agrs это ничто иное как char.

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

Насколько я понимаю, будет указывать на первый аргумент из "...".
Только для доступу к нему нужно применить va_arg.
Применишь va_arg ещё раз - получишь второй аргумент и т.д.

ttnl ★★★★★
()

Лучше б ты уроки учил

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

>Только для доступу к нему нужно применить va_arg

да, это я понял.

Волнует то как решается вопрос с безопастностью при использовании, на сколько я уже понял после вызова va_start далее работа с параметрами ведется через стек, и при получении параметра из стека нужно явно указывать тип извлекаемого параметра. Сразу напрашивается вопрос, а если положили одни параметры и извлекаем параметры с другим типом или вообще не извлекаем параметры, то до вызова va_end они остаются в стеке, а если его не вызвать вообще то получается что в стек мы положили все что угодно (вредоностный код) и оно там осталось... как то все странно.

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

> ут такой базар начнется что не ведать мне своих ушей среди тонны грязи которую вылью на мну.

Поверь мне, тебе нечего терять. )))

отвечайте только с профессиональной точки зрения.


Все до единого ответы тебе были даны исключительно с профессиональной точки зрения.

Ну вот ты сам подумай, когда студент-медик спрашивает опытных врачей «как удалить гланды через жопу», что ему отвечают?

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

>как то все странно.

Я же тебе говорил, это хак. Юзать его надо ну очень осторожно. Это одна из причин, по которой не советуют писать функции с эллипсисами.

legolegs ★★★★★
()

Феерический топик, спасибо за хорошее утреннее настроение.

MuZHiK-2 ★★★★
()

хороший вопрос

...а сделайте мне капитальный ремонт двигателя через выхлопную трубу...

limux
()
Ответ на: комментарий от ttnl

>6. За добавление лишних системных вызовов Линус обычно отрывает яйца

7. и твое имя проклинают в списке разработчиков ядра

я бы ему уже за одно создание этого топика оторвал руки, яйца и проклял на работу дворником.

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

страшно становится, когда такие люди как ТС лезут в ядро и потом еще мнят себя крутыми сиспрогерами.

xydo ★★
()

Топикстартеру:

Идея бредова по своей сути. Первая проблема, с которой вы столкнетесь при реализации подобного механизма, это то, что стек ядра и пользовательского процесса распологаются несколько в разных местах. Как следствие, использовать макросы va_list и va_start вам не удастся; о vprintk тоже придется забыть по той же самой причине. Как вариант вы можете написать syscall который примет набор параметров из стека процесса (тех, что описаны в строке форматирования), сверстать строку и скормить её напрямую printk. Но стоит ли это такого титанически-бесполезного труда?

Для того что бы отправить строку в syslog, можно воспользоваться вызовом syslog(2).

jr_A
()
Ответ на: комментарий от xydo

Ну он пока не лезет, только тренируется.

С другой стороны непросто так самому все ядро изучить.

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

зачем сразу бредовая, называйте просто «безумная» :)

за разъяснения спасибо, я предполагал что подобное, вы же все разъяснили как на ладоне.

сверстать строку и скормить её напрямую printk. Но стоит ли

в начале просто хотелось сделать все как можно с меньшими модификациями (как казалось на тот момент). В последствии конечно была идея чтобы делать полное распарсивание строки на не кернел уровне и после передавать уже готовую строку. В этом случае конечно же нет никакого смысла передавать ее принтка.

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

>С другой стороны непросто так самому все ядро изучить.
так самому и не надо, блин)))
книги есть. вполне нормальные причем!
в которых черным по белому написано, что и как можно и нужно делать в ядре...

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