Как ядро Linux может скомпилировать себя?

Это источник, скопированный из JDK 9 java.util.stream.Stream.takeWhile (Predicate). Небольшая разница для работы с JDK 8.

static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<? super T> p) {
    class Taking extends Spliterators.AbstractSpliterator<T> implements Consumer<T> {
        private static final int CANCEL_CHECK_COUNT = 63;
        private final Spliterator<T> s;
        private int count;
        private T t;
        private final AtomicBoolean cancel = new AtomicBoolean();
        private boolean takeOrDrop = true;

        Taking(Spliterator<T> s) {
            super(s.estimateSize(), s.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED));
            this.s = s;
        }

        @Override
        public boolean tryAdvance(Consumer<? super T> action) {
            boolean test = true;
            if (takeOrDrop &&               // If can take
                    (count != 0 || !cancel.get()) && // and if not cancelled
                    s.tryAdvance(this) &&   // and if advanced one element
                    (test = p.test(t))) {   // and test on element passes
                action.accept(t);           // then accept element
                return true;
            } else {
                // Taking is finished
                takeOrDrop = false;
                // Cancel all further traversal and splitting operations
                // only if test of element failed (short-circuited)
                if (!test)
                    cancel.set(true);
                return false;
            }
        }

        @Override
        public Comparator<? super T> getComparator() {
            return s.getComparator();
        }

        @Override
        public void accept(T t) {
            count = (count + 1) & CANCEL_CHECK_COUNT;
            this.t = t;
        }

        @Override
        public Spliterator<T> trySplit() {
            return null;
        }
    }
    return StreamSupport.stream(new Taking(stream.spliterator()), stream.isParallel()).onClose(stream::close);
}
87
задан MainID 30 January 2009 в 03:32
поделиться

5 ответов

Первый раунд двоичных файлов для Вашего поля Linux был основан на некотором другом поле Linux (вероятно).

двоичные файлы для первой системы Linux были основаны приблизительно на на другом платформа.

двоичные файлы для того компьютера могут проследить свой корень до исходной системы, которая была основана все же другой платформа.

...

Нажатие настолько далеко достаточно, и Вы находите компиляторы созданными с более примитивными инструментами, которые были в свою очередь основаны на машинах кроме их хоста.

...

Продолжают продвигать, и Вы находите компьютеры созданными так, чтобы их инструкции могли быть введены [1 111], установка включает переднюю панель машины .

Очень интересный материал.

правило является "сборкой инструменты для создания инструментов для создания инструментов...". Очень как инструменты, которые выполняют нашу физическую среду. Также известный как "тянуть себя начальными загрузками".

207
ответ дан hippietrail 5 November 2019 в 15:17
поделиться

Я думаю, что необходимо различать:

компиляция , v: использовать компилятор, чтобы обработать исходный код и произвести установку исполняемого кода [1] .

и

, v: Для соединения настройте или подготовьте что-то к использованию [2] .

Компиляция производит двоичные исполняемые файлы из исходного кода. Установка просто кладет те двоичные исполняемые файлы на правильное место для выполнения их позже. Так, установка и использование не требуют компиляции, если двоичные файлы доступны. Думайте о ”compile” и “install” как приблизительно “cook” и “serve”, соответственно.

Теперь, Ваши вопросы:

  1. ядро записано в C, однако как ядро становилось скомпилированным без установленного компилятора?

ядро не может быть скомпилировано без компилятора, но это может быть , установил от скомпилированного двоичного файла.

Обычно при установке операционной системы Вы устанавливаете предварительно скомпилированное ядро (двоичный исполняемый файл). Это было скомпилировано кем-то еще. И только если Вы хотите скомпилировать ядро сами, Вам нужны источник и компилятор и все другие инструменты.

Даже в ”source-based” дистрибутивах как хинду Вы запускаете с выполнения скомпилированного двоичного файла.

Так, можно жить всей жизнью, не компилируя ядра, потому что Вам скомпилировал их кто-то еще.

  1. , Если компилятор C установлен на моей машине, прежде чем ядро компилируется, как может сам компилятор компилироваться без установленного компилятора?

компилятор не может быть запущен, если нет никакого ядра (ОС). Таким образом, нужно установить , скомпилировал ядро для выполнения компилятора, но не нуждается для компиляции ядро сам.

Снова, наиболее распространенная практика должна установить скомпилированные двоичные файлы компилятора и использовать их для компиляции чего-либо еще (включая сам компилятор и ядро).

Теперь, курица и проблема яйца. Первый двоичный файл компилируется кем-то еще... См. превосходный ответ dmckee.

33
ответ дан sastanin 5 November 2019 в 15:17
поделиться

Термин, описывающий это явление, начальная загрузка , это - интересное понятие для чтения на. Если Вы думаете о встроенной разработке, становится ясно, что много устройств, скажем будильники, микроволны, дистанционные управления, которые требуют программного обеспечения, не достаточно способно скомпилировать их собственное программное обеспечение. На самом деле эти виды устройств обычно не имеют достаточного количества ресурсов для выполнения чего-либо удаленно столь же сложного как компилятор.

Их программное обеспечение разрабатывается на настольной машине и затем копируется, после того как оно было скомпилировано.

, Если этот вид вещи интересует Вас, статья, которая приходит на ум первое, что пришло на ум: Отражения о Доверии Доверию ( pdf), это - классик и забавное чтение.

14
ответ дан a2800276 5 November 2019 в 15:17
поделиться

Ядро не компилирует себя - оно компилируется компилятором C в пространстве пользователя. В большинстве архитектур ЦП ЦП имеет многие биты в специальных регистрах, которые представляют, какие полномочия код, в настоящее время работающий, имеет. В x86 это текущие биты уровня полномочий (CPL) в сегмент кода (CS) регистр. Если биты CPL 00, код, как говорят, работает в , безопасность звонит 0 , также известный как привилегированный режим . Если биты CPL равняются 11, код, как говорят, работает в , безопасность звонит 3 , также известный как непривилегированный режим . Другие две комбинации, 01 и 10 (безопасность звонит 1 и 2 соответственно) редко используются.

правила о том, какой код может и не может сделать в непривилегированном режиме по сравнению с привилегированным режимом, являются скорее сложными, но являются достаточными для высказывания, непривилегированный режим сильно уменьшил полномочия.

Теперь, когда люди говорят о ядре операционной системы, они обращаются к частям кода ОС, которые добираются для выполнения в привилегированном режиме с поднятыми полномочиями. Обычно авторы ядра пытаются сохранить ядро как можно меньше из соображений безопасности, так, чтобы код, для которого не нужны дополнительные полномочия, не имел их.

компилятор C является одним примером такой программы - этому не нужны дополнительные полномочия, предлагаемые привилегированным режимом, таким образом, это работает в непривилегированном режиме, как большинство других программ.

В случае Linux, ядро состоит из двух частей: исходный код ядра и скомпилированный исполняемый файл ядра. Любая машина с компилятором C может скомпилировать ядро от исходного кода в двухуровневое изображение. Вопрос, затем, состоит в том, что сделать с тем двухуровневым изображением.

при установке Linux в новой системе Вы устанавливаете предварительно скомпилированное двухуровневое изображение, обычно от любого физические среды (такие как DVD CD) или из сети. BIOS загрузится (двухуровневое изображение) загрузчик ядра от медиа или сети, и затем загрузчик установит (двухуровневое изображение) ядро на Ваш жесткий диск. Затем когда Вы перезагружаете, BIOS загружает загрузчик ядра из Вашего жесткого диска, и загрузчик загружает ядро в память, и Вы являетесь выключенными и рабочими.

, Если Вы хотите к , перекомпилировали Ваше собственное ядро, это немного более хитро, но оно может быть сделано.

11
ответ дан Adam Rosenfield 5 November 2019 в 15:17
поделиться

Какой был там первым? курица или яйцо?

Яйца были вокруг со времени динозавров..

.. некоторые путают все путем высказывания, что цыплята являются на самом деле потомками великих зверей.. длинная короткая история: технология (Яйцо) была существующей до Текущего продукта (Курица)

, Вам нужно ядро для создания ядра, т.е. Вы создаете один с другим.

первое ядро может быть чем-либо, что Вы хотите (предпочтительно что-то разумное, это может создать Ваш желаемый конечный продукт ^ __^)

, Это учебное руководство от Разработки Ядра Отрубей учит Вас разрабатывать и создавать небольшое ядро, которое можно затем протестировать с Виртуальной машиной по Вашему выбору.

Значение: Вы пишете и компилируете ядро где-нибудь и читаете его на пустом (никакая ОС) виртуальная машина.

то, Что происходит с теми установками Linux, следует за той же идеей с добавленной сложностью.

5
ответ дан Ric Tokyo 5 November 2019 в 15:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: