Date: Tue, 14 Oct 2025 19:49:40 GMT From: Vladlen Popolitov <vladlen@FreeBSD.org> To: doc-committers@FreeBSD.org, dev-commits-doc-all@FreeBSD.org Subject: git: b98c929f06 - main - update translation of books/arch-handbook to Russian Message-ID: <202510141949.59EJne8f053209@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by vladlen: URL: https://cgit.FreeBSD.org/doc/commit/?id=b98c929f06d6664e6476d1372e60c797ae6b9339 commit b98c929f06d6664e6476d1372e60c797ae6b9339 Author: Vladlen Popolitov <vladlen@FreeBSD.org> AuthorDate: 2025-10-14 19:49:26 +0000 Commit: Vladlen Popolitov <vladlen@FreeBSD.org> CommitDate: 2025-10-14 19:49:26 +0000 update translation of books/arch-handbook to Russian Reviewed by: maxim Differential Revision: https://reviews.freebsd.org/D52026 --- .../content/ru/books/arch-handbook/_index.adoc | 57 + .../content/ru/books/arch-handbook/_index.po | 71 + .../books/arch-handbook/bibliography/_index.adoc | 51 + .../ru/books/arch-handbook/bibliography/_index.po | 45 + .../content/ru/books/arch-handbook/book.adoc | 49 +- .../content/ru/books/arch-handbook/book.po | 71 + .../ru/books/arch-handbook/boot/_index.adoc | 1351 +++ .../content/ru/books/arch-handbook/boot/_index.po | 4415 ++++++++++ .../books/arch-handbook/driverbasics/_index.adoc | 347 + .../ru/books/arch-handbook/driverbasics/_index.po | 867 ++ .../content/ru/books/arch-handbook/isa/_index.adoc | 1121 +++ .../content/ru/books/arch-handbook/isa/_index.po | 4237 ++++++++++ .../ru/books/arch-handbook/jail/_index.adoc | 529 ++ .../content/ru/books/arch-handbook/jail/_index.po | 1452 ++++ .../ru/books/arch-handbook/kobj/_index.adoc | 259 + .../content/ru/books/arch-handbook/kobj/_index.po | 622 ++ .../ru/books/arch-handbook/locking/_index.adoc | 145 + .../ru/books/arch-handbook/locking/_index.po | 390 + .../content/ru/books/arch-handbook/mac/_index.adoc | 5080 ++++++++++++ .../content/ru/books/arch-handbook/mac/_index.po | 8639 ++++++++++++++++++++ .../ru/books/arch-handbook/newbus/_index.adoc | 213 + .../ru/books/arch-handbook/newbus/_index.po | 711 ++ .../content/ru/books/arch-handbook/parti.adoc | 13 + .../content/ru/books/arch-handbook/parti.po | 31 + .../content/ru/books/arch-handbook/partii.adoc | 12 + .../content/ru/books/arch-handbook/partii.po | 31 + .../content/ru/books/arch-handbook/partiii.adoc | 12 + .../content/ru/books/arch-handbook/partiii.po | 31 + .../ru/books/arch-handbook/pccard/_index.adoc | 209 + .../ru/books/arch-handbook/pccard/_index.po | 710 ++ .../content/ru/books/arch-handbook/pci/_index.adoc | 424 + .../content/ru/books/arch-handbook/pci/_index.po | 1071 +++ .../ru/books/arch-handbook/scsi/_index.adoc | 1367 ++++ .../content/ru/books/arch-handbook/scsi/_index.po | 4280 ++++++++++ .../content/ru/books/arch-handbook/smp/_index.adoc | 360 + .../content/ru/books/arch-handbook/smp/_index.po | 1983 +++++ .../ru/books/arch-handbook/sound/_index.adoc | 351 + .../content/ru/books/arch-handbook/sound/_index.po | 1125 +++ .../ru/books/arch-handbook/sysinit/_index.adoc | 165 + .../ru/books/arch-handbook/sysinit/_index.po | 393 + .../content/ru/books/arch-handbook/usb/_index.adoc | 186 + .../content/ru/books/arch-handbook/usb/_index.po | 1200 +++ .../content/ru/books/arch-handbook/vm/_index.adoc | 127 + .../content/ru/books/arch-handbook/vm/_index.po | 551 ++ 44 files changed, 45342 insertions(+), 12 deletions(-) diff --git a/documentation/content/ru/books/arch-handbook/_index.adoc b/documentation/content/ru/books/arch-handbook/_index.adoc new file mode 100644 index 0000000000..7417861a9b --- /dev/null +++ b/documentation/content/ru/books/arch-handbook/_index.adoc @@ -0,0 +1,57 @@ +--- +add_single_page_link: true +authors: + - + author: 'The FreeBSD Documentation Project' +bookOrder: 50 +copyright: '2000-2006, 2012-2023 The FreeBSD Documentation Project' +description: 'Для разработчиков систем FreeBSD. В этой книге рассматриваются архитектурные особенности многих важных подсистем ядра FreeBSD' +next: books/arch-handbook/parti +params: + path: /books/arch-handbook/ +showBookMenu: true +tags: ["Arch Handbook", "FreeBSD"] +title: 'Руководство по архитектуре FreeBSD' +trademarks: ["freebsd", "apple", "microsoft", "unix", "general"] +weight: 0 +--- + += Руководство по архитектуре FreeBSD +:doctype: book +:toc: macro +:toclevels: 1 +:icons: font +:sectnums: +:sectnumlevels: 6 +:partnums: +:source-highlighter: rouge +:experimental: +:images-path: books/arch-handbook/ + +ifdef::env-beastie[] +ifdef::backend-html5[] +include::shared/authors.adoc[] +include::shared/mirrors.adoc[] +include::shared/releases.adoc[] +include::shared/attributes/attributes-{{% lang %}}.adoc[] +include::shared/{{% lang %}}/teams.adoc[] +include::shared/{{% lang %}}/mailing-lists.adoc[] +include::shared/{{% lang %}}/urls.adoc[] +endif::[] +ifdef::backend-pdf,backend-epub3[] +include::../../../../../shared/asciidoctor.adoc[] +endif::[] +endif::[] + +ifndef::env-beastie[] +include::../../../../../shared/asciidoctor.adoc[] +endif::[] + +[.abstract-title] +Аннотация + +Добро пожаловать в Руководство по архитектуре FreeBSD. Это руководство находится _в стадии разработки_ и создаётся усилиями многих участников. Многие разделы пока не написаны, а существующие могут требовать обновления. Если вы хотите помочь в работе над этим проектом, напишите на электронную почту списка рассылки {freebsd-doc}. + +Актуальная версия этого документа всегда доступна на https://www.FreeBSD.org/[официально веб-сервере FreeBSD]. Его также можно загрузить в различных форматах и с разными вариантами сжатия с https://download.freebsd.org/doc/[сервер загрузок FreeBSD] или одного из многочисленных зеркал extref:{handbook}mirrors/[mirror sites, mirrors]. + +''' diff --git a/documentation/content/ru/books/arch-handbook/_index.po b/documentation/content/ru/books/arch-handbook/_index.po new file mode 100644 index 0000000000..980f503404 --- /dev/null +++ b/documentation/content/ru/books/arch-handbook/_index.po @@ -0,0 +1,71 @@ +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR The FreeBSD Project +# This file is distributed under the same license as the FreeBSD Documentation package. +# Vladlen Popolitov <vladlenpopolitov@list.ru>, 2025. +msgid "" +msgstr "" +"Project-Id-Version: FreeBSD Documentation VERSION\n" +"POT-Creation-Date: 2025-10-14 22:43+0300\n" +"PO-Revision-Date: 2025-08-16 04:45+0000\n" +"Last-Translator: Vladlen Popolitov <vladlenpopolitov@list.ru>\n" +"Language-Team: Russian <https://translate-dev.freebsd.org/projects/" +"documentation/booksarch-handbook_index/ru/>\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.17\n" + +#. type: Yaml Front Matter Hash Value: description +#: documentation/content/en/books/arch-handbook/_index.adoc:1 +#, no-wrap +msgid "For FreeBSD system developers. This book covers the architectural details of many important FreeBSD kernel subsystems" +msgstr "Для разработчиков систем FreeBSD. В этой книге рассматриваются архитектурные особенности многих важных подсистем ядра FreeBSD" + +#. type: Title = +#: documentation/content/en/books/arch-handbook/_index.adoc:1 +#: documentation/content/en/books/arch-handbook/_index.adoc:18 +#, no-wrap +msgid "FreeBSD Architecture Handbook" +msgstr "Руководство по архитектуре FreeBSD" + +#. type: .abstract-title +#: documentation/content/en/books/arch-handbook/_index.adoc:51 +msgid "Abstract" +msgstr "Аннотация" + +#. type: .abstract-title +#: documentation/content/en/books/arch-handbook/_index.adoc:53 +msgid "" +"Welcome to the FreeBSD Architecture Handbook. This manual is a _work in " +"progress_ and is the work of many individuals. Many sections do not yet " +"exist and some of those that do exist need to be updated. If you are " +"interested in helping with this project, send email to the {freebsd-doc}." +msgstr "" +"Добро пожаловать в Руководство по архитектуре FreeBSD. Это руководство " +"находится _в стадии разработки_ и создаётся усилиями многих участников. " +"Многие разделы пока не написаны, а существующие могут требовать обновления. " +"Если вы хотите помочь в работе над этим проектом, напишите на электронную " +"почту списка рассылки {freebsd-doc}." + +#. type: .abstract-title +#: documentation/content/en/books/arch-handbook/_index.adoc:55 +msgid "" +"The latest version of this document is always available from the " +"link:https://www.FreeBSD.org/[FreeBSD World Wide Web server]. It may also be " +"downloaded in a variety of formats and compression options from the https://" +"download.freebsd.org/doc/[FreeBSD download server] or one of the numerous " +"extref:{handbook}[mirror sites, mirrors]." +msgstr "" +"Актуальная версия этого документа всегда доступна на https://www.FreeBSD.org/" +"[официальном веб-сервере FreeBSD]. Его также можно загрузить в различных " +"форматах и с разными вариантами сжатия с https://download.freebsd.org/doc/" +"[сервера загрузок FreeBSD] или одного из многочисленных зеркал extref:" +"{handbook}mirrors/[mirror sites, mirrors]." + +#. type: .abstract-title +#: documentation/content/en/books/arch-handbook/_index.adoc:56 +msgid "'''" +msgstr "'''" diff --git a/documentation/content/ru/books/arch-handbook/bibliography/_index.adoc b/documentation/content/ru/books/arch-handbook/bibliography/_index.adoc new file mode 100644 index 0000000000..96ff388686 --- /dev/null +++ b/documentation/content/ru/books/arch-handbook/bibliography/_index.adoc @@ -0,0 +1,51 @@ +--- +description: 'Библиография Руководства по архитектуре FreeBSD' +params: + path: /books/arch-handbook/bibliography/ +prev: books/arch-handbook/partiii +showBookMenu: true +tags: ["bibliography", "Arch Handbook", "FreeBSD"] +title: Библиография +weight: 20 +--- + +[appendix] +[[bibliography]] += Библиография +:doctype: book +:toc: macro +:toclevels: 1 +:icons: font +:sectnums: +:sectnumlevels: 6 +:sectnumoffset: A +:partnums: +:source-highlighter: rouge +:experimental: +:images-path: books/arch-handbook/ + +ifdef::env-beastie[] +ifdef::backend-html5[] +:imagesdir: ../../../../images/{images-path} +endif::[] +ifndef::book[] +include::shared/authors.adoc[] +include::shared/mirrors.adoc[] +include::shared/releases.adoc[] +include::shared/attributes/attributes-{{% lang %}}.adoc[] +include::shared/{{% lang %}}/teams.adoc[] +include::shared/{{% lang %}}/mailing-lists.adoc[] +include::shared/{{% lang %}}/urls.adoc[] +toc::[] +endif::[] +ifdef::backend-pdf,backend-epub3[] +include::../../../../../shared/asciidoctor.adoc[] +endif::[] +endif::[] + +ifndef::env-beastie[] +toc::[] +include::../../../../../shared/asciidoctor.adoc[] +endif::[] + +[1] _Marshall Kirk McKusick, Keith Bostic, Michael J Karels, and John S Quarterman._ Copyright © 1996 Addison-Wesley Publishing Company, Inc.. 0-201-54979-4. Издано Addison-Wesley Publishing Company, Inc.. The Design and Implementation of the 4.4 BSD Operating System. 1-2. diff --git a/documentation/content/ru/books/arch-handbook/bibliography/_index.po b/documentation/content/ru/books/arch-handbook/bibliography/_index.po new file mode 100644 index 0000000000..c5253e7d57 --- /dev/null +++ b/documentation/content/ru/books/arch-handbook/bibliography/_index.po @@ -0,0 +1,45 @@ +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR The FreeBSD Project +# This file is distributed under the same license as the FreeBSD Documentation package. +# Vladlen Popolitov <vladlenpopolitov@list.ru>, 2025. +msgid "" +msgstr "" +"Project-Id-Version: FreeBSD Documentation VERSION\n" +"POT-Creation-Date: 2025-10-14 22:43+0300\n" +"PO-Revision-Date: 2025-07-12 04:45+0000\n" +"Last-Translator: Vladlen Popolitov <vladlenpopolitov@list.ru>\n" +"Language-Team: Russian <https://translate-dev.freebsd.org/projects/" +"documentation/booksarch-handbookbibliography_index/ru/>\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.17\n" + +#. type: Yaml Front Matter Hash Value: description +#: documentation/content/en/books/arch-handbook/bibliography/_index.adoc:1 +#, no-wrap +msgid "Bibliography of the FreeBSD Architecture Handbook" +msgstr "Библиография Руководства по архитектуре FreeBSD" + +#. type: Title = +#: documentation/content/en/books/arch-handbook/bibliography/_index.adoc:1 +#: documentation/content/en/books/arch-handbook/bibliography/_index.adoc:14 +#, no-wrap +msgid "Bibliography" +msgstr "Библиография" + +#. type: appendix +#: documentation/content/en/books/arch-handbook/bibliography/_index.adoc:51 +msgid "" +"[1] _Marshall Kirk McKusick, Keith Bostic, Michael J Karels, and John S " +"Quarterman._ Copyright © 1996 Addison-Wesley Publishing Company, Inc.. " +"0-201-54979-4. Addison-Wesley Publishing Company, Inc.. The Design and " +"Implementation of the 4.4 BSD Operating System. 1-2." +msgstr "" +"[1] _Marshall Kirk McKusick, Keith Bostic, Michael J Karels, and John S " +"Quarterman._ Copyright © 1996 Addison-Wesley Publishing Company, Inc.. " +"0-201-54979-4. Издано Addison-Wesley Publishing Company, Inc.. The Design " +"and Implementation of the 4.4 BSD Operating System. 1-2." diff --git a/documentation/content/ru/books/arch-handbook/book.adoc b/documentation/content/ru/books/arch-handbook/book.adoc index 02d82d2ae2..22f9cfba0b 100644 --- a/documentation/content/ru/books/arch-handbook/book.adoc +++ b/documentation/content/ru/books/arch-handbook/book.adoc @@ -1,14 +1,16 @@ --- -title: FreeBSD Architecture Handbook -authors: - - author: The FreeBSD Documentation Project -copyright: 2000-2006, 2012-2013 The FreeBSD Documentation Project -description: FreeBSD Architecture Handbook -trademarks: ["freebsd", "apple", "microsoft", "unix", "general"] +add_split_page_link: true +authors: + - + author: 'The FreeBSD Documentation Project' +copyright: '2000-2006, 2012-2023 The FreeBSD Documentation Project' +description: 'Для разработчиков систем FreeBSD. В этой книге рассматриваются архитектурные особенности многих важных подсистем ядра FreeBSD' tags: ["Arch Handbook", "FreeBSD"] +title: 'Руководство по архитектуре FreeBSD' +trademarks: ["freebsd", "apple", "microsoft", "unix", "general"] --- -= FreeBSD Architecture Handbook += Руководство по архитектуре FreeBSD :doctype: book :toc: macro :toclevels: 2 @@ -20,7 +22,6 @@ tags: ["Arch Handbook", "FreeBSD"] :experimental: :book: true :pdf: false -:images-path: books/arch-handbook/ ifdef::env-beastie[] ifdef::backend-html5[] @@ -44,15 +45,39 @@ ifndef::env-beastie[] include::../../../../../shared/asciidoctor.adoc[] endif::[] +[.abstract-title] +Аннотация + +Добро пожаловать в Руководство по архитектуре FreeBSD. Это руководство находится _в стадии разработки_ и создаётся усилиями многих участников. Многие разделы пока не написаны, а существующие могут требовать обновления. Если вы хотите помочь в работе над этим проектом, напишите на электронную почту списка рассылки {freebsd-doc}. + +Актуальная версия этого документа всегда доступна на https://www.FreeBSD.org/[официально веб-сервере FreeBSD]. Его также можно загрузить в различных форматах и с разными вариантами сжатия с https://download.freebsd.org/doc/[сервер загрузок FreeBSD] или одного из многочисленных зеркал extref:{handbook}mirrors/[mirror sites, mirrors]. + ''' toc::[] // Section one - -include::{chapters-path}locking/chapter.adoc[leveloffset=+1] +include::{chapters-path}parti.adoc[] +include::{chapters-path}boot/_index.adoc[leveloffset=+1] +include::{chapters-path}locking/_index.adoc[leveloffset=+1] +include::{chapters-path}kobj/_index.adoc[leveloffset=+1] +include::{chapters-path}jail/_index.adoc[leveloffset=+1] +include::{chapters-path}sysinit/_index.adoc[leveloffset=+1]] +include::{chapters-path}mac/_index.adoc[leveloffset=+1] +include::{chapters-path}vm/_index.adoc[leveloffset=+1] +include::{chapters-path}smp/_index.adoc[leveloffset=+1] // Section two +include::{chapters-path}partii.adoc[] +include::{chapters-path}driverbasics/_index.adoc[leveloffset=+1] +include::{chapters-path}isa/_index.adoc[leveloffset=+1] +include::{chapters-path}pci/_index.adoc[leveloffset=+1] +include::{chapters-path}scsi/_index.adoc[leveloffset=+1] +include::{chapters-path}usb/_index.adoc[leveloffset=+1] +include::{chapters-path}newbus/_index.adoc[leveloffset=+1] +include::{chapters-path}sound/_index.adoc[leveloffset=+1] +include::{chapters-path}pccard/_index.adoc[leveloffset=+1] -include::{chapters-path}driverbasics/chapter.adoc[leveloffset=+1] -include::{chapters-path}sound/chapter.adoc[leveloffset=+1] +// Section three +include::{chapters-path}partiii.adoc[] +include::{chapters-path}bibliography/_index.adoc[leveloffset=+1] diff --git a/documentation/content/ru/books/arch-handbook/book.po b/documentation/content/ru/books/arch-handbook/book.po new file mode 100644 index 0000000000..a099efa2f7 --- /dev/null +++ b/documentation/content/ru/books/arch-handbook/book.po @@ -0,0 +1,71 @@ +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR The FreeBSD Project +# This file is distributed under the same license as the FreeBSD Documentation package. +# Vladlen Popolitov <vladlenpopolitov@list.ru>, 2025. +msgid "" +msgstr "" +"Project-Id-Version: FreeBSD Documentation VERSION\n" +"POT-Creation-Date: 2025-10-14 22:43+0300\n" +"PO-Revision-Date: 2025-08-16 04:45+0000\n" +"Last-Translator: Vladlen Popolitov <vladlenpopolitov@list.ru>\n" +"Language-Team: Russian <https://translate-dev.freebsd.org/projects/" +"documentation/booksarch-handbookbook/ru/>\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 4.17\n" + +#. type: Yaml Front Matter Hash Value: description +#: documentation/content/en/books/arch-handbook/book.adoc:1 +#, no-wrap +msgid "For FreeBSD system developers. This book covers the architectural details of many important FreeBSD kernel subsystems" +msgstr "Для разработчиков систем FreeBSD. В этой книге рассматриваются архитектурные особенности многих важных подсистем ядра FreeBSD" + +#. type: Title = +#: documentation/content/en/books/arch-handbook/book.adoc:1 +#: documentation/content/en/books/arch-handbook/book.adoc:12 +#, no-wrap +msgid "FreeBSD Architecture Handbook" +msgstr "Руководство по архитектуре FreeBSD" + +#. type: .abstract-title +#: documentation/content/en/books/arch-handbook/book.adoc:49 +msgid "Abstract" +msgstr "Аннотация" + +#. type: .abstract-title +#: documentation/content/en/books/arch-handbook/book.adoc:51 +msgid "" +"Welcome to the FreeBSD Architecture Handbook. This manual is a _work in " +"progress_ and is the work of many individuals. Many sections do not yet " +"exist and some of those that do exist need to be updated. If you are " +"interested in helping with this project, send email to the {freebsd-doc}." +msgstr "" +"Добро пожаловать в Руководство по архитектуре FreeBSD. Это руководство " +"находится _в стадии разработки_ и создаётся усилиями многих участников. " +"Многие разделы пока не написаны, а существующие могут требовать обновления. " +"Если вы хотите помочь в работе над этим проектом, напишите на электронную " +"почту списка рассылки {freebsd-doc}." + +#. type: .abstract-title +#: documentation/content/en/books/arch-handbook/book.adoc:53 +msgid "" +"The latest version of this document is always available from the " +"link:https://www.FreeBSD.org/[FreeBSD World Wide Web server]. It may also be " +"downloaded in a variety of formats and compression options from the https://" +"download.freebsd.org/doc/[FreeBSD download server] or one of the numerous " +"extref:{handbook}[mirror sites, mirrors]." +msgstr "" +"Актуальная версия этого документа всегда доступна на https://www.FreeBSD.org/" +"[официальном веб-сервере FreeBSD]. Его также можно загрузить в различных " +"форматах и с разными вариантами сжатия с https://download.freebsd.org/doc/" +"[сервера загрузок FreeBSD] или одного из многочисленных зеркал extref:" +"{handbook}mirrors/[mirror sites, mirrors]." + +#. type: .abstract-title +#: documentation/content/en/books/arch-handbook/book.adoc:55 +msgid "'''" +msgstr "'''" diff --git a/documentation/content/ru/books/arch-handbook/boot/_index.adoc b/documentation/content/ru/books/arch-handbook/boot/_index.adoc new file mode 100644 index 0000000000..5b356b42ac --- /dev/null +++ b/documentation/content/ru/books/arch-handbook/boot/_index.adoc @@ -0,0 +1,1351 @@ +--- +description: 'Начальная загрузка и инициализация ядра' +next: books/arch-handbook/locking +params: + path: /books/arch-handbook/boot/ +prev: books/arch-handbook/parti +showBookMenu: true +tags: ["boot", "BIOS", "kernel", "MBR", "FreeBSD"] +title: 'Глава 1. Начальная загрузка и инициализация ядра' +weight: 2 +--- + +[[boot]] += Начальная загрузка и инициализация ядра +:doctype: book +:toc: macro +:toclevels: 1 +:icons: font +:sectnums: +:sectnumlevels: 6 +:sectnumoffset: 1 +:partnums: +:source-highlighter: rouge +:experimental: +:images-path: books/arch-handbook/ + +ifdef::env-beastie[] +ifdef::backend-html5[] +:imagesdir: ../../../../images/{images-path} +endif::[] +ifndef::book[] +include::shared/authors.adoc[] +include::shared/mirrors.adoc[] +include::shared/releases.adoc[] +include::shared/attributes/attributes-{{% lang %}}.adoc[] +include::shared/{{% lang %}}/teams.adoc[] +include::shared/{{% lang %}}/mailing-lists.adoc[] +include::shared/{{% lang %}}/urls.adoc[] +toc::[] +endif::[] +ifdef::backend-pdf,backend-epub3[] +include::../../../../../shared/asciidoctor.adoc[] +endif::[] +endif::[] + +ifndef::env-beastie[] +toc::[] +include::../../../../../shared/asciidoctor.adoc[] +endif::[] + +[[boot-synopsis]] +== Обзор + +Эта глава представляет собой обзор процессов загрузки и инициализации системы, начиная с POST в BIOS (микропрограмме) и заканчивая созданием первого пользовательского процесса. Поскольку начальные этапы загрузки системы сильно зависят от архитектуры, в качестве примера используется архитектура IA-32. Однако архитектуры AMD64 и ARM64 гораздо важнее и интереснее, и их следует рассмотреть в ближайшем будущем в соответствии с темой этого документа. + +Процесс загрузки FreeBSD может быть удивительно сложным. После передачи управления от BIOS необходимо выполнить значительный объем низкоуровневой настройки перед загрузкой и выполнением ядра. Эта настройка должна быть выполнена простым и гибким способом, предоставляя пользователю широкие возможности для настройки и адаптации. + +[[boot-overview]] +== Обзор + +Процесс загрузки — это операция, крайне зависимая от оборудования. Не только для каждой архитектуры компьютера должен быть написан код, но также могут существовать различные типы загрузки в рамках одной архитектуры. Например, список файлов в каталоге [.filename]#stand# показывает большое количество кода, зависящего от архитектуры. Для каждой из поддерживаемых архитектур существует отдельный каталог. FreeBSD поддерживает стандарт загрузки CSM (Compatibility Support Module). Таким образом, CSM поддерживается (как с GPT, так и с MBR разметкой), а также загрузка через UEFI (GP T полностью поддерживается, MBR — в основном). Также поддерживается загрузка файлов с ext2fs, MSDOS, UFS и ZFS. FreeBSD поддерживает функцию загрузочного окружения ZFS, которая позволяет основной ОС передавать детали о том, что загружать, выходящие за рамки простого раздела, как это было возможно ранее. Однако в наши дни UEFI более актуален, чем CSM. В следующем примере показана загрузка компьютера x86 с жёсткого диска с MBR-разметкой, где используется мультизагрузчик FreeBSD [.filename]#boot0#, сохранённый в самом первом секторе. Этот загрузочный код запускает трёхэтапный роцесс загрузки FreeBSD. + +Ключ к пониманию этого процесса заключается в том, что он состоит из последовательных стадий возрастающей сложности. Эти стадии — [.filename]#boot1#, [.filename]#boot2# и [.filename]#loader# (подробнее см. man:boot[8]). Система загрузки выполняет каждую стадию последовательно. Последняя стадия, [.filename]#loader#, отвечает за загрузку ядра FreeBSD. Каждая стадия рассматривается в следующих разделах. + +Вот пример вывода, сгенерированного на различных этапах загрузки. Фактический вывод может отличаться в зависимости от машины: + +[.informaltable] +[cols="20%,80%", frame="none"] +|=== + +|*Компонент FreeBSD* +|*Вывод (может отличаться)* + +|`boot0` +a| + +[source,bash] +.... +F1 FreeBSD +F2 BSD +F5 Disk 2 +.... + +|`boot2` footnote:[Это приглашение появится, если пользователь нажмет клавишу сразу после выбора ОС для загрузки на этапе boot0.] +a| + +[source,bash] +.... +>>FreeBSD/x86 BOOT +Default: 0:ad(0p4)/boot/loader +boot: +.... + +|[.filename]#loader# +a| + +[source,bash] +.... +BTX loader 1.00 BTX version is 1.02 +Consoles: internal video/keyboard +BIOS drive C: is disk0 +BIOS 639kB/2096064kB available memory + +FreeBSD/x86 bootstrap loader, Revision 1.1 +Console internal video/keyboard +(root@releng1.nyi.freebsd.org, Fri Apr 9 04:04:45 UTC 2021) +Loading /boot/defaults/loader.conf +/boot/kernel/kernel text=0xed9008 data=0x117d28+0x176650 syms=[0x8+0x137988+0x8+0x1515f8] +.... + +|ядро системы +a| + +[source,bash] +.... +Copyright (c) 1992-2021 The FreeBSD Project. +Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 + The Regents of the University of California. All rights reserved. +FreeBSD is a registered trademark of The FreeBSD Foundation. +FreeBSD 13.0-RELEASE 0 releng/13.0-n244733-ea31abc261f: Fri Apr 9 04:04:45 UTC 2021 + root@releng1.nyi.freebsd.org:/usr/obj/usr/src/i386.i386/sys/GENERIC i386 +FreeBSD clang version 11.0.1 (git@github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c3fe) +.... + +|=== + +[[boot-bios]] +== BIOS + +При включении компьютера регистры процессора устанавливаются в некоторые предопределённые значения. Один из регистров — это регистр _указателя команд_, и его значение после включения питания чётко определено: это 32-битное значение `0xfffffff0`. Регистр указателя команд (также известный как Счётчик Команд) указывает на код, который должен быть выполнен процессором. Ещё один важный регистр — это 32-битный управляющий регистр `cr0`, и его значение сразу после перезагрузки равно `0`. Один из битов ``cr0``, бит PE (Protection Enabled, Защита Включена), указывает, рабо тает ли процессор в 32-битном защищённом режиме или 16-битном реальном режиме. Поскольку этот бит сброшен при загрузке, процессор запускается в 16-битном реальном режиме. Реальный режим означает, среди прочего, что линейные и физические адреса идентичны. Причина, по которой процессор не запускается сразу в 32-битном защищённом режиме, — это обратная совместимость. В частности, процесс загрузки зависит от услуг, предоставляемых BIOS, а сам BIOS работает в устаревшем 16-битном коде. + +Значение `0xfffffff0` немного меньше 4 ГБ, поэтому, если в машине нет 4 ГБ физической памяти, оно не может указывать на действительный адрес памяти. Аппаратное обеспечение компьютера преобразует этот адрес так, чтобы он указывал на блок памяти BIOS. + +BIOS (Basic Input Output System) — это микросхема на материнской плате, которая содержит относительно небольшой объем памяти только для чтения (ROM). Эта память включает различные низкоуровневые процедуры, специфичные для оборудования, поставляемого с материнской платой. Процессор сначала переходит по адресу 0xfffffff0, который фактически находится в памяти BIOS. Обычно по этому адресу содержится инструкция перехода к процедурам POST BIOS. + +POST (Power On Self Test) — это набор процедур, включающих проверку памяти, проверку системной шины и другую низкоуровневую инициализацию, чтобы процессор мог правильно настроить компьютер. Важным этапом на этой стадии является определение загрузочного устройства. Современные реализации BIOS позволяют выбирать загрузочное устройство, обеспечивая загрузку с дискеты, CD-ROM, жесткого диска или других устройств. + +Самым последним действием в POST является инструкция `INT 0x19`. Обработчик `INT 0x19` считывает 512 байт из первого сектора загрузочного устройства в память по адресу `0x7c00`. Термин _первый сектор_ происходит из архитектуры жёстких дисков, где магнитная пластина разделена на множество цилиндрических дорожек. Дорожки нумеруются, и каждая дорожка разделена на несколько (обычно 64) секторов. Нумерация дорожек начинается с 0, но нумерация секторов начинается с 1. Дорожка 0 находится на внешней стороне магнитной пластины, а сектор 1, первый сектор, имеет особо е назначение. Он также называется MBR (Master Boot Record) или Главная Загрузочная Запись. Остальные секторы на первой дорожке не используются. + +Этот сектор является нашей точкой входа в последовательность загрузки. Как мы увидим, этот сектор содержит копию нашей программы [.filename]#boot0#. BIOS выполняет переход по адресу `0x7c00`, и она начинает выполняться. + +[[boot-boot0]] +== Главная загрузочная запись (`boot0`) + +После получения управления от BIOS по адресу памяти `0x7c00` начинает выполняться [.filename]#boot0#. Это первый код, который управляется FreeBSD. Задача [.filename]#boot0# довольно проста: просканировать таблицу разделов и позволить пользователю выбрать, с какого раздела загружаться. Таблица разделов — это специальная стандартная структура данных, встроенная в MBR (а значит, и в [.filename]#boot0#), которая описывает четыре стандартных PC-раздела. [.filename]#boot0# находится в файловой системе как [.filename]#/boot/boot0#. Это небольшой файл размером 512 байт, и именно его процедура установки Fr eeBSD записывает в MBR жёсткого диска, если во время установки была выбрана опция "bootmanager". Действительно, [.filename]#boot0# _и есть_ MBR. + +Как упоминалось ранее, мы вызываем прерывание BIOS `INT 0x19` для загрузки MBR ([.filename]#boot0#) в память по адресу `0x7c00`. Исходный файл для [.filename]#boot0# можно найти в [.filename]#stand/i386/boot0/boot0.S# — это впечатляющий фрагмент кода, написанный Робертом Нордье. + +Особая структура, начинающаяся со смещения `0x1be` в MBR, называется _таблицей разделов_. Она содержит четыре записи по 16 байт каждая, называемые _записями разделов_, которые определяют, как разделён жёсткий диск, или, в терминологии FreeBSD, нарезан. Один из этих 16 байт указывает, является ли раздел (срез) загрузочным или нет. Ровно одна запись должна быть с этом установленным флагом, иначе код [.filename]#boot0# откажется продолжать работу. + +Запись о разделе содержит следующие поля: + +* 1-байтовый тип файловой системы +* 1-байтовый флаг загрузки (`bootable`) +* 6-байтовый дескриптор в формате CHS +* 8-байтовый дескриптор в формате LBA + +Дескриптор записи раздела содержит информацию о том, где именно раздел расположен на диске. Оба дескриптора, LBA и CHS, описывают одну и ту же информацию, но разными способами: LBA (Logical Block Addressing) содержит начальный сектор раздела и его длину, тогда как CHS (Cylinder Head Sector) содержит координаты первого и последнего секторов раздела. Таблица разделов завершается специальной сигнатурой `0xaa55`. + +MBR должен помещаться в 512 байт, один сектор диска. Эта программа использует низкоуровневые «трюки», такие как использование побочных эффектов определённых инструкций и повторное использование значений регистров из предыдущих операций, чтобы максимально эффективно использовать минимально возможное количество инструкций. Также необходимо соблюдать осторожность при работе с таблицей разделов, которая встроена в сам MBR. По этим причинам будьте очень внимательны при изменении [.filename]#boot0.S#. + +Обратите внимание, что исходный файл [.filename]#boot0.S# ассемблируется "как есть": инструкции переводятся одна за одной в бинарный код без дополнительной информации (например, без формата файла ELF). Такой низкоуровневый контроль достигается на этапе компоновки с помощью специальных флагов, передаваемых компоновщику. Например, текстовая секция программы располагается по адресу `0x600`. На практике это означает, что [.filename]#boot0# должен быть загружен в память по адресу `0x600` для корректной работы. + +Стоит взглянуть на [.filename]#Makefile# для [.filename]#boot0# ([.filename]#stand/i386/boot0/Makefile#), так как он определяет некоторые аспекты поведения [.filename]#boot0# во время выполнения. Например, если для ввода-вывода используется терминал, подключённый к последовательному порту (COM1), необходимо определить макрос `SIO` (`-DSIO`). `-DPXE` включает загрузку через PXE при нажатии kbd:[F6]. Кроме того, программа определяет набор _флагов_, которые позволяют дополнительно настроить её поведение. Всё это проиллюстрировано в [.filename]#Makefile#. Например, обратите внимание на директивы компоновщика, кото рые предписывают ему начинать секцию текста с адреса `0x600` и создавать выходной файл "как есть" (удаляя любое форматирование файла): + +[.programlisting] +.... + BOOT_BOOT0_ORG?=0x600 + ORG=${BOOT_BOOT0_ORG} +.... + +.[.filename]#stand/i386/boot0/Makefile# [[boot-boot0-makefile-as-is]] +Приступим к изучению MBR, или [.filename]#boot0#, начиная с точки входа. + +[NOTE] +==== +В некоторые инструкции были внесены изменения для лучшего изложения. Например, некоторые макросы раскрыты, а некоторые проверки макросов опущены, когда результат проверки известен. Это относится ко всем приведённым примерам кода. +==== + +[.programlisting] +.... +start: + cld # String ops inc + xorw %ax,%ax # Zero + movw %ax,%es # Address + movw %ax,%ds # data + movw %ax,%ss # Set up + movw $LOAD,%sp # stack +.... + +.[.filename]#stand/i386/boot0/boot0.S# [[boot-boot0-entrypoint]] +Этот первый блок кода является точкой входа программы. Именно сюда BIOS передаёт управление. Сначала он гарантирует, что строковые операции автоматически увеличивают указатели операндов (инструкция `cld`) footnote:[В случае сомнений мы отсылаем читателя к официальным руководствам Intel, где описана точная семантика каждой инструкции: .]. Затем, не делая предположений о состоянии сегментных регистров, он их инициализирует. Наконец, он устанавливает регистр указателя стека (`%sp`) в ($LOAD = адрес `0x7c00`), чтобы обеспечить работоспособный стек. + +Следующий блок отвечает за перемещение и последующий переход к перемещенному коду. + +[.programlisting] +.... + movw %sp,%si # Source + movw $start,%di # Destination + movw $0x100,%cx # Word count + rep # Relocate + movsw # code + movw %di,%bp # Address variables + movb $0x8,%cl # Words to clear + rep # Zero + stosw # them + incb -0xe(%di) # Set the S field to 1 + jmp main-LOAD+ORIGIN # Jump to relocated code +.... + +.[.filename]#stand/i386/boot0/boot0.S# [[boot-boot0-relocation]] +Так как [.filename]#boot0# загружается BIOS по адресу `0x7C00`, он копирует себя по адресу `0x600` и передаёт управление туда (напомним, что он был слинкован для выполнения по адресу `0x600`). Исходный адрес, `0x7c00`, копируется в регистр `%si`. Конечный адрес, `0x600`, — в регистр `%di`. Количество слов для копирования, `256` (размер программы = 512 байт), копируется в регистр `%cx`. Далее инструкция `rep` повторяет следующую за ней инструкцию, то есть `movsw`, количество раз, указанное в регистре `%cx`. Инструкция `movsw` копирует слово, на которое указывает `%si`, по адресу, на который указывает `%d i`. Это повторяется ещё 255 раз. При каждом повторении оба регистра, исходный и конечный, `%si` и `%di`, увеличиваются на единицу. Таким образом, по завершении копирования 256 слов (512 байт), `%di` имеет значение `0x600`+`512`= `0x800`, а `%si` — значение `0x7c00`+`512`= `0x7e00`; таким образом, мы завершили _перемещение_ кода. С момента последнего обновления этого документа инструкции копирования в коде изменились, поэтому вместо movsb и stosb были введены movsw и stosw, которые копируют 2 байта (1 слово) за одну итерацию. + +Затем регистр назначения `%di` копируется в `%bp`. `%bp` получает значение `0x800`. Значение `8` копируется в `%cl` для подготовки новой строковой операции (как в предыдущей `movsw`). Теперь `stosw` выполняется 8 раз. Эта инструкция копирует значение `0` по адресу, на который указывает регистр назначения (`%di`, то есть `0x800`), и увеличивает его. Это повторяется ещё 7 раз, так что `%di` в итоге получает значение `0x810`. Фактически это очищает диапазон адресов `0x800`-`0x80f`. Этот диапазон используется как (фиктивная) таблица разделов для записи MBR обратно на диск. Наконец, полю секто ра для CHS-адресации этого фиктивного раздела присваивается значение 1, и выполняется переход к основной функции из перемещённого кода. Обратите внимание, что до этого перехода к перемещённому коду любые ссылки на абсолютные адреса избегались. + +Следующий блок кода проверяет, следует ли использовать номер диска, предоставленный BIOS, или тот, что хранится в [.filename]#boot0#. + +[.programlisting] +.... +main: + testb $SETDRV,_FLAGS(%bp) # Set drive number? +#ifndef CHECK_DRIVE /* disable drive checks */ + jz save_curdrive # no, use the default +#else + jnz disable_update # Yes + testb %dl,%dl # Drive number valid? + js save_curdrive # Possibly (0x80 set) +#endif +.... + +.[.filename]#stand/i386/boot0/boot0.S# [[boot-boot0-drivenumber]] +Этот код проверяет бит `SETDRV` (`0x20`) в переменной _flags_. Напомним, что регистр `%bp` указывает на адрес `0x800`, поэтому проверка выполняется для переменной _flags_ по адресу `0x800`-`69`= `0x7bb`. Это пример типа изменений, которые можно внести в [.filename]#boot0#. Флаг `SETDRV` не установлен по умолчанию, но его можно задать в [.filename]#Makefile#. Если он установлен, используется номер диска, сохранённый в MBR, вместо предоставленного BIOS. Мы предполагаем значения по умолчанию и то, что BIOS предоставил корректный номер диска, поэтому переходим к `save_curdrive`. + +Следующий блок сохраняет номер диска, предоставленный BIOS, и вызывает `putn` для вывода новой строки на экран. + +[.programlisting] +.... +save_curdrive: + movb %dl, (%bp) # Save drive number + pushw %dx # Also in the stack +#ifdef TEST /* test code, print internal bios drive */ + rolb $1, %dl + movw $drive, %si + call putkey +#endif + callw putn # Print a newline +.... + +.[.filename]#stand/i386/boot0/boot0.S# [[boot-boot0-savedrivenumber]] +Обратите внимание, что мы предполагаем, что `TEST` не определён, поэтому условный код в нём не собирается и не появится в нашем исполняемом файле [.filename]#boot0#. + +Следующий блок реализует фактическое сканирование таблицы разделов. Он выводит на экран тип раздела для каждой из четырёх записей в таблице разделов. Каждый тип сравнивается со списком известных файловых систем операционных систем. Примерами распознаваемых типов разделов являются NTFS (Windows(R), ID 0x7), `ext2fs` (Linux(R), ID 0x83) и, конечно же, `ffs`/`ufs2` (FreeBSD, ID 0xa5). Реализация довольно проста. + +[.programlisting] +.... + movw $(partbl+0x4),%bx # Partition table (+4) + xorw %dx,%dx # Item number + +read_entry: + movb %ch,-0x4(%bx) # Zero active flag (ch == 0) + btw %dx,_FLAGS(%bp) # Entry enabled? + jnc next_entry # No + movb (%bx),%al # Load type + test %al, %al # skip empty partition + jz next_entry + movw $bootable_ids,%di # Lookup tables + movb $(TLEN+1),%cl # Number of entries + repne # Locate + scasb # type + addw $(TLEN-1), %di # Adjust + movb (%di),%cl # Partition + addw %cx,%di # description + callw putx # Display it + +next_entry: + incw %dx # Next item + addb $0x10,%bl # Next entry + jnc read_entry # Till done +.... + +.[.filename]#stand/i386/boot0/boot0.S# [[boot-boot0-partition-scan]] +Важно отметить, что флаг активности для каждой записи сбрасывается, поэтому после сканирования _ни одна_ запись о разделе не активна в нашей копии [.filename]#boot0# в памяти. Позже флаг активности будет установлен для выбранного раздела. Это гарантирует, что только один активный раздел существует, если пользователь решит записать изменения обратно на диск. + +Следующий блок проверяет наличие других дисков. При запуске BIOS записывает количество дисков, присутствующих в компьютере, по адресу `0x475`. Если есть другие диски, [.filename]#boot0# выводит текущий диск на экран. Пользователь может позже дать команду [.filename]#boot0# просканировать разделы на другом диске. + +[.programlisting] +.... + popw %ax # Drive number + subb $0x80-0x1,%al # Does next + cmpb NHRDRV,%al # drive exist? (from BIOS?) + jb print_drive # Yes + decw %ax # Already drive 0? + jz print_prompt # Yes +.... + +.[.filename]#stand/i386/boot0/boot0.S# [[boot-boot0-test-drives]] +Мы предполагаем, что присутствует только один диск, поэтому переход к `print_drive` не выполняется. Также мы предполагаем, что ничего необычного не произошло, поэтому переходим к `print_prompt`. + +Следующий блок просто выводит приглашение с последующим вариантом по умолчанию: + +[.programlisting] +.... +print_prompt: + movw $prompt,%si # Display + callw putstr # prompt + movb _OPT(%bp),%dl # Display + decw %si # default + callw putkey # key + jmp start_input # Skip beep +.... + +.[.filename]#stand/i386/boot0/boot0.S# [[boot-boot0-prompt]] +Наконец, выполняется переход к `start_input`, где используются сервисы BIOS для запуска таймера и чтения пользовательского ввода с клавиатуры; если таймер истекает, будет выбран вариант по умолчанию: + +[.programlisting] +.... +start_input: + xorb %ah,%ah # BIOS: Get + int $0x1a # system time + movw %dx,%di # Ticks when + addw _TICKS(%bp),%di # timeout +read_key: + movb $0x1,%ah # BIOS: Check + int $0x16 # for keypress + jnz got_key # Have input + xorb %ah,%ah # BIOS: int 0x1a, 00 + int $0x1a # get system time + cmpw %di,%dx # Timeout? + jb read_key # No +.... + +.[.filename]#stand/i386/boot0/boot0.S# [[boot-boot0-start-input]] +Прерывание запрашивается с номером `0x1a` и аргументом `0` в регистре `%ah`. BIOS имеет предопределённый набор сервисов, запрашиваемых приложениями как программно-генерируемые прерывания через инструкцию `int`, с получением аргументов в регистрах (в данном случае, `%ah`). Здесь, в частности, запрашивается количество тиков часов с момента последней полуночи; это значение вычисляется BIOS через RTC (Real Time Clock). Эти часы могут быть настроены на работу с частотой от 2 Гц до 8192 Гц. BIOS устанавливает их на 18,2 Гц при запуске. Когда запрос выполнен, 32-битный результат озвращается BIOS в регистрах `%cx` и `%dx` (младшие байты в `%dx`). Этот результат (часть `%dx`) копируется в регистр `%di`, и к `%di` добавляется значение переменной `TICKS`. Эта переменная находится в [.filename]#boot0# по смещению `_TICKS` (отрицательное значение) от регистра `%bp` (который, напомним, указывает на `0x800`). Значение этой переменной по умолчанию — `0xb6` (182 в десятичной системе). Идея заключается в том, что [.filename]#boot0# постоянно запрашивает время у BIOS, и когда значение, возвращённое в регистре `%dx`, становится больше значения, хранящегося в `%di`, время истекает и будет сд лан выбор по умолчанию. ! Поскольку RTC тикает 18,2 раза в секунду, это условие выполнится через 10 секунд (это поведение по умолчанию можно изменить в [.filename]#Makefile#). До истечения этого времени [.filename]#boot0# непрерывно опрашивает BIOS на предмет ввода пользователя; это делается через `int 0x16`, аргумент `1` в `%ah`. + +Была нажата клавиша или истекло время, последующий код проверяет выбор. В зависимости от выбора, регистр `%si` устанавливается так, чтобы указывать на соответствующую запись раздела в таблице разделов. Этот новый выбор переопределяет предыдущий выбор по умолчанию. Действительно, он становится новым значением по умолчанию. Наконец, устанавливается флаг ACTIVE выбранного раздела. Если это было разрешено при компиляции, версия [.filename]#boot0# в памяти с этими изменёнными значениями записывается обратно в MBR на диске. Мы оставляем детали этой реализа ии читателю. + +Мы завершаем наше изучение последним блоком кода из программы [.filename]#boot0#: + +[.programlisting] +.... + movw $LOAD,%bx # Address for read + movb $0x2,%ah # Read sector + callw intx13 # from disk + jc beep # If error + cmpw $MAGIC,0x1fe(%bx) # Bootable? + jne beep # No + pushw %si # Save ptr to selected part. + callw putn # Leave some space + popw %si # Restore, next stage uses it + jmp *%bx # Invoke bootstrap +.... + +.[.filename]#stand/i386/boot0/boot0.S# [[boot-boot0-check-bootable]] +Вспомним, что `%si` указывает на выбранную запись раздела. Эта запись сообщает нам, где начинается раздел на диске. Мы предполагаем, конечно, что выбранный раздел действительно является срезом FreeBSD. + +[NOTE] +==== +Отныне мы будем отдавать предпочтение использованию технически более точного термина "слайс" вместо "раздел". +==== + +Буфер передачи установлен в `0x7c00` (регистр `%bx`), и запрос на чтение первого сектора слайса FreeBSD выполняется вызовом `intx13`. Мы предполагаем, что всё прошло успешно, поэтому переход к `beep` не выполняется. В частности, новый прочитанный сектор должен заканчиваться магической последовательностью `0xaa55`. Наконец, значение в `%si` (указатель на выбранную таблицу разделов) сохраняется для использования на следующем этапе, и выполняется переход по адресу `0x7c00`, где начинается выполнение нашего следующего этапа (только что прочитанного блока). + +[[boot-boot1]] +== Этап `boot1` + +До сих пор мы прошли следующую последовательность: + +* BIOS выполнил первоначальную инициализацию оборудования, включая POST. MBR ([.filename]#boot0#) был загружен по адресу `0x7c00` из абсолютного сектора один с диска. Управление выполнением было передано по этому адресу. +* [.filename]#boot0# переместил себя по адресу, по которому он был скомпонован для выполнения (`0x600`), после чего выполнил переход для продолжения выполнения в соответствующем месте. В завершение, [.filename]#boot0# загрузил первый сектор диска из раздела FreeBSD по адресу `0x7c00`. Управление выполнением было передано по этому адресу. + +[.filename]#boot1# — это следующий шаг в последовательности загрузки. Это первая из трех стадий загрузки. Обратите внимание, что до сих пор мы работали исключительно с секторами диска. Действительно, BIOS загружает самый первый сектор, а [.filename]#boot0# загружает первый сектор раздела FreeBSD. Обе загрузки происходят по адресу `0x7c00`. Мы можем концептуально представлять эти секторы диска как содержащие файлы [.filename]#boot0# и [.filename]#boot1#, соответственно, но на самом деле это не совсем верно для [.filename]#boot1#. Строго говоря, в отличие от [.filename]#boot0#, [.filename]#boot1# не является ча стью загрузочных блоков footnote:[Файл /boot/boot1 существует, но он не записывается в начало раздела FreeBSD. Вместо этого он объединяется с boot2, формируя файл boot, который записывается в начало раздела FreeBSD и считывается во время загрузки.]. Вместо этого, единый полноценный файл [.filename]#boot# ([.filename]#/boot/boot#) в итоге записывается на диск. Этот файл представляет собой комбинацию [.filename]#boot1#, [.filename]#boot2# и `Boot Extender` (или BTX). Этот единый файл превышает размер одного сектора (больше 512 байт). К счастью, [.filename]#boot1# занимает _ровно_ первые 512 байт этого файла, поэтому, когда [.f ilename]#boot0# загружает перв! й сектор раздела FreeBSD (512 байт), он фактически загружает [.filename]#boot1# и передает ему управление. + +Основная задача [.filename]#boot1# — загрузить следующий этап загрузки. Этот следующий этап несколько сложнее. Он состоит из сервера под названием "Boot Extender" (BTX) и клиента под названием [.filename]#boot2#. Как мы увидим, последний этап загрузки, [.filename]#loader#, также является клиентом сервера BTX. + +Давайте теперь подробно рассмотрим, что именно делает [.filename]#boot1#, начиная, как мы это делали для [.filename]#boot0#, с точки входа: + +[.programlisting] +.... +start: + jmp main +.... + +.[.filename]#stand/i386/boot2/boot1.S# [[boot-boot1-entry]] +Точка входа `start` просто переходит через специальную область данных к метке `main`, которая, в свою очередь, выглядит следующим образом: + +[.programlisting] +.... +main: + cld # String ops inc + xor %cx,%cx # Zero + mov %cx,%es # Address + mov %cx,%ds # data + mov %cx,%ss # Set up + mov $start,%sp # stack + mov %sp,%si # Source + mov $MEM_REL,%di # Destination + incb %ch # Word count + rep # Copy + movsw # code +.... + +.[.filename]#stand/i386/boot2/boot1.S# [[boot-boot1-main]] +Как и [.filename]#boot0#, этот код перемещает [.filename]#boot1#, на этот раз по адресу `0x700`. Однако, в отличие от [.filename]#boot0#, он не переходит туда. [.filename]#boot1# скомпонован для выполнения по адресу `0x7c00`, фактически там, куда он был изначально загружен. Причина этого перемещения будет рассмотрена далее. + +Далее идет цикл, который ищет слайс FreeBSD. Хотя [.filename]#boot0# загрузил [.filename]#boot1# из слайса FreeBSD, ему не была передана информация об этом footnote:[На самом деле мы передали указатель на адрес слайса в регистре %si. Однако boot1 не предполагает, что он был загружен boot0 (возможно, его загрузил другой MBR и не передал эту информацию), поэтому он ничего не предполагает.], поэтому [.filename]#boot1# должен повторно просканировать таблицу разделов, чтобы найти начало слайса FreeBSD. Для этого он перечитывает MBR: + +[.programlisting] +.... + mov $part4,%si # Partition + cmpb $0x80,%dl # Hard drive? + jb main.4 # No + movb $0x1,%dh # Block count + callw nread # Read MBR +.... + +.[.filename]#stand/i386/boot2/boot1.S# [[boot-boot1-find-freebsd]] +В приведённом выше коде регистр `%dl` содержит информацию о загрузочном устройстве. Эти данные передаются BIOS и сохраняются MBR. Числа `0x80` и выше указывают на то, что мы имеем дело с жёстким диском, поэтому вызывается `nread`, где считывается MBR. Аргументы для `nread` передаются через `%si` и `%dh`. Адрес памяти по метке `part4` копируется в `%si`. Этот адрес памяти содержит "фальшивый раздел", который будет использован `nread`. Ниже приведены данные фальшивого раздела: + +[.programlisting] +.... + part4: + .byte 0x80, 0x00, 0x01, 0x00 + .byte 0xa5, 0xfe, 0xff, 0xff + .byte 0x00, 0x00, 0x00, 0x00 + .byte 0x50, 0xc3, 0x00, 0x00 +.... + +.[.filename]#stand/i386/boot2/boot1.S# [[boot-boot2-make-fake-partition]] +В частности, LBA для этой фиктивной раздела жестко закодирован как ноль. Это используется как аргумент для BIOS при чтении абсолютного сектора один с жесткого диска. Альтернативно, может использоваться адресация CHS. В этом случае, фиктивный раздел содержит цилиндр 0, головку 0 и сектор 1, что эквивалентно абсолютному сектору один. + +Продолжим, рассмотрев `nread`: + +[.programlisting] +.... +nread: + mov $MEM_BUF,%bx # Transfer buffer + mov 0x8(%si),%ax # Get + mov 0xa(%si),%cx # LBA + push %cs # Read from + callw xread.1 # disk + jnc return # If success, return +.... + +.[.filename]#stand/i386/boot2/boot1.S# [[boot-boot1-nread]] +Напомним, что `%si` указывает на поддельный раздел. Слово footnote:[В контексте 16-битного реального режима слово — это 2 байта.] по смещению `0x8` копируется в регистр `%ax`, а слово по смещению `0xa` — в `%cx`. BIOS интерпретирует их как младшее 4-байтовое значение, обозначающее LBA для чтения (старшие четыре байта предполагаются нулевыми). Регистр `%bx` содержит адрес памяти, куда будет загружен MBR. Инструкция, помещающая `%cs` в стек, очень интересна. В данном контексте она ничего не делает. Однако, как мы скоро увидим, [.filename]#boot2# в сочетании с сервером BTX также исполь ует `xread.1`. Этот механизм будет рассмотрен в следующем разделе. + +Код в `xread.1` далее вызывает функцию `read`, которая фактически обращается к BIOS с запросом на чтение сектора диска: + +[.programlisting] +.... +xread.1: + pushl $0x0 # absolute + push %cx # block + push %ax # number + push %es # Address of + push %bx # transfer buffer + xor %ax,%ax # Number of + movb %dh,%al # blocks to + push %ax # transfer + push $0x10 # Size of packet + mov %sp,%bp # Packet pointer + callw read # Read from disk + lea 0x10(%bp),%sp # Clear stack + lret # To far caller +.... + +.[.filename]#stand/i386/boot2/boot1.S# [[boot-boot1-xread1]] +Обратите внимание на длинную инструкцию возврата в конце этого блока. Эта инструкция извлекает регистр `%cs`, помещённый в стек `nread`, и возвращает управление. В конце `nread` также возвращает управление. + +С загрузкой MBR в память начинается фактический цикл поиска слайса FreeBSD: + +[.programlisting] +.... + mov $0x1,%cx # Two passes +main.1: + mov $MEM_BUF+PRT_OFF,%si # Partition table + movb $0x1,%dh # Partition +main.2: + cmpb $PRT_BSD,0x4(%si) # Our partition type? + jne main.3 # No + jcxz main.5 # If second pass + testb $0x80,(%si) # Active? + jnz main.5 # Yes +main.3: + add $0x10,%si # Next entry + incb %dh # Partition + cmpb $0x1+PRT_NUM,%dh # In table? + jb main.2 # Yes + dec %cx # Do two + jcxz main.1 # passes +.... + +.[.filename]#stand/i386/boot2/boot1.S# [[boot-boot1-find-part]] +Если обнаружен слайс FreeBSD, выполнение продолжается на метке `main.5`. Обратите внимание, что при обнаружении слайса FreeBSD `%si` указывает на соответствующую запись в таблице разделов, а `%dh` содержит номер раздела. Мы предполагаем, что слайс FreeBSD найден, поэтому продолжаем выполнение на метке `main.5`: + +[.programlisting] +.... +main.5: + mov %dx,MEM_ARG # Save args + movb $NSECT,%dh # Sector count + callw nread # Read disk + mov $MEM_BTX,%bx # BTX + mov 0xa(%bx),%si # Get BTX length and set + add %bx,%si # %si to start of boot2.bin + mov $MEM_USR+SIZ_PAG*2,%di # Client page 2 + mov $MEM_BTX+(NSECT-1)*SIZ_SEC,%cx # Byte + sub %si,%cx # count + rep # Relocate + movsb # client +.... + +.[.filename]#stand/i386/boot2/boot1.S# [[boot-boot1-main5]] +Напомним, что в данный момент регистр `%si` указывает на запись среза FreeBSD в таблице разделов MBR, поэтому вызов `nread` фактически прочитает секторы в начале этого раздела. Аргумент, переданный в регистре `%dh`, указывает `nread` прочитать 16 секторов диска. Напомним, что первые 512 байт, или первый сектор слайса FreeBSD, совпадает с программой [.filename]#boot1#. Также напомним, что файл, записанный в начало слайса FreeBSD, это не [.filename]#/boot/boot1#, а [.filename]#/boot/boot#. Давайте посмотрим на размер этих файлов в файловой системе: + *** 44718 LINES SKIPPED ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202510141949.59EJne8f053209>
