-
Notifications
You must be signed in to change notification settings - Fork 4
/
README
149 lines (125 loc) · 9.59 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
Проект по КС. Пособин Глеб, группа 141.
Добавлено: exec для скриптов, mkfifo, пользователи, /proc, треды, mmap.
1. #!/bin/ls
Добавлена проверка файла на #! в начале, в таком случае сплитим первую строку
файла по пробелам, первый токен — имя интерпретатора, последующие — его аргументы
(в линуксе это сделано немного иначе, он сплитит только по первому пробелу,
все аргумены склеивает в один. Но стандарта по #! нет, OS X делает как я, например
(http://mail-index.netbsd.org/netbsd-users/2008/11/09/msg002388.html)).
Ещё добавляем в аргументы имя вызванного файла и аргументы, данные при этом вызове.
Так как теперь есть переменные окружения, также передаём их дальше.
Да, теперь все бинарники лежат в /bin, так что в #! надо писать полный путь к
интерпретатору.
Глубина рекурсии ограничена пятью, когда превышается, возвращаем -1 и ставим
errno = ELOOP.
2. mkfifo
Сделал новый тип для inode и file, mkfifo просто создаёт inode с таким типом.
Первый open этого файла создаёт соответствующий ему pipe,
записывает его адрес в inode.
Если не передан флаг O_NONBLOCK, то open ждёт открытия другого конца (либо того,
что файл удалят. В линуксе немного не так: если сделать cat fifo, а потом
rm fifo, cat продолжит ждать открытия другого конца пайпа). Когда другой конец
открыли, возвращаем file, соответствующий нашему концу пайпа. read и write
происходят так же, как и для пайпов.
В close не забываем уменьшать счётчик, в скольких процессах этот пайп открыт с нашей
стороны. Когда оба конца пайпа больше нигде не открыты, удаляем пайп из памяти.
В unlink ставим на пайп флаг is_deleted, удаляем соответствующий inode из папки.
3. Пользователи
По умолчанию есть два пользователя root и user, у обоих нет пароля. Добавить нового
пользователя (из-под рута, понятное дело) можно командой useradd -m username
(-m — чтоб создать домашнюю директорию для нового пользователя, по умолчанию у
пользователя не будет пароля).
Работают команды chown username:groupname filename, chmod mode filename
(mode в виде восьмеричного числа), id, ls теперь показывает права на файле и
его владельца и группу.
Утилита login логинит пользователя, её теперь запускает init по умолчанию вместо sh.
login же при успешном вводе пароля запускает программу по умолчанию для заданного
пользователя (обычно это /bin/sh).
passwd username устанавливает пароль пользователя (если права текущего пользователя
это позволяют, конечно). На исполняемом файле passwd стоит бит setuid, так что
при запуске passwd эффективный uid пользователя меняется на uid владельца
файла (в данном случае это рут). Благодаря этому passwd может модифицировать
файл /etc/passwd.
Чтобы выйти из пользователя, достаточно просто выйти из сессии sh нажав ^D,
sh закончит работу, исполнение перейдёт к init, init снова запустит login.
4. Треды
Как в линуксе сделан вызов clone, создающий копию процесса, и копирующий то,
что было сказано копировать в аргументах.
Функция thread_create создаёт стек и дескриптор потока, потом создаёт новый
поток с помощью clone.
Есть thread_join и thread_detach.
Системый вызов exit_group() выходит из всех тредов в группе, exit() только
из данного процесса. Пользовательский вызов exit() вызывает exit_group().
5. /proc
Реализован с помощью чего-то похожего на VFS.
Доступная информация:
/proc/free_pages — количество свободных страниц в системе,
/proc/PID/name — имя процесса,
/proc/PID/state — состояние процесса (sleeping, running, …),
/proc/PID/memory — количество виртуальной памяти у процесса,
/proc/PID/pid — pid процесса,
/proc/PID/uid — uid пользователя,
/proc/PID/parent — хардлинк на каталог родителя в /proc.
Есть утилита ps.
C /proc начнутся проблемы, когда pid процессов перевалит за 10000, т.к.
номер айнода хранится в short, а номер айнода директории процесса — 6 * PID.
Практически весь код, отвечающий за /proc, находится в procfs.c.
6. mmap
При вызове mmap, если mmap не анонимный, считывается
файл в память по переданному адресу.
Соответствующие страницы виртуальной памяти помечаются
заблокированными для записи.
Когда выходим из процесса, записываем в файл (если не анонимный mmap)
страницы с флагом dirty (он ставится при записи в страницу).
То есть, в данном случае два процесса, которые открыли файл shared mmap’ом,
не будут видеть изменения друг друга.
mmap сам память не выделяет, поэтому сначала надо делать malloc.
Shared mmap’ы разделяются после форка (см. mmap_pp.c).
munmap() нет, память очищается при выходе из процесса.
7. Ещё
* errno — не thread-safe.
* Переменные окружения.
* Аллокатор памяти в ядре (благодаря ему, например, может быть запущено 700
процессов). Похож по устройству на slabы в линуксе.
* chroot (можно протестировать, сделав `chroot /test/chroot`).
* Всякие тесты/примеры лежат в /test.
* Тесты из usertests проходятся успешно.
Дальше оригинальный Readme:
xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix
Version 6 (v6). xv6 loosely follows the structure and style of v6,
but is implemented for a modern x86-based multiprocessor using ANSI C.
ACKNOWLEDGMENTS
xv6 is inspired by John Lions's Commentary on UNIX 6th Edition (Peer
to Peer Communications; ISBN: 1-57398-013-7; 1st edition (June 14,
2000)). See also http://pdos.csail.mit.edu/6.828/2012/v6.html, which
provides pointers to on-line resources for v6.
xv6 borrows code from the following sources:
JOS (asm.h, elf.h, mmu.h, bootasm.S, ide.c, console.c, and others)
Plan 9 (entryother.S, mp.h, mp.c, lapic.c)
FreeBSD (ioapic.c)
NetBSD (console.c)
The following people have made contributions:
Russ Cox (context switching, locking)
Cliff Frey (MP)
Xiao Yu (MP)
Nickolai Zeldovich
Austin Clements
In addition, we are grateful for the patches contributed by Greg
Price, Yandong Mao, and Hitoshi Mitake.
The code in the files that constitute xv6 is
Copyright 2006-2012 Frans Kaashoek, Robert Morris, and Russ Cox.
ERROR REPORTS
If you spot errors or have suggestions for improvement, please send
email to Frans Kaashoek and Robert Morris (kaashoek,[email protected]).
BUILDING AND RUNNING XV6
To build xv6 on an x86 ELF machine (like Linux or FreeBSD), run "make".
On non-x86 or non-ELF machines (like OS X, even on x86), you will
need to install a cross-compiler gcc suite capable of producing x86 ELF
binaries. See http://pdos.csail.mit.edu/6.828/2012/tools.html.
Then run "make TOOLPREFIX=i386-jos-elf-".
To run xv6, you can use the Bochs or QEMU PC simulators. Bochs makes
debugging easier, but QEMU is much faster. To run in Bochs, run "make
bochs" and then type "c" at the bochs prompt. To run in QEMU, run
"make qemu".
To create a typeset version of the code, run "make xv6.pdf". This
requires the "mpage" utility. See http://www.mesa.nl/pub/mpage/.