Created
March 12, 2014 15:41
-
-
Save siviae/9509433 to your computer and use it in GitHub Desktop.
OS lecture summary
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Ян. Лекция 3. | |
| План: | |
| 1. память -> mmap, fork | |
| 2. -> vfs - virtual file system (упрощённая семантика read, write) | |
| __________________________ | |
| Process r = (r,mmn)~>Context (secure process) | |
| r - регистр | |
| mmn - таблица маппинга из виртуальных адресов в физические | |
| Хотим чтобы для каждого процесса mmn был свой. pid (!-> - функция с явным конечным представлением)!-> ProcInfo | |
| ProcInfo = record{ | |
| mmu::VMA // | |
| pid::pid_t | |
| ... | |
| } | |
| MMU - memory management unit | |
| Context = record { | |
| tag: SysCallTag, | |
| args: Args(tag), | |
| continuation: Process(Res(tag)) | |
| } | |
| что такое ядро? | |
| по сути, цикл while, у которого есть список процессов, которые нужно запустить и оно их по очереди дёргает. | |
| //todo почитать исходник с первой лекции, который Ян присылал | |
| как реализовать mmap? | |
| kvma - kernel virtual memory ? | |
| mmu - просто функция в духе "если страница закеширована - смапить, иначе закешировать и смапить" | |
| эффективно реализуется деревом отрезков | |
| когда производим mmap - он делается лениво(ставит пометку, чтобы маппинг произошёл при первом обращении) | |
| Файловые системы | |
| Они хранят описание файлов в виде | |
| inode{ | |
| type | |
| ... | |
| поля, зависящие от типа | |
| size | |
| atime | |
| ctime(creation) | |
| mtime(modification) | |
| size_in_blocks | |
| body :: set<block>, block - номер блока на диске | |
| et cetera | |
| } | |
| эта информация для xfs.., ntfs и прочих юниксовых. в FAT всё по другому | |
| type = enum { | |
| f/file/r, //common,regular file | |
| d/directory, // таблица из двух полей: имя и inode. Таким образом, директория просто отображает имена файлов в inode других файлов | |
| L/symlink, //ссылка, в виде строки пути к файлу. обработка происходит таким образом: есть путь, состоящий из директорий. мы прыгаем | |
| по симлинкам в пути можно проходить по дефолту 7 раз | |
| c //character device - можно читать просто по символам | |
| b // block device - имеют право не разрешать читать меньше, чем блоком. | |
| fifo //именованный pipe - два файловых дескриптора, связанных номером в ядре - нужны, для реализации | . | |
| Собственно | - это и есть пайп(труба). | |
| Можно организовать, чтобы многие к этому пайпу подключались, а кто-то один читал | |
| socket //наоборот, один пишет, все читают | |
| } | |
| каждый девайс нумеруется определённым номером, состоящим из двух интов: тип и номер. "номер шины и номер девайса на шине для старых систем" | |
| где-то захардкожен путь корневой inode - и от него вся файловая система парсится. | |
| Namespaces | |
| идея - хотим монтировать одну директорию на другую (перевешивать поддерево). | |
| mount(bdevFD::file_descriptor, path::String) - открывает файл как файловую систему и подвешивает её к директории по пути. | |
| что делает ядро? просто нужно системе найти соответствующий драйвер для файловой системы, драйвер запускается, открывает девайс, | |
| выдаёт наружу хэндл ФС с тем же интерфейсом, что и VFS: open/close/read/write. | |
| что делать дальше? | |
| как вариант - добавить тип inode fileSystem, и некоторые файловые системы это поддерживают, но ни одна операционка не реализовывает. | |
| но в реальных юниксах делают namespace: | |
| ("путь", хэндл ФС , номер рутовой inode в fs). | |
| если хотим open по монтированной системе - ищем нужный триплет из неймспейсе, открываем хэндл и дальше работаем с ним. | |
| интересный спецэффект - если мы открыли файл в директории, а потом туда что-то примонтировали - мы без проблем продолжаем работать. | |
| и вообще, любая операция будет продолжать работать, как будто мы ничего не примонтировали. (потому что ..) | |
| у inode есть счётчик ссылок | |
| nlinks - сколько директорий ссылаются на эту inode | |
| ещё один список поддерживается ядром - сколько текущих открытых файловых дескрипторов указывает на эту inode. inode удаляются, когда оба списка - нули. | |
| что такое файловый дескриптор? просто int с точки зрения процесса. | |
| внутри procInfo - | |
| таблица файловых дескрипторов pwd:: fdobj | |
| fdtable:: int-> fdobj | |
| fdobj = record { | |
| type = сужение inode.type.values (f,d,l,pipe(получается из сокетов, фифо и прочая)) | |
| закэшированный(fs, | |
| inodenumber) | |
| } | |
| с точки зрения процесса, файловый дескриптор - просто int, с точки зрения ядра - некий fdobj | |
| У файлов есть !права(режимы записи/запуска и прочая). (в частности, в fdobj они записаны). | |
| Есть указатель на текущую позицию считывания(offset). В директории - текущий элемент директории. | |
| dup2(int,int); | |
| Взять файловый дескриптор с первым номером и скопировать его во второй. После этого оба будут указывать на один fdobj. | |
| Соответственно, меняется fdobj - меняются оба дескриптора. | |
| fork целиком копирует всё, кроме (pid) | |
| На самом деле fdtable:: int !-> (*fdobj, flags); flags только один - CLOSE_ON_EXEC | |
| !!! Семантика read(fd, buffer, len); //запиши по адресу buffer не больше , чем len byte из соотв. ресурса. | |
| read возвращает, сколько реально байтов было скопировано. | |
| Если есть 1+ процесс, у которого есть ссылка на fdobj, который может писать в этот ресурс. Если на данный момент этот процесс не может ничего прочитать и больше есть ещё процессы, которые пишут в этот pipe, то процессы ждут, пока в пайп что-нибудь не запишут. Если же такий процессов нет, то всем процессорам, которые читают, получают eof. | |
| если read вернёт 0 - то это eof. | |
| Cемантика write(resource,buf,len); | |
| res = write(resource,buf,len); - возвращает, сколько реально байт записалось в процессе ввыполнения функции | |
| <0 - ошибки | |
| =0 - тоже ошибки | |
| pipe реализован как ring-буфер! то есть, конец как бы спаян с началом. | |
| Файл - это буфер, про который считается, что в него никто не может писать? | |
| Типа ДЗ: продумать | |
| 0. PLT OS - читаем исходник, выкидываем, пишем такой же сами, если не понимаем - repeat | |
| 1. MMU в PLT OS | |
| 2.как на самом деле реализована приостановка процессов на пайпе(read и write в ringbuffer) - как эту семантику реализовать | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment