Как загружаются x86-машины
Прежде чем думать о том, как писать ядро, давай посмотрим, как компьютер загружается и передает управление ядру. Большинство регистров процессора x86 имеют определенные значения после загрузки. Регистр — указатель на инструкцию (EIP) содержит адрес инструкции, которая будет исполнена процессором. Его захардкоженное значение — это 0xFFFFFFF0. То есть x86-й процессор всегда будет начинать исполнение с физического адреса 0xFFFFFFF0. Это последние 16 байт 32-разрядного адресного пространства. Этот адрес называется «вектор сброса» (reset vector).
В карте памяти, которая содержится в чипсете, прописано, что адрес 0xFFFFFFF0 ссылается на определенную часть BIOS, а не на оперативную память. Однако BIOS копирует себя в оперативку для более быстрого доступа — этот процесс называется «шедоуинг» (shadowing), создание теневой копии. Так что адрес 0xFFFFFFF0 будет содержать только инструкцию перехода к тому месту в памяти, куда BIOS скопировала себя.
Итак, BIOS начинает исполняться. Сначала она ищет устройства, с которых можно загружаться в том порядке, который задан в настройках. Она проверяет носители на наличие «волшебного числа», которое отличает загрузочные диски от обычных: если байты 511 и 512 в первом секторе равны 0xAA55, значит, диск загрузочный.
Как только BIOS найдет загрузочное устройство, она скопирует содержимое первого сектора в оперативную память, начиная с адреса 0x7C00, а затем переведет исполнение на этот адрес и начнет исполнение того кода, который только что загрузила. Вот этот код и называется загрузчиком (bootloader).
Загрузчик загружает ядро по физическому адресу 0x100000. Именно он и используется большинством популярных ядер для x86.
Все процессоры, совместимые с x86, начинают свою работу в примитивном 16-разрядном режиме, которые называют «реальным режимом» (real mode). Загрузчик GRUB переключает процессор в 32-разрядный защищенный режим (protected mode), переводя нижний бит регистра CR0 в единицу. Поэтому ядро начинает загружаться уже в 32-битном защищенном режиме.
Заметь, что GRUB в случае с ядрами Linux выбирает соответствующий протокол загрузки и загружает ядро в реальном режиме. Ядра Linux сами переключаются в защищенный режим.
Недостатки метода
- Мобильные устройства. Не рекомендуется включать в систему все элементы в ноутбуках и нетбуках. Устройство может не выдержать большой нагрузки, что приведет к выходу из строя.
- Энергопотребление. Даже при небольшой загруженности элементов, энергопотребление увеличивается в несколько раз. Необходимо регулировать вычисления компьютера так, чтобы снизить данный показатель, иначе на функциональность будет тратиться слишком много энергии.
- Износ. Так как комплектующие используются на максимальных параметрах, они быстрее изнашиваются. Регулярная мощная работа приведет к износу и поломке центрального процессора. Придется заменять комплектующие, которые стоят дорого, особенно многоядерные. Среднее потребление энергии центрального процессора составляет 40-50 ватт. Для стационарной системы это приемлемая величина, однако ноутбук быстро выйдет из строя, так как у него низкие показатели.
- Повреждение. Есть риск, что заблокированные комплектующие повреждены. В выключенном состоянии дефекты незаметны. Поломка не мешает нормальной работе ПК. При наличии повреждений, скорее всего, у пользователя не получится активировать элемент — это основной признак дефектов.
- Неустойчивая работа. Даже если включить все ядра в работу, нет гарантии, что компьютер будет стабильно функционировать. Возможно, система не выдержит такой нагрузки, если до этого устройство эксплуатировалось без многоядерности длительное время. Чрезмерная нагрузка видна не сразу. Обычно, неполадки появляются спустя некоторое время после использования мощных программ или игр.
IDT — это массив, объединяющий структуры IDT_entry. Мы еще обсудим привязку клавиатурного прерывания к обработчику, а сейчас посмотрим, как работает PIC.
Современные системы x86 имеют два чипа PIC, у каждого восемь входных линий. Будем называть их PIC1 и PIC2. PIC1 получает от IRQ0 до IRQ7, а PIC2 — от IRQ8 до IRQ15. PIC1 использует порт 0x20 для команд и 0x21 для данных, а PIC2 — порт 0xA0 для команд и 0xA1 для данных.
Оба PIC инициализируются восьмибитными словами, которые называются «командные слова инициализации» (Initialization command words, ICW).
В защищенном режиме обоим PIC первым делом нужно отдать команду инициализации ICW1 (0x11). Она сообщает PIC, что нужно ждать еще трех инициализационных слов, которые придут на порт данных.
Эти команды передадут PIC:
- вектор отступа (ICW2),
- какие между PIC отношения master/slave (ICW3),
- дополнительную информацию об окружении (ICW4).
Вторая команда инициализации (ICW2) тоже шлется на вход каждого PIC. Она назначает , то есть значение, к которому мы добавляем номер линии, чтобы получить номер прерывания.
PIC разрешают каскадное перенаправление их выводов на вводы друг друга. Это делается при помощи ICW3, и каждый бит представляет каскадный статус для соответствующего IRQ. Сейчас мы не будем использовать каскадное перенаправление и выставим нули.
ICW4 задает дополнительные параметры окружения. Нам нужно определить только нижний бит, чтобы PIC знали, что мы работаем в режиме 80×86.
Та-дам! Теперь PIC проинициализированы.
У каждого PIC есть внутренний восьмибитный регистр, который называется «регистр масок прерываний» (Interrupt Mask Register, IMR). В нем хранится битовая карта линий IRQ, которые идут в PIC. Если бит задан, PIC игнорирует запрос. Это значит, что мы можем включить или выключить определенную линию IRQ, выставив соответствующее значение в 0 или 1.
Чтение из порта данных возвращает значение в регистре IMR, а запись — меняет регистр. В нашем коде после инициализации PIC мы выставляем все биты в единицу, чем деактивируем все линии IRQ. Позднее мы активируем линии, которые соответствуют клавиатурным прерываниям. Но для начала все же выключим!
Если линии IRQ работают, наши PIC могут получать сигналы по IRQ и преобразовывать их в номер прерывания, добавляя оффсет. Нам же нужно заполнить IDT таким образом, чтобы номер прерывания, пришедшего с клавиатуры, соответствовал адресу функции-обработчика, которую мы напишем.
На какой номер прерывания нам нужно завязать в IDT обработчик клавиатуры?
Клавиатура использует IRQ1. Это входная линия 1, ее обрабатывает PIC1. Мы проинициализировали PIC1 с оффсетом 0x20 (см. ICW2). Чтобы получить номер прерывания, нужно сложить 1 и 0x20, получится 0x21. Значит, адрес обработчика клавиатуры будет завязан в IDT на прерывание 0x21.
Задача сводится к тому, чтобы заполнить IDT для прерывания 0x21. Мы замапим это прерывание на функцию , которую напишем в ассемблерном файле.
Каждая запись в IDT состоит из 64 бит. В записи, соответствующей прерыванию, мы не сохраняем адрес функции-обработчика целиком. Вместо этого мы разбиваем его на две части по 16 бит. Нижние биты сохраняются в первых 16 битах записи в IDT, а старшие 16 бит — в последних 16 битах записи. Все это сделано для совместимости с 286-ми процессорами. Как видишь, Intel выделывает такие номера на регулярной основе и во многих-многих местах!
В записи IDT нам осталось прописать тип, обозначив таким образом, что все это делается, чтобы отловить прерывание. Еще нам нужно задать оффсет сегмента кода ядра. GRUB задает GDT за нас. Каждая запись GDT имеет длину 8 байт, где дескриптор кода ядра — это второй сегмент, так что его оффсет составит 0x08 (подробности не влезут в эту статью). Гейт прерывания представлен как 0x8e. Оставшиеся в середине 8 бит заполняем нулями. Таким образом, мы заполним запись IDT, которая соответствует клавиатурному прерыванию.
Когда с маппингом IDT будет покончено, нам надо будет сообщить процессору, где находится IDT. Для этого существует ассемблерная инструкция lidt, она принимает один операнд. Им служит указатель на дескриптор структуры, которая описывает IDT.
С дескриптором никаких сложностей. Он содержит размер IDT в байтах и его адрес. Я использовал массив, чтобы вышло компактнее. Точно так же можно заполнить дескриптор при помощи структуры.
В переменной у нас есть указатель, который мы передаем инструкции в функции .
1 |
load_idt mov edx,esp+4 lidtedx sti ret |
Дополнительно функция возвращает прерывание при использовании инструкции .
Заполнив и загрузив IDT, мы можем обратиться к IRQ клавиатуры, используя маску прерывания, о которой мы говорили ранее.
1 |
voidkb_init(void) { write_port(0x21,0xFD); } |
— это — включаем только IRQ1 (клавиатуру).
Какую версию Linux выбрать
Когда мы говорим о программном обеспечении, мы всегда рекомендуем иметь самую последнюю версию всего. Это лучший способ гарантировать, что из-за нарушения безопасности наш компьютер окажется под угрозой. С ядром Linux то же самое, всегда рекомендуется иметь последнюю версию
Однако всегда нужно делать это осторожно
Одна из причин, по которой ядро такое большое, заключается в том, что оно ничего не удаляет. Столь же старый, как он есть. Благодаря этому можно продолжать использовать последние версии Linux на первых компьютерах, где он был впервые запущен в 1991 году. Каждое обновление, которое оно обычно делает, добавить драйверы и изменить функции для оптимизации общая работа ПК.
Но может случиться так, что версия содержит ошибку, из-за которой наш компьютер не работает должным образом, и даже производительность не соответствует ожидаемой. В этом случае просто переустановка предыдущей версии должен вернуть операционную систему в нормальное состояние. Хотя мы потеряем поддержку более новых аппаратных компонентов.
Лучшим и самым простым для большинства является обновление ядра по мере обновления дистрибутива из его репозиториев. Таким образом, мы избежим этих проблем, «всегда будучи в курсе».
Физика смотрит на мир совсем не так, как биология
Жизнь — это царство частного. Конкретные свойства достигаются при определенном сочетании компонентов, и любые изменения в этой комбинации вызвали бы катастрофические последствия. Малейшее изменение скорости, с которой кровь течет по сосудам, или последовательности ДНК, кодирующей структуру определенного белка, может существенно отразиться на функционировании всего организма.
Данной проблемы невозможно избежать, так как взгляд с точки зрения физики всегда будет отличаться от взгляда с точки зрения биологии.
Физика основана на измерении конкретных величин: расстояния, массы, длительности, заряда, температуры и т. п. Физические законы выражают то, как одни измеримые величины меняются под влиянием других измеримых величин. Гениальность второго закона Ньютона не столько в том, что он устанавливает зависимость между силой, массой и ускорением, а в том, что он показывает: все эти величины можно измерить по отдельности.
Мы знаем гораздо меньше, чем думаем. И это можно проверить
Знание часто определяют как «обоснованное истинное убеждение». Однако на деле большинство знаний мы обосновать не можем — и просто верим в то, что услышали от других людей.
К примеру — мы знаем факт, что растения используют фотосинтез, или знаем, что машину с бензиновым двигателем не стоит заправлять дизельным топливом. Но объяснить подробно, как работает фотосинтез или как устроен двигатель внутреннего сгорания, подавляющее большинство не сможет.
Человек часто переоценивает способность объяснять феномены окружающего мира. Так, в одном эксперименте группу подопытных спросили, понимают ли они, что такое гроза и радуга, на что все ответили положительно. А затем попросили объяснить их происхождение — лишь в этот момент большинство респондентов осознали собственную беспомощность.
Хатсон пишет, что поставить на себе такой эксперимент может каждый — просто попробуйте нарисовать по памяти велосипед, а потом сравните с тем, как выглядит оригинал.
ПК становится медленным
Я знаю, что вы чувствуете, когда требуется всего 5 минут, чтобы открыть только приложение. Ну, это еще одна распространенная проблема, с которой люди сталкиваются в своей повседневной жизни.
Основная причина обычно связана с продолжительностью работы компьютера. Компьютер старше 2 лет будет испытывать это независимо от их технических характеристик.
Решения:
1. Найти ресурсоёмкую программу
В вашей системе полно программ, безусловно, будет одна или две программы, которые используют множество ваших ресурсов, например, оперативную память.
Чтобы узнать, откройте диспетчер задач. Вы можете щелкнуть правой кнопкой мыши на панели задач и выбрать опцию «Диспетчер задач» или нажать Ctrl + Shift + Escape, чтобы открыть ее. В Windows 8, 8.1 и 10.
Щелкните заголовки «CPU», «Memory» и «Disk», чтобы отсортировать список по приложениям, использующим наибольшее количество ресурсов. Если какое-либо приложение использует слишком много ресурсов, вы можете закрыть его как обычно – если вы не можете, выберите его здесь и нажмите «Завершить задачу», чтобы принудительно закрыть его.
2. Отключить запуск программы
Автозапуск программ во время запуска системы может быть основной причиной замедления работы ПК.
В Windows 8, 8.1 и 10 теперь есть диспетчер запуска в диспетчере задач, который вы можете использовать для управления программами запуска.
Щелкните правой кнопкой мыши панель задач и выберите «Диспетчер задач» или нажмите Ctrl + Shift + Escape, чтобы запустить его. Перейдите на вкладку «Автозагрузка» и отключите автозапуск приложений, которые вам не нужны.
Windows подскажет вам, какие приложения больше всего замедляют процесс запуска.
3. Сканирование на наличие вредоносного и рекламного ПО.
Ежедневное использование компьютеров может заставить вас случайно поймать вредоносное и рекламное ПО.
Обычно это небольшие вредоносные программы, которые вылавливаются из Интернета, когда мы что-то просматриваем или скачиваем.
Эти программы предназначены для кражи вашей информации и для этого они должны передавать информацию через Интернет, что потенциально может замедлить работу вашей системы.
Чтобы удалить их, просто используйте встроенное антивирусное программное обеспечение для сканирования и обнаружения. Для получения дополнительной информации о том, как удалить шпионское и рекламное ПО, ознакомьтесь с моей статьей здесь .
Комбинация разных подходов [ править | править код ]
Все рассмотренные подходы к построению операционных систем имеют свои достоинства и недостатки. В большинстве случаев современные операционные системы используют различные комбинации этих подходов. Так, например, сейчас ядро «Linux» представляет собой монолитную систему с отдельными элементами модульного ядра . При компиляции ядра можно разрешить динамическую загрузку и выгрузку очень многих компонентов ядра — так называемых модулей. В момент загрузки модуля его код загружается на уровне системы и связывается с остальной частью ядра. Внутри модуля могут использоваться любые экспортируемые ядром функции.
Существуют варианты ОС GNU, в которых вместо монолитного ядра применяется ядро Mach (такое же, как в Hurd), а поверх него крутятся в пользовательском пространстве те же самые процессы, которые при использовании Linux были бы частью ядра. Другим примером смешанного подхода может служить возможность запуска операционной системы с монолитным ядром под управлением микроядра. Так устроены 4.4BSD и MkLinux, основанные на микроядре Mach. Микроядро обеспечивает управление виртуальной памятью и работу низкоуровневых драйверов. Все остальные функции, в том числе взаимодействие с прикладными программами, осуществляются монолитным ядром. Данный подход сформировался в результате попыток использовать преимущества микроядерной архитектуры, сохраняя по возможности хорошо отлаженный код монолитного ядра.
Смешанное ядро, в принципе, должно объединять преимущества монолитного ядра и микроядра: казалось бы, микроядро и монолитное ядро — крайности, а смешанное — золотая середина. В них возможно добавлять драйвера устройств двумя способами: и внутрь ядра, и в пользовательское пространство. Но на практике концепция смешанного ядра часто подчёркивает не только достоинства, но и недостатки обоих типов ядер.
Ядро системы каждый день помогает работе компьютера, но многие даже не знают, что это такое. Мы расскажем про все функции ядра и простыми словами объясним, для чего оно нужно.
Итак, что такое ядро операционной системы и за что оно отвечает в работе вашего компьютера? Разберемся подробнее.
- Ядро — это согласующее звено между графическим интерфейсом, программным и аппаратным обеспечением. Ядро постоянно используется в работе компьютера и является центральным модулем операционной системы.
- Ядро имеет разные слои. Нижний уровень формирует интерфейс к системному оборудованию, например, сетевым контроллерам или контроллерам PCI Express.
- Следующий уровень отвечает за управление памятью и выделяет ее каждому процессу. Ваше программное обеспечение обычно включает в себя несколько таких процессов.
- Уровень «управления процессами» позволяет параллельно запускать несколько задач на вашем компьютере. Ядро обрабатывает все запросы, поступающие от программ, упорядочивает их во времени и прерывает, если возникают проблемы.
- Верхний уровень — файловая система. Здесь процессам назначаются области на HDD (жестком диске) и в основной памяти компьютера.
- Таким образом, ядро регулирует весь путь от системного оборудования до прикладного программного обеспечения, которым управляет пользователь через графический интерфейс (GUI). Но сама пользовательская область не является частью ядра и называется «shell», «ring» или «userland».
- Компьютерная программа отправляет системные вызовы «System Calls» в ядро. Затем оно делает фактический запрос на машинном языке СPU. Ядро знает полный набор команд центрального процессора, то есть все машинные инструкции, которые он может выполнить. Такие системные вызовы запускаются, например, при чтении или записи файлов на компьютер. Эта простая задача постоянно решается даже в фоновом режиме.
- В многопользовательских системах ядро также контролирует доступ к файлам и аппаратным компонентам.
архитектура и типы ядер операционной системы
Классическая архитектура ядра очень сильно зависит от того какой тип ядра представлен в операционной системе. Типов ядер операционной системы бывает очень много и все различаются лишь по размеру и доступным функциям кроме базовых.
Монолитное ядро
монолитное ядро операционной системы представляет богатый выбор абстракций. все части или лучше сказать элементы находятся в одном адресном пространстве и представляют собой единый «Монолит». Все элементы которые были представлены выше на картинке спокойно взаимодействуют между собой и сообщаются. Это самое старое воплощение ядра в ОС.
Недостаток:
Обладает достаточно значимым минусом что при отказе работы одного элемента перестает работать всё ядро операционной системы и следовательно ОС.
Преимущества:
Из положительного момента — быстрая разработка и внедрение новых модулей а также скорость работы такого ядра. всё таки унификация всех элементов берет своё
Примеры ОС построенных на таких ядрах :LINUX, Unix, ms-dos
Модульное ядро
Модульное уже более современная реализация типа работы ядра операционной системы . Модульное ядро в отличие от монолитного, бывает двух видов статичное и динамическое. Статичное работает как и монолитное, все изменения только после перезапуска, а динамическая заключается в следующем — при разработке ядра операционной системы не нужно перезагружать всю систему, а только ту часть которая подверглась каким либо изменениям. Для пользователя это выражается в том что после установки, например драйвера для новой видеокарты не нужно перезагружать систему, после установки перезагрузится только тот модуль что работает с этим новым драйвером, как говориться на лету.
Микроядро
Микроядро работает по принципу всё что сложнее элементарных функций — выноситься за пределы его работы. Наибольшая часть работы выполняется с помощью сервисов или по другому пользовательских процессов.
драйверы и модули, всё находиться в серверных процессах. Чтобы было понятно взгляните на картинку
Самые главные преимущества то что при любой сбой системы или например обновление ядра, не может нанести ущерба и это можно делать раздельно. Также намного проще позволяет добавлять новые элементы не прерывая работы системы.
Недостатки: увеличенное потребление ресурсов.
Из самых популярных операционных систем которое используют это ядро операционной системы это MAC OS X.
Экзоядро
Экзоядро представляет всего лишь самые базовые функция взаимодействия между процессами, выгрузка и загрузка памяти и других ресурсов. То есть устроенно это ядро таким образом — ядро операционной системы не взаимодействует с программным обеспечением напрямую, а только через специальные библиотеки которые предоставляют API. Является оптимальным решениям для некоторого вида приложений которые должны очень быстро работать.
Сервисы ОС¶
Функции ОС заключены в её сервисах (модулях). Реализация организации которых зависит от архитектуры ядра. Рассмотрим на примере монолитного ядра:
Рис 6. Основные компоненты ОС
-
- Управление процессами (Process scheduler — планировщик)
-
- Запуск (помещение на процессор, выделение процессорного времени)
- Приостановка (заморозка)
- Завершение
- Изменение приоритета
Примечание
Как говорилось , реализация планировщика осуществляется с помощью прерывания по таймеру — каждый квант времени происходит прерывание, которое передаёт управление ОС и она анализирует состояние всех процессов и что с каким процессом сделать: запустить, приостановить, завершить или изменить приоритет.
-
- Межпроцессное взаимодействие (IPC — Inter Process Communication)
-
- Общая память для нескольких процессов (shared memory)
- Способы обмена данными через те или иные механизмы (file, pipe, signals)
- Сетевое взаимодействие
- Механизмы предотвращения коллизий и синхронизации (семафоры, мьютексы)
-
- Управление памятью (Memory manager)
-
- Динамическое выделение памяти (Memory allocation)
- Создание иллюзии уникальности адресного пространства для каждого процесса
- Механизм виртуальной памяти
Модульное ядро[править | править код]
- Основная статья: Модульное ядро
Модульное ядро — современная, усовершенствованная модификация архитектуры монолитных ядер операционных систем компьютеров.
В отличие от «классических» монолитных ядер, считающихся ныне устаревшими, модульные ядра, как правило, не требуют полной перекомпиляции ядра при изменении состава аппаратного обеспечения компьютера. Вместо этого модульные ядра предоставляют тот или иной механизм подгрузки модулей ядра, поддерживающих то или иное аппаратное обеспечение (например, драйверов). При этом подгрузка модулей может быть как динамической (выполняемой «на лету», без перезагрузки ОС, в работающей системе), так и статической (выполняемой при перезагрузке ОС после переконфигурирования системы на загрузку тех или иных модулей).
Все модули ядра работают в адресном пространстве ядра и могут пользоваться всеми функциями, предоставляемыми ядром. Поэтому модульные ядра продолжают оставаться монолитными.
Модульные ядра удобнее для разработки, чем традиционные монолитные ядра, не поддерживающие динамическую загрузку модулей, так как от разработчика не требуется многократная полная перекомпиляция ядра при работе над какой-либо его подсистемой или драйвером. Выявление, локализация, отладка и устранение ошибок при тестировании также облегчаются.
Модульные ядра предоставляют особый программный интерфейс (API) для связывания модулей с ядром, для обеспечения динамической подгрузки и выгрузки модулей. В свою очередь, не любая программа может быть сделана модулем ядра: на модули ядра накладываются определённые ограничения в части используемых функций (например, они не могут пользоваться функциями стандартной библиотеки С/С++ и должны использовать специальные аналоги, являющиеся функциями API ядра). Кроме того, модули ядра обязаны экспортировать определённые функции, нужные ядру для правильного подключения и распознавания модуля, для его корректной инициализации при загрузке и корректного завершения при выгрузке, для регистрации модуля в таблице модулей ядра и для обращения из ядра к сервисам, предоставляемым модулем.
Не все части ядра могут быть сделаны модулями. Некоторые части ядра всегда обязаны присутствовать в оперативной памяти и должны быть жёстко «вшиты» в ядро. Также не все модули допускают динамическую подгрузку (без перезагрузки ОС). Степень модульности ядер (количество и разнообразие кода, которое может быть вынесено в отдельные модули ядра и допускает динамическую подгрузку) различна в различных архитектурах модульных ядер. Ядра Linux в настоящее время имеют более модульную архитектуру, чем ядра *BSD (FreeBSD, NetBSD, OpenBSD).
Общей тенденцией развития современных модульных архитектур является всё большая модуларизация кода (повышение степени модульности ядер), улучшение механизмов динамической подгрузки и выгрузки, уменьшение или устранение необходимости в ручной подгрузке модулей или в переконфигурации ядра при изменениях аппаратуры путём введения тех или иных механизмов автоматического определения оборудования и автоматической подгрузки нужных модулей, универсализация кода ядра и введение в ядро абстрактных механизмов, предназначенных для совместного использования многими модулями (примером может служить VFS — «виртуальная файловая система», совместно используемая многими модулями файловых систем в ядре Linux).
Курсивное начертание
Доступ к портам ввода-вывода осуществляется при помощи инструкций in и out, входящих в набор x86.
В номер порта передается в качестве аргумента. Когда компилятор вызывает функцию, он кладет все аргументы в стек. Аргумент копируется в регистр при помощи указателя на стек. Регистр — это нижние 16 бит регистра . Инструкция здесь читает порт, номер которого задан в , и кладет результат в . Регистр — это нижние 8 бит регистра . Возможно, ты помнишь из институтского курса, что значения, возвращаемые функциями, передаются через регистр . Таким образом, позволяет нам читать из портов ввода-вывода.
Функция работает схожим образом. Мы принимаем два аргумента: номер порта и данные, которые будут записаны. Инструкция пишет данные в порт.