Pull to refresh

Comments 24

C socket() можно интереснее расследование провести.
Еще и в зависимости от платформы может меняться: sys_socketcall() (мультиплексирование) для i386 или sys_socket() (чисто socket()) для x86_64 и Arm.
Спасибо, на досуге посмотрю, что там к чему.
как-то не очень понятно, что именно данной статьёй хотел донести ТС до публики
Хотели донести что очень интересно и познавательно копаться в исходниках используемого програмного обеспечения.
Автор открыл для себя VFS. И заодно, как работают системные вызовы в Linux.

На мой взгляд, ядро Linux уже достаточно большое, чтобы изучать его эмпирически. Лучше почитать какую-нибудь толковую книжку сначала (например, Роберт Лав, «Linux. Системное программирование»).

Кстати, интересно, что таблица системных вызовов может изменяться от ядра к ядру. Если вы перекомпилируете ядро, mkdir может уже стать не 83-м. Кажется, это разруливается где-то на уровне libc
Что? Номера системных выховов не могут меняться. Они чётко заданы #define. Иначе всё рассыпалось бы.

А то что его не надо изучать эмпирически — это да. Но эмпирически можно вносить небольшие изменения, используя strace + grep. Очень странно, что strace не был упомянут.
Имелось в виду, меняться статически, от ядра к ядру. Не уверен, что такое часто происходит. По крайней мере, в ядре таблица системных вызовов лежит во многих местах — в зависимости от платформы в arch/*/ketnel/syscall*.S
К тому же, когда добавляют свой системный вызов, его добавляют в конец — каждый по-своему — и никакой стандартизации
Номера системных вызовов действительно свои в каждом архитектурном порте, но ни одна архитектура не меняет эти номера со временем: требование обратной совместимости ядер по отношению к юзерленду (т.е. гарантия того, что пользовательские программы работают без пересборки на разных версиях ядра) — ключевой момент дизайна линукса.
И, кстати, одно из того, чем оно радикально отличается от дизайна *BSD-систем, где их таки изредка меняют — из-за чего в некоторых случаях пересобирают юзерленд вместе с новым ядром.
Из mm/mmap.c:
SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)
{
	struct mmap_arg_struct a;

	if (copy_from_user(&a, arg, sizeof(a)))
		return -EFAULT;
	if (a.offset & ~PAGE_MASK)
		return -EINVAL;

	return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
			      a.offset >> PAGE_SHIFT);
}


Системный вызов mmap имеет всего один аргумент — указатель на mmap_arg_struct__user. То, что вы привели выше, это сигнатура функции-обертки, которая в user space заварачивает все 6 аргументов в нужную структуру. Но вы частично правы, так как с точки зрения ядра аргумент 1, а с точки зрения программы их 6.
То, что вы привели — это syscall old_mmap, а не syscall mmap. «Настоящий» mmap принимает 6 аргументов системного вызова. Вот что о нём пишут в man 2 syscalls.

The select(2) and mmap(2) system calls use five or more arguments, which caused problems the way argument passing on the i386 used to be set up. Thus, while other architectures have sys_select() and sys_mmap() corresponding to __NR_select and __NR_mmap, on i386 one finds old_select() and old_mmap() (routines that use a pointer to a argument block) instead. These days passing five arguments is not a problem any more, and there is a __NR__newselect that corresponds directly to sys_select() and similarly __NR_mmap2
Согласен. Мое утверждение правдиво только для i386.
А кто-нибудь знает, зачем в системных h-файлаХ столько подчерков перед именами аргументов и иногда типов? Зачем они там, почему без них просто не написали?
По стандартам С и С++ в юзерской программе не может быть двойных подчеркиваний и одиночных подчеркиваний перед заглавными буквами.
Для реализаций стандартных библиотек таких лимитов нет.
Поэтому, чтобы не было случайных конфликтов внутренних системных имен с юзерскими (а особенно с юзерскими макросами, которым пофик на локальность переменных например) обычно и используется такая декорация имен.

Кроме того есть ряд случаев когда реализация обязана использовать декорирование подчеркиваниями.
Ну т.е. реальная причина только одна: это возможный конфликт с макросами? Но ведь юзер может и #define int long написать, они же от этого не защищаются…
Речь про случайные конфликты, а не преднамеренные.

Потому что если юзер захочет наломать или допустим он дурак, то от этого в С никак не защититься.
UFO just landed and posted this here
Свое «погружение» я начал недавно с Unix V6, по адресу pdos.csail.mit.edu/6.828/2011/xv6.html можно найти исходники unix версии 6, которую используют при изучении operation system студенты MIT. Сейчас конечно, как вы описали выше, все намного запутаней получается, что делает тему только еще более интересней =) Спасибо за статью!
make tags
vim '+:ts sys_mkdir'

На самом деле очень жаль, что подобные вещи постят на хабре и они собирют столько голосов.
Да, кстати, если действительно хочется понять принципы работы, то рекомендую книжку «Understanding the Linux Kernel, Third Edition», она есть в неплохом русском переводе.
Согласен.
В статье надо предупредить читателя, что int 0x80 — устаревший способ обращения к системным вызовам и не приемлем, т.к. жутко снижает производительность конвейера процессора.
Sign up to leave a comment.

Articles