Профессиональное веб-программирование

Лабораторная работа №1. Знакомство с рабочей средой SYNTACORE KIT

Разбить на страницы
Показывать лекцию целиком

1.1 Цель и задачи

Целью работы является освоение работы с виртуальным окружением лабораторного практикума (Syntacore Kit).

Для достижения поставленной цели требуется решить следующие задачи:

  • Изучить структуру виртуального окружения, научится запускать виртуальные машины.
  • Ознакомиться с основными командами, позволяющими проверить исправность среды.
  • Изучить инструменты кросс-компиляции программ.
  • Написать программу-пример для работы в виртуальной машине на базе RISC-V.
  • Презентация к блоку "Введение и инструменты сборки"

    1.2. Основные теоретические сведения

    1.2.1. Syntacore Kit

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

    Syntacore Kit -- набор инструментов разработчика для платформы RISC-V, организованный в виде набора виртуальных машин. Внешне Syntacore Kit представляет собой образ виртуальной машины VirtualBox, внутри которого содержится ОС (операционная система) Ubuntu 22.04 с процессором x86_64, необходимые инструменты разработчика (инструменты командной строки и Syntacore SC-IDE) , а также виртуальная машина QEMU с процессором RISC-V и ОС Debian Unstable с ядром Linux версии 5.18. В дальнейшем мы будем использовать следующие термины:

  • ОС хоста - операционная система компьютера, на котором вы выполняете лабораторные работы
  • Гостевая ОС - операционная система Ubuntu 22.04, работающая на виртуальной машине VirtualBox, запускаемой в ОС хоста.
  • RISC-V ОС - операционная система Debian Unstable с ядром Linux версии 5.18 без графической оболочки, работающая на виртуальной машине QEMU (с виртуальным процессором RISC-V), запускаемой на гостевой ОС.
  • Syntacore Kit позволяет разработчикам создавать, компилировать и запускать тестировать программы для платформы RISC-V с помощью инструментов, расположенных в гостевой ОС. Для этого используется механизм кросс-компиляции - подхода, при котором код программы собирается для архитектуры, отличной от той, где запущен компилятор. Кросс-компиляторы входят в состав инструментов командной строки и Syntacore SC-IDE.

    1.2.2. Компиляция и запуск программ в Syntacore Kit

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

    Если запуск выполнен успешно, то вы увидите интерфейс гостевой ОС (Рис 1.)

    (рис 1.1) Интерфейс гостевой ОС и основные элементы Syntacore Kit

    Необходимые элементы Syntacore Kit для выполнения данной лабораторной работы:

  • Эмулятор терминала.
  • Ярлык запуска Syntacore SC-IDE.
  • Для того чтобы запустить RISC-V ОС, нажмите на ярлык №1 (Рис. 2.1). В открывшемся окне терминала выполните две команды

    $ cd ~/riscv-debian-sandbox/artifacts
    $ ./run.sh
    

    После выполнения данных команд начнется процесс запуска виртуальной машины QEMU c RISC-V ОС. Полная загрузка RISC-V ОС может потребовать некоторого времени (порядка 1-2 минут). В случае успешного запуска в интерфейсе гостевой ОС отобразится следующее окно (Рис. 1.2).

    (рис 1.2) Интерфейс авторизации RISC-V ОС

    В окне вам будет предоставлен интерфейс авторизации RISC-V ОС. Для авторизации используйте логин debian и пароль debian. В случае успешной авторизации вам будет доступен интерфейс командной строки (Рис. 1.3).

    (рис 1.3) Интерфейс командной строки RISC-V ОС

    В командной строке (Рис. 1.3) содержится минимальный инструментарий разработчика, позволяющий создавать и компилировать программы непосредственно в RISC-V ОС. Рассмотрим три основных способа создания RISC-V приложений в Syntacore Kit

    Создание приложений в терминале RISC-V ОС

    При данном способе и редактирование исходного кода, и его компиляция происходит в RISC-V ОС. Для сборки своего первого приложения выполните следующие команды:

    $ cd ~/hello_world_test/ # Смена текущего каталога 
    $ gcc -o hello hello.c  # Компиляция программы (флаг -o задает имя исполняемого файла
    $ ./hello # запуск программы
    

    В случае успешного выполнения в терминале должна отобразится строка "Hello from RISC-V". Обратите внимание, что вы можете создавать новые программы или редактировать пример с помощью предустановленных текстовых редакторов в командной строке nano, vim и vi. Начинающим пользователям мы рекомендуем использовать nano.

    Создание приложений в терминале гостевой ОС

    Гостевая ОС имеет инструменты кросс-компиляции для сборки RISC-V приложений. Для начала работы в терминале создайте с помощью следующих команд файл hello.c:

    $ nano hello.c
    

    В открывшемся окне вставьте код программы выше с помощью буфера обмена. Затем нажмите сочетание клавиш CTRL + X (в английской раскладке). После чего, нажмите на клавиатуре Y (в английской раскладке) и клавишу Enter.

    #include <stdio.h>
    
    int main(void)
    {
        printf("Hello from RISC-V\n");
        return 0;
    }
    

    Далее выполните команду кросс-компиляции:

    $ riscv64-unknown-linux-gnu-gcc -o hello hello.c
    

    Эта команда вызовет специальную версию компилятора gcc, которая создает приложения RISC-V. По итогу ее работы, на вашей файловой системе будет создан файл ./hello. Однако, если вы попробуете запустить его в том же терминале, то вас ждет ошибка:

    $ ./hello 
    bash: ./hello: cannot execute binary file: Exec format error
    

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

    1.2.2.1 Запуск через qemu-riscv64

    В ряде случаев, для запуска и отладки программ на архитектуре RISC-V не обязательно запускать полноценную виртуальную машину с RISC-V ОС. В этих случаях можно использовать утилиту qemu-riscv64, которая обеспечивает запуск легковесной эмуляции для одной программы.

    Выполните следующую команду в терминале гостевой ОС:

    $ qemu-riscv64 -L "$RISCV/sysroot" ./hello
    

    Произойдет запуск и вы увидите сообщение "Hello from RISC-V". Флаг -L устанавливает предварительно настроенное окружение для корректной работы RISC-V программ.

    1.2.2.2 Копирование программы в RISC-V ОС

    В терминале гостевой ОС выполните команду копирования по ssh:

    $ scp ./hello riscv-debian:/home/debian 
    

    Данная команда создала копию исполняемого файла ./hello из гостевой ОС в каталоге /home/debian RISC-V ОС. Теперь откройте окно терминала RISC-V ОС и выполните команды

    $ cd ~
    $ ./hello
    

    Произойдет запуск и вы увидите сообщение "Hello from RISC-V".

    1.2.2.3 Создание приложений в Syntacore SC-IDE

    Для запуска Syntacore SC-IDE нажмите на ярлык №2 (Рис. 1.4). В появившемся окне выберите пункт меню File -> New -> C/C++ project

    (рис 1.4) Создание проекта в Syntacore SC-IDE

    На экране (Рис. 1.5) появится диалог "New C/C++ project" . В нем необходимо выбрать опцию "C Managed build" и нажать Next.

    (рис 1.5) Выбор типа сборки

    На следующем шаге (Рис. 1.6) введите имя проекта (1), выберите Project type как "Syntacore RV32/64GC ANSI C/C++ Project" и "RISC-V Cross GCC" (2 и 3)

    (рис 1.6) Настройки для работы с RISC-V

    На следующем этапе (Рис. 1.7) убедитесь, что установлена опция "64 bit XLEN".

    (рис 1.7) Базовые настройки проекта

    На следующем экране (Рис. 1.8) оставьте настройки по умолчанию и нажмите Next. На последнем экране выберите "Toolchain name" в соответствии с "RISC-V GCC/Linux (riscv64-unknown-linux-gnu-gcc)" и нажмите Finish.

    (рис 1.8) Настройки тулчейна проекта

    После этого (Рис. 1.9) у вас отобразится окно редактора файла main.c с кодом HelloWorld приложения. Для его запуска используйте команду

    (рис 1.9) Интерфейс запуска проекта

    Вывод запущенного приложения (Рис. 1.10) отобразится в нижней части среды разработки:

    (рис 1.10) Консоль запущенного приложения

    Обратите внимание, что помимо вывода самого приложения, выводятся также отладочные символы соединения с RISC-V ОС.

    1.2.3. Получение сведений об аппаратном обеспечении в Linux

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

    $ arch # Гостевая ОС
    x86_64
    
    $ arch # RISC-V ОС
    riscv64
    

    Расширенная информация о процессоре и ОЗУ содержится в procfs, в частности в /proc/cpuinfo и /proc/meminfo. С точки зрения ОС это текстовые файлы, содержимое которых можно вывести стандартными средствами (пример для гостевой ОС):

    $ cat /proc/cpuinfo
    processor	: 0
    vendor_id	: GenuineIntel
    cpu family	: 6
    model		: 142
    model name	: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
    stepping	: 9
    cpu MHz		: 2712.008
    ……
    
    ~$ cat /proc/meminfo 
    MemTotal:        2022664 kB
    MemFree:          177740 kB
    MemAvailable:     278060 kB
    Buffers:            6136 kB
    …..
    

    1.3. Задание к лабораторной работе

    Напишите программу на языке С, которая последовательно выводит информацию о процессоре (каждый пункт списка выводится в новой строке):

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

    Программу необходимо скомпилировать и запустить последовательно в гостевой ОС и в RISC-V ОС (либо через qemu-riscv64).

    1.3.1. Описание последовательности выполнения работы

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

    Далее необходимо составить универсальную программу, которая будет решать поставленную задачу вне зависимости от архитектуры процессора, под которую она скомпилирована. Авторы предлагают вынести в отдельные функции работу с /proc/cpuinfo и работу с командой arch. Обратите внимание на формат файла cpuinfo - каждое ядро процессора выводится отдельным блоком. Примеры кода можно посмотреть в разделе 1.2.

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

    1.3.2. Пример выполнения задания на защиту

    Напишите программу, которая считывает общий объем оперативной памяти компьютера.

    #include <stdio.h>
    
    int main(void)
    {
        FILE *meminfo = fopen("/proc/meminfo", "r");
    
        char line[256];
        while(fgets(line, sizeof(line), meminfo))
        {
            int ram;
            if(sscanf(line, "MemTotal: %d kB", ram) == 1)
            {
                fclose(meminfo);
                printf("%d", ram);
            }
        }
    
        fclose(meminfo);
        return 0;
    }
    

    1.4. Вопросы для контроля

  • Как в Syntacore Kit реализуется возможность запуска программ для архитектуры RISC-V?
  • В чем состоит назначение qemu-riscv64?
  • Как узнать размер кэш-памяти для одного ядра процессора в Linux?
  • Страницы:

    1.1 Цель и задачи

    Целью работы является освоение работы с виртуальным окружением лабораторного практикума (Syntacore Kit).

    Для достижения поставленной цели требуется решить следующие задачи:

  • Изучить структуру виртуального окружения, научится запускать виртуальные машины.
  • Ознакомиться с основными командами, позволяющими проверить исправность среды.
  • Изучить инструменты кросс-компиляции программ.
  • Написать программу-пример для работы в виртуальной машине на базе RISC-V.
  • Презентация к блоку "Введение и инструменты сборки"

    1.2. Основные теоретические сведения

    1.2.1. Syntacore Kit

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

    Syntacore Kit -- набор инструментов разработчика для платформы RISC-V, организованный в виде набора виртуальных машин. Внешне Syntacore Kit представляет собой образ виртуальной машины VirtualBox, внутри которого содержится ОС (операционная система) Ubuntu 22.04 с процессором x86_64, необходимые инструменты разработчика (инструменты командной строки и Syntacore SC-IDE) , а также виртуальная машина QEMU с процессором RISC-V и ОС Debian Unstable с ядром Linux версии 5.18. В дальнейшем мы будем использовать следующие термины:

  • ОС хоста - операционная система компьютера, на котором вы выполняете лабораторные работы
  • Гостевая ОС - операционная система Ubuntu 22.04, работающая на виртуальной машине VirtualBox, запускаемой в ОС хоста.
  • RISC-V ОС - операционная система Debian Unstable с ядром Linux версии 5.18 без графической оболочки, работающая на виртуальной машине QEMU (с виртуальным процессором RISC-V), запускаемой на гостевой ОС.
  • Syntacore Kit позволяет разработчикам создавать, компилировать и запускать тестировать программы для платформы RISC-V с помощью инструментов, расположенных в гостевой ОС. Для этого используется механизм кросс-компиляции - подхода, при котором код программы собирается для архитектуры, отличной от той, где запущен компилятор. Кросс-компиляторы входят в состав инструментов командной строки и Syntacore SC-IDE.

    1.2.2. Компиляция и запуск программ в Syntacore Kit

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

    Если запуск выполнен успешно, то вы увидите интерфейс гостевой ОС (Рис 1.)

    (рис 1.1) Интерфейс гостевой ОС и основные элементы Syntacore Kit

    Необходимые элементы Syntacore Kit для выполнения данной лабораторной работы:

  • Эмулятор терминала.
  • Ярлык запуска Syntacore SC-IDE.
  • Для того чтобы запустить RISC-V ОС, нажмите на ярлык №1 (Рис. 2.1). В открывшемся окне терминала выполните две команды

    $ cd ~/riscv-debian-sandbox/artifacts
    $ ./run.sh
    

    После выполнения данных команд начнется процесс запуска виртуальной машины QEMU c RISC-V ОС. Полная загрузка RISC-V ОС может потребовать некоторого времени (порядка 1-2 минут). В случае успешного запуска в интерфейсе гостевой ОС отобразится следующее окно (Рис. 1.2).

    (рис 1.2) Интерфейс авторизации RISC-V ОС

    В окне вам будет предоставлен интерфейс авторизации RISC-V ОС. Для авторизации используйте логин debian и пароль debian. В случае успешной авторизации вам будет доступен интерфейс командной строки (Рис. 1.3).

    (рис 1.3) Интерфейс командной строки RISC-V ОС

    В командной строке (Рис. 1.3) содержится минимальный инструментарий разработчика, позволяющий создавать и компилировать программы непосредственно в RISC-V ОС. Рассмотрим три основных способа создания RISC-V приложений в Syntacore Kit

    Создание приложений в терминале RISC-V ОС

    При данном способе и редактирование исходного кода, и его компиляция происходит в RISC-V ОС. Для сборки своего первого приложения выполните следующие команды:

    $ cd ~/hello_world_test/ # Смена текущего каталога 
    $ gcc -o hello hello.c  # Компиляция программы (флаг -o задает имя исполняемого файла
    $ ./hello # запуск программы
    

    В случае успешного выполнения в терминале должна отобразится строка "Hello from RISC-V". Обратите внимание, что вы можете создавать новые программы или редактировать пример с помощью предустановленных текстовых редакторов в командной строке nano, vim и vi. Начинающим пользователям мы рекомендуем использовать nano.

    Создание приложений в терминале гостевой ОС

    Гостевая ОС имеет инструменты кросс-компиляции для сборки RISC-V приложений. Для начала работы в терминале создайте с помощью следующих команд файл hello.c:

    $ nano hello.c
    

    В открывшемся окне вставьте код программы выше с помощью буфера обмена. Затем нажмите сочетание клавиш CTRL + X (в английской раскладке). После чего, нажмите на клавиатуре Y (в английской раскладке) и клавишу Enter.

    #include <stdio.h>
    
    int main(void)
    {
        printf("Hello from RISC-V\n");
        return 0;
    }
    

    Далее выполните команду кросс-компиляции:

    $ riscv64-unknown-linux-gnu-gcc -o hello hello.c
    

    Эта команда вызовет специальную версию компилятора gcc, которая создает приложения RISC-V. По итогу ее работы, на вашей файловой системе будет создан файл ./hello. Однако, если вы попробуете запустить его в том же терминале, то вас ждет ошибка:

    $ ./hello 
    bash: ./hello: cannot execute binary file: Exec format error
    

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

    1.2.2.1 Запуск через qemu-riscv64

    В ряде случаев, для запуска и отладки программ на архитектуре RISC-V не обязательно запускать полноценную виртуальную машину с RISC-V ОС. В этих случаях можно использовать утилиту qemu-riscv64, которая обеспечивает запуск легковесной эмуляции для одной программы.

    Выполните следующую команду в терминале гостевой ОС:

    $ qemu-riscv64 -L "$RISCV/sysroot" ./hello
    

    Произойдет запуск и вы увидите сообщение "Hello from RISC-V". Флаг -L устанавливает предварительно настроенное окружение для корректной работы RISC-V программ.

    1.2.2.2 Копирование программы в RISC-V ОС

    В терминале гостевой ОС выполните команду копирования по ssh:

    $ scp ./hello riscv-debian:/home/debian 
    

    Данная команда создала копию исполняемого файла ./hello из гостевой ОС в каталоге /home/debian RISC-V ОС. Теперь откройте окно терминала RISC-V ОС и выполните команды

    $ cd ~
    $ ./hello
    

    Произойдет запуск и вы увидите сообщение "Hello from RISC-V".

    1.2.2.3 Создание приложений в Syntacore SC-IDE

    Для запуска Syntacore SC-IDE нажмите на ярлык №2 (Рис. 1.4). В появившемся окне выберите пункт меню File -> New -> C/C++ project

    (рис 1.4) Создание проекта в Syntacore SC-IDE

    На экране (Рис. 1.5) появится диалог "New C/C++ project" . В нем необходимо выбрать опцию "C Managed build" и нажать Next.

    (рис 1.5) Выбор типа сборки

    На следующем шаге (Рис. 1.6) введите имя проекта (1), выберите Project type как "Syntacore RV32/64GC ANSI C/C++ Project" и "RISC-V Cross GCC" (2 и 3)

    (рис 1.6) Настройки для работы с RISC-V

    На следующем этапе (Рис. 1.7) убедитесь, что установлена опция "64 bit XLEN".

    (рис 1.7) Базовые настройки проекта

    На следующем экране (Рис. 1.8) оставьте настройки по умолчанию и нажмите Next. На последнем экране выберите "Toolchain name" в соответствии с "RISC-V GCC/Linux (riscv64-unknown-linux-gnu-gcc)" и нажмите Finish.

    (рис 1.8) Настройки тулчейна проекта

    После этого (Рис. 1.9) у вас отобразится окно редактора файла main.c с кодом HelloWorld приложения. Для его запуска используйте команду

    (рис 1.9) Интерфейс запуска проекта

    Вывод запущенного приложения (Рис. 1.10) отобразится в нижней части среды разработки:

    (рис 1.10) Консоль запущенного приложения

    Обратите внимание, что помимо вывода самого приложения, выводятся также отладочные символы соединения с RISC-V ОС.

    1.2.3. Получение сведений об аппаратном обеспечении в Linux

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

    $ arch # Гостевая ОС
    x86_64
    
    $ arch # RISC-V ОС
    riscv64
    

    Расширенная информация о процессоре и ОЗУ содержится в procfs, в частности в /proc/cpuinfo и /proc/meminfo. С точки зрения ОС это текстовые файлы, содержимое которых можно вывести стандартными средствами (пример для гостевой ОС):

    $ cat /proc/cpuinfo
    processor	: 0
    vendor_id	: GenuineIntel
    cpu family	: 6
    model		: 142
    model name	: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
    stepping	: 9
    cpu MHz		: 2712.008
    ……
    
    ~$ cat /proc/meminfo 
    MemTotal:        2022664 kB
    MemFree:          177740 kB
    MemAvailable:     278060 kB
    Buffers:            6136 kB
    …..
    

    1.3. Задание к лабораторной работе

    Напишите программу на языке С, которая последовательно выводит информацию о процессоре (каждый пункт списка выводится в новой строке):

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

    Программу необходимо скомпилировать и запустить последовательно в гостевой ОС и в RISC-V ОС (либо через qemu-riscv64).

    1.3.1. Описание последовательности выполнения работы

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

    Далее необходимо составить универсальную программу, которая будет решать поставленную задачу вне зависимости от архитектуры процессора, под которую она скомпилирована. Авторы предлагают вынести в отдельные функции работу с /proc/cpuinfo и работу с командой arch. Обратите внимание на формат файла cpuinfo - каждое ядро процессора выводится отдельным блоком. Примеры кода можно посмотреть в разделе 1.2.

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

    1.3.2. Пример выполнения задания на защиту

    Напишите программу, которая считывает общий объем оперативной памяти компьютера.

    #include <stdio.h>
    
    int main(void)
    {
        FILE *meminfo = fopen("/proc/meminfo", "r");
    
        char line[256];
        while(fgets(line, sizeof(line), meminfo))
        {
            int ram;
            if(sscanf(line, "MemTotal: %d kB", ram) == 1)
            {
                fclose(meminfo);
                printf("%d", ram);
            }
        }
    
        fclose(meminfo);
        return 0;
    }
    

    1.4. Вопросы для контроля

  • Как в Syntacore Kit реализуется возможность запуска программ для архитектуры RISC-V?
  • В чем состоит назначение qemu-riscv64?
  • Как узнать размер кэш-памяти для одного ядра процессора в Linux?
  • Вернуться к учебному плану