Как настроить смартфоны и ПК. Информационный портал
  • Главная
  • Новости
  • Создание ядра операционной системы. UNIX-подобная операционная система: пишем ядро на языке C

Создание ядра операционной системы. UNIX-подобная операционная система: пишем ядро на языке C

Семантическое ядро — это страшное название, которое придумали SEOшники для обозначения довольно простой вещи. Нам надо просто подобрать ключевые запросы, по которым мы будем продвигать наш сайт.

И в этой статье я покажу вам, как правильно составить семантическое ядро, чтобы ваш сайт побыстрее вышел в ТОП, а не топтался месяцами на месте. Тут тоже есть свои «секретики».

И прежде чем мы перейдем к составлению СЯ, давайте разберем, что это такое, и к чему мы в итоге должны прийти.

Что такое семантическое ядро простыми словами

Как это ни странно, но семантическое ядро — это обычный excel файл, в котором списком представлены ключевые запросы, по которым вы (или ваш копирайтер) будете писать статьи для сайта.

Вот как, например, выглядит мое семантическое ядро:

Зеленым цветом у меня помечены те ключевые запросы, по которым я уже написал статьи. Желтым — те, которым статьи собираюсь написать в ближайшее время. А бесцветные ячейки — это значит, что до этих запросов дело дойдет немного позже.

Для каждого ключевого запроса у меня определена частотность, конкурентность, и придуман «цепляющий» заголовок. Вот примерно такой же файл должен получиться и у вас. Сейчас у меня СЯ состоит из 150 ключевиков. Это значит, что я обеспечен «материалом» минимум на 5 месяцев вперед (если даже буду писать по одной статье в день).

Чуть ниже мы поговорим о том, к чему вам готовиться, если вы вдруг решите заказать сбор семантического ядра у специалистов. Здесь скажу кратко — вам дадут такой же список, но только на тысячи «ключей». Однако, в СЯ важно не количество, а качество. И мы с вами будем ориентироваться именно на это.

Зачем вообще нужно семантическое ядро?

А в самом деле, зачем нам эти мучения? Можно же, в конце концов, просто так писать качественные статьи, и привлекать этим аудиторию, правильно? Да, писать можно, а вот привлекать не получится.

Главная ошибка 90% блогеров — это как раз написание просто качественных статей. Я не шучу, у них реально интересные и полезные материалы. Вот только поисковые системы об этом не знают. Они же не экстрасенсы, а всего лишь роботы. Соответственно они и не ставят вашу статью в ТОП.

Здесь есть еще один тонкий момент с заголовком. Например, у вас есть очень качественная статья на тему «Как правильно вести бизнес в «мордокниге». Там вы очень подробно и профессионально расписываете все про фейсбук. В том числе и то, как там продвигать сообщества. Ваша статья — самая качественная, полезная и интересная в интернете на эту тему. Никто и рядом с вами не валялся. Но вам это все равно не поможет.

Почему качественные статьи вылетают из ТОПа

Представьте, что на ваш сайт зашел не робот, а живой проверяльщик (асессор) с Яндекса. Он понял, что у вас самая классная статья. И рукам поставил вас на первое место в выдаче по запросу «Продвижение сообщества в фейсбук».

Знаете, что произойдет дальше? Вы оттуда все равно очень скоро вылетите. Потому что по вашей статье, даже на первом месте, никто не будет кликать. Люди вводят запрос «Продвижение сообщества в фейсбук», а у вас заголовок — «Как правильно вести бизнес в «мордокниге». Оригинально, свежо, забавно, но… не под запрос. Люди хотят видеть именно то, что они искали, а не ваш креатив.

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

Зато у этих статей будет правильный «релевантный» заголовок — «Продвижение сообщества в фейсбук с нуля» (по шагам, за 5 шагов, от А до Я, бесплатно и пр.) Обидно? Еще бы. Ну так боритесь против несправедливости. Давайте составим грамотное семантическое ядро, чтобы ваши статьи занимали заслуженные первые места.

Еще одна причина начать составлять СЯ прямо сейчас

Есть еще одна вещь, о которой почему-то люди мало задумываются. Вам надо писать статьи часто — как минимум каждую неделю, а лучше 2-3 раза в неделю, чтобы набрать побольше трафика и побыстрее.

Все это знают, но почти никто этого не делает. А все потому, что у них «творческий застой», «никак не могут себя заставить», «просто лень». А на самом деле вся проблема именно в отсутствие конкретного семантического ядра.

Я ввел в поле поиска один из своих базовых ключей — «smm», и Яндекс тут же выдал мне с десяток подсказок, что еще может быть интересно людям, которым интересно «smm». Мне остается только скопировать эти ключи в блокнотик. Потом я точно так же проверю каждый из них, и соберу подсказки еще и по ним.

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

Шаг #2 — Парсинг базовых ключей в SlovoEB

Конечно, если вы напишите статью под запрос «вебинар» или «smm», то чуда не произойдет. Вы никогда не сможете выйти в ТОП по такому широкому запросу. Нам надо разбить базовый ключ на множество мелких запросов по этой теме. И делать это мы будем с помощью специальной программы.

Я использую KeyCollector, но он платный. Вы можете воспользоваться бесплатным аналогом — программой SlovoEB. Скачать её вы можете с официального сайта.

Самое сложное в работе с этой программой — это её правильно настроить. Как правильно настроить и использовать Словоеб я показываю . Но в той статье я упор делаю на подбор ключей для Яндекс-Директа.

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

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

Я обычно даю такое же название проекту, как и мой базовый ключ, чтобы потом не запутаться. И да, предупрежу вас еще от одной ошибки. Не пытайтесь парсить все базовые ключи одновременно. Вам потом будет очень сложно отфильтровать «пустые» ключевые запросы от золотых крупиц. Давайте парсить по одному ключу.

После создания проекта — проводим базовую операцию. То есть мы собственно парсим ключ через Яндекс Вордстат. Для этого нажмите на кнопку «Ворстат» в интерфейсе программы, впишите ваш базовый ключ, и нажмите «Начать сбор».

Для примера, давайте распарсим базовый ключ для моего блога «контекстная реклама».

После этого запустится процесс, и через некоторое время программа нам выдаст результат — до 2000 ключевых запросов, в которых содержится «контекстная реклама».

Так же рядом с каждым запросом будет стоять «грязная» частотность — сколько раз этот ключ (+ его словоформы и хвосты) искали в месяц через яндекс. Но не советую делать никаких выводов из этих цифр.

Шаг #3 — Сбор точной частотности для ключей

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

Нам надо выявить чистую частотность. И для этого мы сначала выделяем все найденные ключи галочками, а потом нажимаем на кнопочку «Яндекс Директ» и снова запускаем процесс. Теперь Словоеб будет нам искать точную частоту запроса в месяц для каждого ключа.

Теперь у нас есть объективная картина — сколько раз какой запрос вводили пользователи интернета за последний месяц. Предлагаю теперь сгруппировать все ключевые запросы по частотности, чтобы с ними было удобнее работать.

Для этого нажимаем на значок «фильтр» в столбце «Частота «!» », и указываем — отфильтровать ключи со значением «меньше или равно 10».

Теперь программа покажет вам только те запросы, частотность которых меньше или равна значению «10». Эти запросы вы можете удалить или скопировать на будущее в другую группу ключевых запросов. Меньше 10 — это очень мало. Писать статьи под эти запросы — пустая трата времени.

Сейчас нам надо выбрать те ключевые запросы, которые принесут нам более или менее хороший трафик. И для этого нам надо выяснить еще один параметр — уровень конкурентности запроса.

Шаг #4 — Проверка конкурентности запросов

Все «ключи» в этом мире делятся на 3 типа: высокочастотные (ВЧ), среднечастотные (СЧ), низкочастотные (НЧ). А еще они могут быть выосококонкурнетными (ВК), среднеконкурентными (СК) и низкоконкурентными (НК).

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

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

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

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

Здесь я проверил запрос «настройка контекстной рекламы в google adwords». Мутаген показал нам, что у этого ключа конкурентность «более 25» — это максимальное значение, которое он показывает. А просмотров у этого запроса всего 11 в месяц. Значит нам он точно не подходит.

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

Мутаген — это платный сервис. Но 10 проверок в сутки вы можете сделать бесплатно. Кроме того, стоимость проверки очень низкая. За все время работы с ним я еще не истратил и 300 рублей.

Кстати, на счет уровня конкуренции. Если у вас молодой сайт, то лучше выбирать запросы с уровнем конкуренции 3-5. А если вы раскручиваетесь уже более года, то можно брать и 10-15.

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

Шаг #5 — Сбор «хвостов» для выбранных ключей

Как уже много раз было доказано и проверено, основной объем трафика ваш сайт будет получать не от основных ключей, а от так называемых «хвостов». Это когда человек вводит в поисковую строку странные ключевые запросы, с частотностью 1-2 в месяц, но таких запросов очень много.

Чтобы увидеть «хвост» — просто зайдите в Яндекс и введите выбранный вами ключевой запрос в строку поиска. Вот что вы примерно увидите.

Теперь вам надо просто выписать эти дополнительные слова в отдельный документ, и использовать их в своей статье. При чем не надо ставить их всегда рядом с основным ключом. Иначе поисковые системы увидят «переоптимизацию» и ваши статьи упадут в выдаче.

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

Например, у нас есть запрос — «Настройка контекстной рекламы». Вот как можно его переформулировать:

  • Настройка = настроить, сделать, создать, запустить, запуск, включить, разместить…
  • Контекстная реклама = контекст, директ, тизер, РСЯ, адвордс, кмс. direct, adwords…

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

Вот так, мы собираем список из 100 — 150 ключевых запросов. Если вы составляете семантическое ядро впервые, то у вас может уйти на это несколько недель.

А может ну его, глаза ломать? Может есть возможность делегировать составления СЯ специалистам, которые сделают это лучше и быстрее? Да, такие специалисты есть, но пользоваться их услугами нужно не всегда.

Стоит ли заказывать СЯ у специалистов?

По большому счету специалисты по составлению семантического ядра сделают вам только шаги 1 — 3 из нашей схемы. Иногда, за большую дополнительную плату, сделают и шаги 4-5 — (сбор хвостов и проверку конкурентности запросов).

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

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

И вот тут встает вопрос — а зачем тогда собственно нужны специалисты по СЯ? Согласитесь, распарсить базовый ключ и собрать точные частотности (шаги #1-3) — это совсем не сложно. У вас уйдет на это буквально полчаса времени.

Самое сложное — это именно выбрать ВЧ запросы, у которых низкая конкуренция. А теперь еще, как выясняется, надо ВЧ-НК, на которые вы можете написать хорошую статью. Вот именно это займет у вас 99% времени работы над семантическим ядром. И этого вам не сделает ни один специалист. Ну и стОит ли тратиться на заказ таких услуг?

Когда услуги специалистов по СЯ полезны

Другое дело, если вы изначально планируете привлекать копирайтеров. Тогда вам необязательно разбираться в теме запроса. Копирайтеры ваши тоже не будут в ней разбираться. Они просто возьмут несколько статей по этой теме, и скомпилируют из них «свой» текст.

Такие статьи будут пустыми, убогими, почти бесполезными. Но их будет много. Самостоятельно вы сможете писать максимум 2-3 качественные статьи в неделю. А армия копирайтеров обеспечит вам 2-3 говнотекста в день. При этом они будут оптимизированы под запросы, а значит будут привлекать какой-то трафик.

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

Резюме

Давайте еще раз пробежимся по основным мыслям в статье для закрепления информации.

  • Семантическое ядро — это просто список ключевых запросов, под которые вы будете писать статьи на сайт для продвижения.
  • Необходимо оптимизировать тексты под точные ключевые запросы, иначе ваши даже самые качественные статьи никогда не выйдут в ТОП.
  • СЯ — это как контент-план для социальных сетей. Он помогает вам не впадать в «творческий кризис», и всегда точно знать, о чем вы будете писать завтра, послезавтра и через месяц.
  • Для составления семантического ядра удобно использовать бесплатную программу Словоеб, надо только её .
  • Вот пять шагов составления СЯ: 1 — Подбор базовых ключей; 2 — Парсинг базовых ключей; 3 — Сбор точной частотности для запросов; 4 — Проверка конкурентости ключей; 5 — Сбор «хвостов».
  • Если вы хотите сами писать статьи, то лучше сделайте семантическое ядро самостоятельно, под себя. Специалисты по составлению СЯ не смогут здесь вам помочь.
  • Если вы хотите работать на количество и использовать копирайтеров для написания статей, то вполне можно привлечь делегировать и составления семантического ядра. Лишь бы на все хватило денег.

Надеюсь, эта инструкция была вам полезна. Сохраняйте её в избранное, чтобы не потерять, и поделитесь с друзьями. Не забудьте скачать мою книгу . Там я показываю вам самый быстрый путь с нуля до первого миллиона в интернете (выжимка из личного опыта за 10 лет =)

До скорого!

Ваш Дмитрий Новосёлов

Давайте напишем простое ядро, которое можно загрузить при помощи бутлоадера GRUB x86-системы. Это ядро будет отображать сообщение на экране и ждать.

Как загружается x86-система?

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

В большей части регистров процессора при запуске уже находятся определённые значения. Регистр, указывающий на адрес инструкций (Instruction Pointer, EIP), хранит в себе адрес памяти, по которому лежит исполняемая процессором инструкция. EIP по умолчанию равен 0xFFFFFFF0 . Таким образом, x86-процессоры на аппаратном уровне начинают работу с адреса 0xFFFFFFF0. На самом деле это - последние 16 байт 32-битного адресного пространства. Этот адрес называется вектором перезагрузки (reset vector).

Теперь карта памяти чипсета гарантирует, что 0xFFFFFFF0 принадлежит определённой части BIOS, не RAM. В это время BIOS копирует себя в RAM для более быстрого доступа. Адрес 0xFFFFFFF0 будет содержать лишь инструкцию перехода на адрес в памяти, где хранится копия BIOS.

Так начинается исполнение кода BIOS. Сперва BIOS ищет устройство, с которого можно загрузиться, в предустановленном порядке. Ищется магическое число, определяющее, является ли устройство загрузочным (511-ый и 512-ый байты первого сектора должны равняться 0xAA55 ).

Когда BIOS находит загрузочное устройство, она копирует содержимое первого сектора устройства в RAM, начиная с физического адреса 0x7c00 ; затем переходит на адрес и исполняет загруженный код. Этот код называется бутлоадером .

Бутлоадер загружает ядро по физическому адресу 0x100000 . Этот адрес используется как стартовый во всех больших ядрах на x86-системах.

Все x86-процессоры начинают работу в простом 16-битном режиме, называющимся реальным режимом . Бутлоадер GRUB переключает режим в 32-битный защищённый режим , устанавливая нижний бит регистра CR0 в 1 . Таким образом, ядро загружается в 32-битном защищённом режиме.

Заметьте, что в случае с ядром Linux GRUB видит протоколы загрузки Linux и загружает ядро в реальном режиме. Ядро самостоятельно переключается в защищённый режим.

Что нам нужно?

  • x86-компьютер;
  • Linux;
  • ld (GNU Linker);

Задаём точку входа на ассемблере

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

Как же нам сделать так, чтобы этот код обязательно был именно исходной точкой?

Мы будем использовать скрипт-линковщик, который соединяет объектные файлы для создания конечного исполняемого файла. В этом скрипте мы явно укажем, что хотим загрузить данные по адресу 0x100000.

Вот код на ассемблере:

;;kernel.asm bits 32 ;nasm directive - 32 bit section .text global start extern kmain ;kmain is defined in the c file start: cli ;block interrupts mov esp, stack_space ;set stack pointer call kmain hlt ;halt the CPU section .bss resb 8192 ;8KB for stack stack_space:

Первая инструкция, bits 32 , не является x86-ассемблерной инструкцией. Это директива ассемблеру NASM, задающая генерацию кода для процессора, работающего в 32-битном режиме. В нашем случае это не обязательно, но вообще полезно.

Со второй строки начинается секция с кодом.

global - это ещё одна директива NASM, делающая символы исходного кода глобальными. Таким образом, линковщик знает, где находится символ start - наша точка входа.

kmain - это функция, которая будет определена в файле kernel.c . extern значит, что функция объявлена где-то в другом месте.

Затем идёт функция start , вызывающая функцию kmain и останавливающая процессор инструкцией hlt . Именно поэтому мы заранее отключаем прерывания инструкцией cli .

В идеале нам нужно выделить немного памяти и указать на неё указателем стека (esp). Однако, похоже, что GRUB уже сделал это за нас. Тем не менее, вы всё равно выделим немного места в секции BSS и переместим на её начало указатель стека. Мы используем инструкцию resb , которая резервирует указанное число байт. Сразу перед вызовом kmain указатель стека (esp) устанавливается на нужное место инструкцией mov .

Ядро на Си

В kernel.asm мы совершили вызов функции kmain() . Таким образом, наш «сишный» код должен начать исполнение с kmain() :

/* * kernel.c */ void kmain(void) { const char *str = "my first kernel"; char *vidptr = (char*)0xb8000; //video mem begins here. unsigned int i = 0; unsigned int j = 0; /* this loops clears the screen * there are 25 lines each of 80 columns; each element takes 2 bytes */ while(j < 80 * 25 * 2) { /* blank character */ vidptr[j] = " "; /* attribute-byte - light grey on black screen */ vidptr = 0x07; j = j + 2; } j = 0; /* this loop writes the string to video memory */ while(str[j] != "\0") { /* the character"s ascii */ vidptr[i] = str[j]; /* attribute-byte: give character black bg and light grey fg */ vidptr = 0x07; ++j; i = i + 2; } return; }

Всё, что сделает наше ядро - очистит экран и выведет строку «my first kernel».

Сперва мы создаём указатель vidptr , который указывает на адрес 0xb8000 . С этого адреса в защищённом режиме начинается «видеопамять». Для вывода текста на экран мы резервируем 25 строк по 80 ASCII-символов, начиная с 0xb8000.

Каждый символ отображается не привычными 8 битами, а 16. В первом байте хранится сам символ, а во втором - attribute-byte . Он описывает форматирование символа, например, его цвет.

Для вывода символа s зелёного цвета на чёрном фоне мы запишем этот символ в первый байт и значение 0x02 во второй. 0 означает чёрный фон, 2 - зелёный цвет текста.

Вот таблица цветов:

0 - Black, 1 - Blue, 2 - Green, 3 - Cyan, 4 - Red, 5 - Magenta, 6 - Brown, 7 - Light Grey, 8 - Dark Grey, 9 - Light Blue, 10/a - Light Green, 11/b - Light Cyan, 12/c - Light Red, 13/d - Light Magenta, 14/e - Light Brown, 15/f – White.

В нашем ядре мы будем использовать светло-серый текст на чёрном фоне, поэтому наш байт-атрибут будет иметь значение 0x07.

В первом цикле программа выводит пустой символ по всей зоне 80×25. Это очистит экран. В следующем цикле в «видеопамять» записываются символы из нуль-терминированной строки «my first kernel» с байтом-атрибутом, равным 0x07. Это выведет строку на экран.

Связующая часть

Мы должны собрать kernel.asm в объектный файл, используя NASM; затем при помощи GCC скомпилировать kernel.c в ещё один объектный файл. Затем их нужно присоединить к исполняемому загрузочному ядру.

Для этого мы будем использовать связывающий скрипт, который передаётся ld в качестве аргумента.

/* * link.ld */ OUTPUT_FORMAT(elf32-i386) ENTRY(start) SECTIONS { . = 0x100000; .text: { *(.text) } .data: { *(.data) } .bss: { *(.bss) } }

Сперва мы зададим формат вывода как 32-битный Executable and Linkable Format (ELF). ELF - это стандарный формат бинарных файлов Unix-систем архитектуры x86. ENTRY принимает один аргумент, определяющий имя символа, являющегося точкой входа. SECTIONS - это самая важная часть. В ней определяется разметка нашего исполняемого файла. Мы определяем, как должны соединяться разные секции и где их разместить.

В скобках после SECTIONS точка (.) отображает счётчик положения, по умолчанию равный 0x0. Его можно изменить, что мы и делаем.

Смотрим на следующую строку: .text: { *(.text) } . Звёздочка (*) - это специальный символ, совпадающий с любым именем файла. Выражение *(.text) означает все секции.text из всех входных файлов.

Таким образом, линковщик соединяет все секции кода объектных файлов в одну секцию исполняемого файла по адресу в счётчике положения (0x100000). После этого значение счётчика станет равным 0x100000 + размер полученной секции.

Аналогично всё происходит и с другим секциями.

Grub и Multiboot

Теперь все файлы готовы к созданию ядра. Но остался ещё один шаг.

Существует стандарт загрузки x86-ядер с использованием бутлоадера, называющийся Multiboot specification . GRUB загрузит наше ядро, только если оно удовлетворяет этим спецификациям .

Следуя им, ядро должно содержать заголовок в своих первых 8 килобайтах. Кроме того, этот заголовок должен содержать 3 поля, являющихся 4 байтами:

  • магическое поле: содержит магическое число 0x1BADB002 для идентификации ядра.
  • поле flags : нам оно не нужно, установим в ноль.
  • поле checksum : если сложить его с предыдущими двумя, должен получиться ноль.

Наш kernel.asm станет таким:

;;kernel.asm ;nasm directive - 32 bit bits 32 section .text ;multiboot spec align 4 dd 0x1BADB002 ;magic dd 0x00 ;flags dd - (0x1BADB002 + 0x00) ;checksum. m+f+c should be zero global start extern kmain ;kmain is defined in the c file start: cli ;block interrupts mov esp, stack_space ;set stack pointer call kmain hlt ;halt the CPU section .bss resb 8192 ;8KB for stack stack_space:

Строим ядро

Теперь мы создадим объектные файлы из kernel.asm и kernel.c и свяжем их, используя наш скрипт.

Nasm -f elf32 kernel.asm -o kasm.o

Эта строка запустит ассемблер для создания объектного файла kasm.o в формате ELF-32.

Gcc -m32 -c kernel.c -o kc.o

Опция «-c» гарантирует, что после компиляции не произойдёт скрытого линкования.

Ld -m elf_i386 -T link.ld -o kernel kasm.o kc.o

Это запустит линковщик с нашим скриптом и создаст исполняемый файл, называющийся kernel .

Настраиваем grub и запускаем ядро

GRUB требует, чтобы имя ядра удовлетворяло шаблону kernel- . Поэтому переименуйте ядро. Своё я назвал kernel-701.

Теперь поместите его в директорию /boot . Для этого понадобятся права суперпользователя.

В конфигурационном файле GRUB grub.cfg добавьте следующее:

Title myKernel root (hd0,0) kernel /boot/kernel-701 ro

Не забудьте убрать директиву hiddenmenu , если она есть.

Перезагрузите компьютер, и вы увидите список ядер с вашим в том числе. Выберите его, и вы увидите:

UNIX-подобная операционная система интересна для разбора, а также для написания собственного ядра, которое выведет сообщение. Ну что, напишем?

UNIX-подобная операционная система и загрузка x86 машины

Что такое UNIX-подобная операционка? Это ОС, созданная под влиянием UNIX. Но прежде чем заняться написанием ядра для нее, давайте посмотрим, как машина загружается и передает управление ядру.

Большинство регистров x86 процессора имеют четко определенные значения после включения питания. Регистр указателя инструкций (EIP) содержит адрес памяти для команды, выполняемой процессором. EIP жестко закодирован на значение 0xFFFFFFF0. Таким образом, у процессора есть четкие инструкции по физическому адресу 0xFFFFFFF0, что, по сути, – последние 16 байт 32-разрядного адресного пространства. Этот адрес называется вектором сброса.

Теперь карта памяти чипсета гарантирует, что 0xFFFFFFF0 сопоставляется с определенной частью BIOS, а не с ОЗУ. Между тем, BIOS копирует себя в ОЗУ для более быстрого доступа. Это называется затенением (shadowing). Адрес 0xFFFFFFF0 будет содержать только инструкцию перехода к адресу в памяти, где BIOS скопировал себя.

Таким образом, код BIOS начинает свое выполнение. Сначала BIOS ищет загрузочное устройство в соответствии с настроенным порядком загрузочных устройств. Он ищет определенное магическое число, чтобы определить, является устройство загрузочным или нет (байты 511 и 512 первого сектора равны 0xAA55).

После того, как BIOS обнаружил загрузочное устройство, он копирует содержимое первого сектора устройства в оперативную память, начиная с физического адреса 0x7c00; затем переходит по адресу и выполняет только что загруженный код. Этот код называется системным загрузчиком (bootloader).

Затем bootloader загружает ядро ​​по физическому адресу 0x100000. Адрес 0x100000 используется как стартовый адрес для всех больших ядер на x86 машинах.

Все x86 процессоры стартуют в упрощенном 16-битном режиме, называемом режимом реальных адресов. Загрузчик GRUB переключается в 32-битный защищенный режим, устанавливая младший бит регистра CR0 равным 1. Таким образом, ядро ​​загружается в 32-разрядный защищенный режим.

Обратите внимание, что в случае обнаружения ядра Linux, GRUB получит протокол загрузки и загрузит ​​Linux-ядро в реальном режиме. А ядро Linux сделает переключение в защищенный режим.

Что нам понадобится?

  • x86 компьютер (разумеется)
  • Ассемблер NASM
  • ld (GNU Linker)
  • Исходный код

Ну и неплохо было бы иметь представление о том, как работает UNIX-подобная ОС. Исходный код можно найти в репозитории на Github.

Точка входа и запуск ядра

Для начала напишем небольшой файл в x86 ассемблере, который будет отправной точкой для запуска ядра. Этот файл будет вызывать внешнюю функцию на C, а затем остановит поток программы.

Как убедиться, что этот код послужит отправной точкой для ядра?

Мы будем использовать скрипт компоновщика, который связывает объектные файлы с целью создания окончательного исполняемого файла ядра. В этом скрипте явно укажем, что бинарный файл должен быть загружен по адресу 0x100000. Этот адрес, является тем местом, где должно быть ядро.

Вот код сборки:

;;kernel.asm bits 32 ;директива nasm - 32 bit section .text global start extern kmain ;kmain определена в C-файле start: cli ;блокировка прерываний mov esp, stack_space ;установка указателя стека call kmain hlt ;остановка процессора section .bss resb 8192 ;8KB на стек stack_space:

Первая инструкция bits 32 не является инструкцией сборки x86. Это директива для ассемблера NASM, которая указывает, что он должен генерировать код для работы на процессоре, работающем в 32-битном режиме. Это не обязательно требуется в нашем примере, однако это хорошая практика – указывать такие вещи явно.

Вторая строка начинается с текстового раздела. Здесь мы разместим весь наш код.

global — еще одна директива NASM, служит для установки символов исходного кода как глобальных.

kmain — это собственная функция, которая будет определена в нашем файле kernel.c. extern объявляет, что функция определена ​​в другом месте.

Функция start вызывает функцию kmain и останавливает CPU с помощью команды hlt. Прерывания могут пробудить CPU из выполнения инструкции hlt. Поэтому мы предварительно отключаем прерывания, используя инструкцию cli.

В идеале необходимо выделить некоторый объем памяти для стека и указать на нее с помощью указателя стека (esp). Однако, GRUB делает это за нас, и указатель стека уже установлен. Тем не менее, для верности, мы выделим некоторое пространство в разделе BSS и поместим указатель стека в начало выделенной памяти. Для этого используем команду resb, которая резервирует память в байтах. После этого остается метка, которая указывает на край зарезервированного фрагмента памяти. Перед вызовом kmain указатель стека (esp) используется для указания этого пространства с помощью команды mov.

Ядро на C

В kernel.asm мы сделали вызов функции kmain(). Таким образом, код на C начнет выполнятся в kmain():

/* * kernel.c */ void kmain(void) { const char *str = "my first kernel"; char *vidptr = (char*)0xb8000; //видео пямять начинается здесь unsigned int i = 0; unsigned int j = 0; /* этот цикл очищает экран*/ while(j < 80 * 25 * 2) { /* пустой символ */ vidptr[j] = " "; /* байт атрибутов */ vidptr = 0x07; j = j + 2; } j = 0; /* в этом цикле строка записывается в видео память */ while(str[j] != "\0") { /* ascii отображение */ vidptr[i] = str[j]; vidptr = 0x07; ++j; i = i + 2; } return; }

* kernel.c

void kmain (void )

const char * str = "my first kernel" ;

unsigned int i = 0 ;

unsigned int j = 0 ;

/* этот цикл очищает экран*/

while (j < 80 * 25 * 2 ) {

/* пустой символ */

vidptr [ j ] = " " ;

/* байт атрибутов */

vidptr [ j + 1 ] = 0x07 ;

j = j + 2 ;

j = 0 ;

/* в этом цикле строка записывается в видео память */

while (str [ j ] != "\0" ) {

/* ascii отображение */

vidptr [ i ] = str [ j ] ;

vidptr [ i + 1 ] = 0x07 ;

i = i + 2 ;

return ;

Наше ядро ​​будет очищать экран и выводить на него строку «my first kernel».

Для начала мы создаем указатель vidptr, который указывает на адрес 0xb8000. Этот адрес является началом видеопамяти в защищенном режиме. Текстовая память экрана – это просто кусок памяти в нашем адресном пространстве. Ввод/вывод для экрана на карте памяти начинается с 0xb8000 и поддерживает 25 строк по 80 ascii символов каждая.

Каждый элемент символа в этой текстовой памяти представлен 16 битами (2 байта), а не 8 битами (1 байт), к которым мы привыкли. Первый байт должен иметь представление символа, как в ASCII. Второй байт является атрибутным байтом. Он описывает форматирование символа, включая разные атрибуты, например цвет.

Чтобы напечатать символ с зеленым цветом на черном фоне, мы сохраним символ s в первом байте адреса видеопамяти и значение 0x02 во втором байте.

0 — черный фон, а 2 — зеленый.

Ниже приведена таблица кодов для разных цветов:

0 - Black, 1 - Blue, 2 - Green, 3 - Cyan, 4 - Red, 5 - Magenta, 6 - Brown, 7 - Light Grey, 8 - Dark Grey, 9 - Light Blue, 10/a - Light Green, 11/b - Light Cyan, 12/c - Light Red, 13/d - Light Magenta, 14/e - Light Brown, 15/f – White.

0 - Black , 1 - Blue , 2 - Green , 3 - Cyan , 4 - Red , 5 - Magenta , 6 - Brown , 7 - Light Grey , 8 - Dark Grey , 9 - Light Blue , 10 / a - Light Green , 11 / b - Light Cyan , 12 / c - Light Red , 13 / d - Light Magenta , 14 / e - Light Brown , 15 / f –White .

В нашем ядре мы будем использовать светло-серые символы на черном фоне. Поэтому наш байт атрибутов должен иметь значение 0x07.

В первом цикле while программа записывает пустой символ с атрибутом 0x07 по всем 80 столбцам из 25 строк. Таким образом, экран очищается.

Во втором цикле while символы строки «my first kernel» записываются в кусок видеопамяти. Для каждого символа атрибутный байт содержит значение 0x07.

Таким образом, строка отобразится на экране.

Связующая часть

Мы собираем kernel.asm и NASM в объектный файл, а затем с помощью GCC компилируем kernel.c в другой объектный файл. Теперь наша задача – связать эти объекты с исполняемым загрузочным ядром.

Для этого мы используем явный скрипт компоновщика, который можно передать как аргумент ld (наш компоновщик).

/* * link.ld */ OUTPUT_FORMAT(elf32-i386) ENTRY(start) SECTIONS { . = 0x100000; .text: { *(.text) } .data: { *(.data) } .bss: { *(.bss) } }

* link.ld

OUTPUT_FORMAT (elf32 - i386 )

ENTRY (start )

SECTIONS

0x100000 ;

Text : { * (. text ) }

Data : { * (. data ) }

Bss : { * (. bss ) }

Во-первых, мы устанавливаем выходной формат исполняемого файла как 32-битный исполняемый (ELF). ELF – стандартный формат двоичного файла для Unix-подобных систем на архитектуре x86.

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

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

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

Счетчик местоположения всегда инициализируется до 0x0 в начале блока SECTIONS. Его можно изменить, присвоив ему новое значение.

Как уже говорилось, код ядра должен начинаться с адреса 0x100000. Таким образом, мы установили счетчик местоположения в 0x100000.

Посмотрите на следующую строку .text: {*(.text)}

Звездочка (*) является спецсимволом, который будет соответствовать любому имени файла. То есть, выражение *(.text) означает все секции ввода.text из всех входных файлов.

Таким образом, компоновщик объединяет все текстовые разделы объектных файлов в текстовый раздел исполняемого файла по адресу, хранящемуся в счетчике местоположения. Раздел кода исполняемого файла начинается с 0x100000.

После того, как компоновщик разместит секцию вывода текста, значение счетчика местоположения установится в 0x1000000 + размер раздела вывода текста.

Аналогично, разделы данных и bss объединяются и помещаются на значения счетчика местоположения.

Grub и Multiboot

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

Существует стандарт для загрузки различных x86 ядер с использованием загрузчика, называемый спецификацией Multiboot.

GRUB загрузит ядро только в том случае, если оно соответствует Multiboot-спецификации.

Согласно ей, ядро должно содержать заголовок в пределах его первых 8 килобайт.

Кроме того, этот заголовок должен содержать дополнительно 3 поля:

  • поле магического числа: содержит магическое число 0x1BADB002, для идентификации заголовка.
  • поле флагов: сейчас оно не нужно, просто установим его значение в ноль.
  • поле контрольной суммы: когда задано, должно возвращать ноль для суммы с первыми двумя полями.

Итак, kernel.asm будет выглядеть таким образом:

;;kernel.asm ;nasm directive - 32 bit bits 32 section .text ;multiboot spec align 4 dd 0x1BADB002 ;магические числа dd 0x00 ;флаги dd - (0x1BADB002 + 0x00) ;контрольная сумма. мч+ф+кс должно равняться нулю global start extern kmain ;kmain определена во внешнем файле start: cli ;блокировка прерываний mov esp, stack_space ;указатель стека call kmain hlt ;остановка процессора section .bss resb 8192 ;8KB на стек stack_space:

; ; kernel . asm

; nasm directive - 32 bit

bits 32

section . text

; multiboot spec

align 4

dd 0x1BADB002 ; магическиечисла

dd 0x00 ; флаги

dd - (0x1BADB002 + 0x00 ) ; контрольнаясумма. мч+ ф+ ксдолжноравнятьсянулю

global start

extern kmain ; kmain определенавовнешнемфайле

start :

cli ; блокировкапрерываний

mov esp , stack _ space; указательстека

call kmain

hlt ; остановкапроцессора

Когда начинаешь читать пособия по продвижению сайта, всё всегда начинается с создания семантического ядра. Для новичков этот первый шаг – самый трудный. Кроме того, что не сразу становится понятно, что такое это семантическое ядро, ещё и не ясно, какую оно имеет цель и как его правильно создавать.

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

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

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

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

Как использовать семантическое ядро и для чего оно нужно

Функциями семантического ядра можно назвать следующие аспекты продвижения сайта:

  • Самая главная задача семантического ядра - это понимание структуры сайта и его наполненности. Глядя на него, можно представить себе, какие разделы у сайта будут, и какие статьи будут в каждом разделе. И, таким образом, все недостатки и неудобства структуры сразу видны, и их можно устранить ещё на раннем этапе.
  • Семантика задаёт вектор контента. Благодаря лучшему понимаю структуры сайта, можно подобрать наиболее релевантные и эффективные ключевые фразы.
  • Семантическое ядро - это контент-план сайта на долгие годы вперёд. Каждый раз, когда нужно написать статьи, можно заглянуть туда и увидеть, какой контент планировался и в каком разделе сайта он должен быть.
  • Если планируется платное продвижение сайта, например, за счёт контекстной рекламы, то благодаря семантическому ядру можно рассчитать стоимость продвижения.

Как сделать семантическое ядро

Для начала надо определиться, откуда вы будете брать ключевые фразы для ядра. Наиболее лучший для новичков источник - это сервис Яндекс WordPStat, который показывает то, сколько раз в месяц вводился тот или иной запрос в поиск Яндекс. У WordStat есть разнообразные полезные функции, например можно фильтровать запросы по регионам или устройствам, смотреть похожие запросы и многое другое. А самое главное, что он абсолютно бесплатный. Подробнее об этом .

Можно использовать и разнообразные платные программы, но новичкам лучше подойдёт именно WordStat, в виду его простоты. Кроме этого, он подойдёт не только для Рунета, где Яндекс преобладает. Если вы продвигаете сайт в пределах СНГ, то его можно смело использовать, и статистка по Google будет примерно такая же.

Основная суть создания семантического ядра - это сбор ключевых фраз, которые так или иначе подходят под тематику сайта. Их надо их как-то оформить, систематизировать. Для этого лучше всего подходят таблицы, например Excel, таблицы в Google Doc или аналогичные.

И для большей эффективности, в таблице семантического ядра можно добавить дополнительные графы:

  • Естественно, должна быть графа с самой ключевой фразой.
  • Конечно же, графа с наименование рубрики сайта, где эта фраза будет использоваться.
  • Можно добавить графу с мета-тегами titile и description и сразу написать заголовок и описание к статье с использованием заданной ключевой фразы. Во-первых, сразу будет понятно, о чём писать статью, во-вторых, потом не надо будет ломать голову и придумывать это.
  • Можно сделать графу для указания количества символов в статье по заданной ключевой фразе, чтобы лучше понимать контент-план.
  • Если речь идёт о продвижении контекстной рекламой, нужно добавить и стоимость рекламы для каждого запроса.
  • Всё, что должно понадобится можно смело записывать в таблицу сематического ядра. Какого-либо шаблона для этого нет, поэтому делать там можно всё, что угодно и удобно.

Частые ошибки при создании семантического ядра

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

  • Если ядро предусматривает разделение сайта на рубрики, то частой ошибки является создание глубоких уровней вложенности. Рекомендуется второй уровень и не далее. То есть, можно сделать рубрику, подрубрику и всё, дальше делить на более мелкие рубрики уже нельзя.
  • Новички могут игнорировать низкочастотные запросы, так как считают, что использовать их нецелесообразно, всё равно они не принесут много трафика. Но на самом деле всё наоборот. Для нового сайта нужны именно низкочастотные, никзоконкурентные запросы.
  • Нельзя полностью доверять сервису, с помощью которого будут добываться ключевые фразы. А новички поступают именно так. Машины могут ошибаться и выбрать вам не то, что нужно.
  • Не нужно создавать статью ради ключевой фразы. Если вы нашли фразы “срочно продать дом” и “продать дом быстро”, то нет смысла делать для них две разные статьи.

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

Каждый решает проблему обучения по-своему. Кто-то читает много литературы, кто-то старается поскорее перейти к практике и разбираться по ходу дела, кто-то пытается объяснять друзьям всё, что сам изучает. А мы решили совместить эти подходы. Итак, в этом курсе статей мы будем шаг за шагом демонстрировать, как пишется простая операционная система. Статьи будут носить обзорный характер, то есть в них не будет исчерпывающих теоретических сведений, однако мы будем всегда стараться предоставить ссылки на хорошие теоретические материалы и ответить на все возникающие вопросы. Чёткого плана у нас нет, так что многие важные решения будут приниматься по ходу дела, с учётом ваших отзывов.

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

Мы будем предполагать, что читатель уже знаком с основами языков ассемблер и Си, а также элементарными понятиями архитектуры ЭВМ. То есть, мы не будем объяснять, что такое регистр или, скажем, оперативная память. Если вам не будет хватать знаний, вы всегда можете обратиться к дополнительной литературе. Краткий список литературы и ссылки на сайты с хорошими статьями есть в конце статьи. Также желательно уметь пользоваться Linux, так как все инструкции по компиляции будут приводиться именно для этой системы.

А теперь - ближе к делу. В оставшейся части статьи мы с вами напишем классическую программу «Hello World». Наш хеллоуворлд получится немного специфическим. Он будет запускаться не из какой-либо операционной системы, а напрямую, так сказать «на голом железе». Перед тем, как приступить непосредственно к написанию кода, давайте разберёмся, как же конкретно мы пытаемся это сделать. А для этого надо рассмотреть процесс загрузки компьютера.

Итак, берем свой любимый компьютер и нажимаем самую большую кнопочку на системном блоке. Видим веселую заставку, системный блок радостно пищит спикером и через какое-то время загружается операционная система. Как вы понимаете, операционная система хранится на жёстком диске, и вот тут возникает вопрос: а каким же волшебным образом операционная система загрузилась в ОЗУ и начала выполняться?

Знайте же: за это отвечает система, которая есть на любом компьютере, и имя ей - нет, не Windows, типун вам на язык - называется она BIOS. Расшифровывается ее название как Basic Input-Output System, то есть базовая система ввода-вывода. Находится BIOS на маленькой микросхемке на материнской плате и запускается сразу после нажатия большой кнопки ВКЛ. У BIOS три главных задачи:

  1. Обнаружить все подключенные устройства (процессор, клавиатуру, монитор, оперативную память, видеокарту, голову, руки, крылья, ноги и хвосты…) и проверить их на работоспособность. Отвечает за это программа POST (Power On Self Test – самотестирование при нажатии ВКЛ). Если жизненно важное железо не обнаружено, то никакой софт помочь не сможет, и на этом месте системный динамик пропищит что-нибудь зловещее и до ОС дело вообще не дойдет. Не будем о печальном, предположим, что у нас есть полностью рабочий компьютер, возрадуемся и перейдем к рассмотрению второй функции BIOS:
  2. Предоставление операционной системе базового набора функций для работы с железом. Например, через функции BIOS можно вывести текст на экране или считать данные с клавиатуры. Потому она и называется базовой системой ввода-вывода. Обычно операционная система получает доступ к этим функциям посредством прерываний.
  3. Запуск загрузчика операционной системы. При этом, как правило, считывается загрузочный сектор - первый сектор носителя информации (дискета, жесткий диск, компакт-диск, флэшка). Порядок опроса носителей можно задать в BIOS SETUP. В загрузочном секторе содержится программа, иногда называемая первичным загрузчиком. Грубо говоря, задача загрузчика - начать запуск операционной системы. Процесс загрузки операционной системы может быть весьма специфичен и сильно зависит от её особенностей. Поэтому первичный загрузчик пишется непосредственно разработчиками ОС и при установке записывается в загрузочный сектор. В момент запуска загрузчика процессор находится в реальном режиме.
Печальная новость: размер начального загрузчика должен быть всего 512 байт. Почему так мало? Для этого нам надо ознакомиться с устройством дискеты. Вот познавательная картинка:

На картинке изображена поверхность дискового накопителя. У дискеты 2 поверхности. На каждой поверхности есть кольцеобразные дорожки (треки). Каждый трек делится на маленькие дугообразные кусочки, называемые секторами. Так вот, исторически сложилось, что сектор дискеты имеет размер 512 байт. Самый первый сектор на диске, загрузочный сектор, читается BIOS"ом в нулевой сегмент памяти по смещению 0x7С00, и дальше по этому адресу передается управление. Начальный загрузчик обычно загружает в память не саму ОС, а другую программу-загрузчик, хранящуюся на диске, но по каким-то причинам (скорее всего, эта причина - размер) не влезающую в один сектор. А поскольку пока что роль нашей ОС выполняет банальный хеллоуворлд, наша главная цель - заставить компьютер поверить в существование нашей ОС, пусть даже и на одном секторе, и запустить её.

Как устроен загрузочный сектор? На PC единственное требование к загрузочному сектору - это содержание в двух его последних байтах значений 0x55 и 0xAA - сигнатуры загрузочного сектора. Итак, уже более-менее понятно, что нам нужно делать. Давайте же писать код! Приведённый код написан для ассемблера yasm .

section . text

use16

org 0x7C00 ; наша программа загружается по адресу 0x7C00

start:

mov ax , cs

mov ds , ax ; выбираем сегмент данных



mov si , message

cld ; направление для строковых команд

mov ah , 0x0E ; номер функции BIOS

mov bh , 0x00 ; страница видеопамяти

puts_loop:

lodsb ; загружаем очередной символ в al

test al , al ; нулевой символ означает конец строки

jz puts_loop_exit

int 0x10 ; вызываем функцию BIOS

jmp puts_loop

puts_loop_exit:

jmp $ ; вечный цикл



message:

db "Hello World!" , 0

finish:

times 0x1FE - finish+ start db 0

db 0x55 , 0xAA ; сигнатура загрузочного сектора

Эта короткая программа требует ряда важных пояснений. Строка org 0x7C00 нужна для того, чтобы ассемблер (имеется в виду программа, а не язык) правильно рассчитал адреса для меток и переменных (puts_loop, puts_loop_exit, message). Вот мы ему и сообщаем, что программа будет загружена в память по адресу 0x7C00.
В строках
mov ax , cs

mov ds , ax
происходит установка сегмента данных (ds) равным сегменту кода (cs), поскольку в нашей программе и данные, и код хранятся в одном сегменте.

Далее в цикле посимвольно выводится сообщение «Hello World!». Для этого используется функция 0x0E прерывания 0x10 . Она имеет следующие параметры:
AH = 0x0E (номер функции)
BH = номер видеостраницы (пока не заморачиваемся, указываем 0)
AL = ASCII-код символа

В строке « jmp $ » программа зависает. И правильно, незачем ей выполнять лишний код. Однако чтобы компьютер опять заработал, придется перезагрузиться.

В строке « times 0x1FE-finish+start db 0 » производится заполнение остатка кода программы (за исключением последних двух байт) нулями. Делается это для того, чтобы после компиляции в последних двух байтах программы оказалась сигнатура загрузочного сектора.

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

Лучшие статьи по теме