Нужно сделать возможным вызывать 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.