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 
 6.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
 MINIX...3057 
 Solaris...2933 
 LD...2904 
 Linux Kernel 2.6...2470 
 William Gropp...2180 
 Rodriguez 6...2011 
 C++ Templates 3...1945 
 Trees...1936 
 Kamran Husain...1865 
 Secure Programming for Li...1791 
 Максвелл 5...1710 
 DevFS...1693 
 Part 3...1682 
 Stein-MacEachern-> Час...1632 
 Go Web ...1624 
 Ethreal 4...1618 
 Arrays...1606 
 Стивенс 9...1603 
 Максвелл 1...1592 
 FAQ...1538 
 
  01.01.2024 : 3621733 посещений 

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) позволяет пользовательским программам контролировать устройства .
Оставьте свой комментарий !

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

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