[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: пара отвлеченных вопросов, офтопик



14.06.06, Nikita V. Youshchenko<yoush@debian.org> написал(а):

> 14.06.06, Nikita V. Youshchenko<yoush@debian.org> написал(а):
> > Ядро - это замкнутый в себе статический бинарник.
>
> А загружаемые модули?

А загружаемые модули линкуются внутрь ядра; им доступны только символы,
экспортируемые ядром или другими загруженными модулями.

Значит, уже не замкнутый и не статический.

Советую почитать "Linux device drivers, 3rd edition" - доступно в сети.

Спасибо за совет. Читал. Лучшая из всех и, тем не менее, крайне недостаточная.
4th edition давно в сети.

> Из ядра можно вызывать любой системный вызов, доступный из user space.

Ну если только не играться с ассемблером, то это не так.

Никаких игр с ассемблером. Всё штатными средствами ядра.
Всё ассемблерное и платформо-зависимое предоставлено ядром.

Системному вызову
xxx() соответствует в ядре функция sys_xxx(), и эти функции не
экспортируются

Экспорт не нужен.

(так как, помимо прочего, используют специальные binary
calling conventions).

Любые calling conventions описаны в прототипах.
Неважно.

> Просто нужно знать как. Это не документировано, но без этого маханизма
> само ядро обойтись не может, а потому это будет доступно всегда.

А с этого момента поподробнее пожалуйста. Многолетний опыт работы в ядре
заставляет усомниться в ваших словах ...

Ну тогда можно и без подробностей - смотрите <asm/unistd.h> и
приложенный файл - надёргал фрагментов из рабочего кода.
# include <linux/processor.h>	/* mm_segment_t              */
# include <linux/uaccess.h>	/* set_fs, get_fs, KERNEL_DS */
# include <asm/unistd.h>	/* system calls */


// returns old mm segment.
extern inline
mm_segment_t df_get_and_set_fs(mm_segment_t newfs)
{
    mm_segment_t oldfs = get_fs();
    set_fs(newfs);
    return oldfs;
}


static inline _syscall3(int, chown,
			const char __user*, filename,
			uid_t, user,
			gid_t, group)

int df_chown(const char __kernel* filename,  uid_t user, gid_t group)
{
    mm_segment_t old_fs = df_get_and_set_fs(KERNEL_DS);

    int rc = chown((const char __user*)filename, user, group);

    set_fs(old_fs);

    return rc<0 ? errno : rc;
}


static inline _syscall3(int, mknod,
			const char __user*,filename,
			mode_t,mode,
			dev_t,dev)

int df_mknod(const char __kernel* filename, mode_t mode, dev_t dev)
{
    mm_segment_t old_fs = df_get_and_set_fs(KERNEL_DS);

    int rc = mknod((const char __user*)filename, mode, dev);

    set_fs(old_fs);

    return rc<0 ? errno : rc;
}


Reply to: