Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 Kernels
 Boot 
 Memory 
 File system
 0.01
 1.0 
 2.0 
 2.4 
 2.6 
 3.x 
 4.x 
 5.x 
 Интервью 
 Kernel
 HOW-TO 1
 Ptrace
 Kernel-Rebuild-HOWTO
 Runlevel
 Linux daemons
 FAQ
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 Part 4...505 
 Part 3...502 
 Kamran Husain...347 
 Alg1...303 
 2.0-> Linux IP Networking...302 
 Stein-MacEachern-> Час...282 
 Secure Programming for Li...276 
 Mod_perl 2...264 
 Benchmark...260 
 Trees...235 
 Advanced Bash Scripting G...220 
 Ext4 FS...219 
 Ethreal 1...214 
 K&R 2...214 
 Rodriguez 6...205 
 Part 2...202 
 Part 1...201 
 Kamran Husain...200 
 Тренажёр...199 
 C++ Patterns 2...199 
 
  01.12.2020 : 3018131+ посещений 

iakovlev.org

Rubini

Информация основывается на версии Linux 1.0 .
При включении процессор 80x86 загружается в real mode по биос-адресу 0xFFFF0.
Биос тестирует систему и инициализирует вектор прерывания по адресу 0.
После этого биос грузит код с первого сектора загрузочного устройства(дискеты или харда) в память по адресу 0x7C00 и прыгает в этот адрес. boot/bootsect.S написан на асм-е.
Загрузчик первым делом клонирует себя по адресу 0x90000, затем загружает очередную порцию кода - 2Кб - с загрузочного устройства по адресу 0x90200, а остальную чать - по адресу 0x10000.
Контроль передается в boot/Setup.S. Здесь пользователю может быть предложен выбор видео-режима.
Затем происходит клонирование кода с адреса 0x10000 по адресу 0x1000 , устанавливается защищенный режим и запускается адрес 0x1000.
Следующий шаг - декомпрессия ядра . zBoot/head.S инициализирует регистры и вызывает decompress_kernel().
Архив копируется по адресу 0x100000 (1 Meg),и это основная причина, по которой линукс не может работать на системах , на которых меньше 2 метров памяти :-)
Этот код запускается , при этом инициализируются таблицы IDT, GDT, LDT , пэйджинг .
На этом этапе ошибок быть не должно , иначе процессор упадет в ступор .
Все дальнейшее - на си . Вызывается start_kernel из init/main.c . Вызывается paging_init() , IRQ , парсится командная строка , инициализируются устройства , После чего вызывается move_to_user_mode() , генерится init-процесс "idle" с нулевым id-шником.
init-процесс пытается запуститься по одному из адресов /etc/init, /bin/init, /sbin/init.
Ежели это не удается , вываливается shell и нет никакой возможности залогиниться вновь .
Далее ядро ожидает системных вызовов от запущенных пользовательских процессов .
С точки зрения ядра , пользовательский процесс - это адрес в таблице процессов , и ничего более .
Таблица процессов-это массив структур task_struct . Также можно сказать , что таблица процессов - это древовидная структура , построенная на основе double-linked списков , физически это массив указателей , и каждая структура хранится в отдельной странице памяти . Перемещаться по этому массиву можно с помощью указателей next_task и prev_task .
Существует глобальный указатель "current" , который всегда указывает на процесс , выполняемый в данный момент .
Значение current может быть изменено в kernel/sched.c . Для того , чтобы сделать обзор всех процессов , нужно использовать макрос for_each_task . Процесс может выполняться либо в user mode'', либо в ``kernel mode''.
Код пользовательских программ выполняется в user mode'', системные вызовы в них - в ``kernel mode''.
Внутри этого процесса стек может быть различным - в зависимости от mode . Стек ядра никогда не своппится .
Системный вызов начинается с префикса `sys_'. Новый процесс создается с помощью системного вызова fork() , прекращение процесса - спомощью exit() или специального сигнала . Реализация - в kernel/fork.c и kernel/exit.c.
Для структуры task_struct выделяется место , вызывается find_empty_process() для нахождения пустого слота , выделяется страница для kernel_stack_page , запоминается родительский процесс для возвращения .
В файле exit.c лежат функции для выхода sys_kill() , sys_wait(), sys_exit() .
Как правило , при запуске пользовательского процесса параллельно запускается 2-й процесс - exec().
Его роль заключается в том , чтобы загрузить с харда и запустить образ исполняемого бинарного файла .
Поддерживаются различные бинарные форматы , для этого есть структура linux_binfmt , в которой есть 2 указателя на функции загрузки бинарника и соответствующей библиотеки . sys_execve() определяет первые 2 байта бинарника , и если это ``#!'' , то запускается интерпретатор .
Если что-то набирается в консоли , вызывается con_write() , которая идентифицирует набираемые символы. Обмен между видеопамятью и консолью осуществляют set_scrmem() и get_scrmem().
По поводу клавиатуры привожу цитату : "Keyboard management is quite a nightmare".
За это в версии 1.0 отвечает файл keyboard.c , который состоит из 16-ричных кодовых представлений от различных производителей . Переключение между консолями выполняет change_console() и complete_change_console() (tty_io.c) .
Системный вызов ioctl() (fs/ioctl.c) позволяет пользовательским программам контролировать устройства .
Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье