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: