unknown chipset

Если вы попали на эту страницу, то скорее всего у вас проблема с загрузкой вашего Linux дистрибутива, которая заключается в том, что вы видите ошибку содержащую слова «unknown chipset».

А так же у вас скорее всего видео карта NVIDIA и именно с ней связанна данная проблема. В противном случае вы вряд ли найдете для себя тут что то полезное.

Причина

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

Решение

Для того, что бы все же запустить вашу систему без данного драйвера (что бы в последствии установить то, что будет работать с вашей конфигурацией), можно воспользоваться «recovery mode», который обычно есть в большинстве дистрибутивов и находится в пункте «advanced options» загрузчика GRUB или в чем то подобном. Если же это не помогло (или такой пункт не был найден), то делаем следующее (для загрузчика GRUB):
* Находим в меню загрузчика пункт с проблемной осью и нажимаем e
* Появляется редактор в котором открывается конфиг загрузчика для загрузки этой системы
* Находим там строчку, которая начинается со слова linux
* Перемещаемся в конец этой строки и добавляем nomodeset nouveau.modeset=0 отделяя пробелом от содержимого

Этими действиями, мы заставляем наш загрузчик запустить наше ядро с параметром nomodeset nouveau.modeset=0 который должен отключить сей ненавистный драйвер. После этого система должна загрузиться. Останется только скачать нужный драйвер и установить его.

Примечание

Скорее всего параметр nomodeset nouveau.modeset=0 так и придется оставить в конфиге загрузчика (во всяком случае мне пришлось так сделать)

Может кому пригодится

switch case в Go

На первый взгляд, все стандартные элементы языка Go, такие как циклы или условные переходы, работают аналогично другим языкам. Однако, с операцией switch есть одна особенность, которая заключается в следующем: Если в других языках после каждого case необходимо было ставить break для того, что бы выйти из switch то в Go этого делать не нужно так как он по умолчанию выходит из case в который попал, и не проваливается в следующие. А вот для того, что бы провалиться в следующий блок case существует специальное служебное слово fallthrough. Но и на использовании fallthrough есть некоторые ограничения. В то время как break можно было указывать в любом месте блока case (не обязательно в конце или в других блоках, таких как if) fallthrough необходимо указывать только в самом конце и не вкладывать в другие блоки, в противном случае код считается не валидным.

Самостоятельная статическая линковка Go и C

Введение

В языке C процесс создания выполняемого файла проходит следующие этапы:
1. обработка препроцессором
2. Компиляция файлов в объектные файлы
3. Линковка (объединение) скомпилированных объектных файлов в исполняемый файл

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

Получение объектных файлов C

Для того, что бы получить объектный файл программы написанной на C нужно передать ее компилятору с соответствующим параметром, в случае gcc это -c

gcc -c main.c -o main.o

Получение объектных файлов Go

Для того, что бы объектный файл получить из кода написанного на го нужно к параметру build указать дополнительную опцию -buildmode=c-archive

Линкова

После того как оба файла будут готовы остается их слинковать тем же ggc

gcc main.o test.a -pthread -o main

Примечание

Любая программа на го имеет в себе некоторый оверхед в виде сборщика мусора и других полезных вещей, некоторые из них работают в отдельном потоке. По этому, для того, что бы слинковать файлы среди которых есть объектные файлы полученные из исходников программы на Go необходимо включить объектные файлы реализующие функционал работы с потоками. Именно по этому нужно так же добавить параметр -pthread

Пример

Разница между массивом и слайсом в Go

Введение

Основная разница:
массив — это структура которая хранит в себе некоторое количество элементов одного типа, и как следствие одного размера. Такая структура всегда занимает место равное размеру одного элемента помноженного на количество элементов. Память под такую структуру выделяется сразу же в зависимости от количества элементов которые нужно разместить. Для того, что бы изменить размер массива, нужно выделить другую область памяти под другое количество элементов и скопировать туда нужные элементы. Обращение к такому элементу всегда осуществляется по адресу, которое вычисляется путем умножения номера нужного элемента на размер одного элемента и добавление этого значения к адресу первого элемента (который так же считается адресом самого массива, именно по этому в этой структуре обязательна фиксированная длина элемента.

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

Объявление

разница объявления массивов и слайсов заключается только в том, что в случае слайса в квадратных скобках не указывается длина слайса

Примечание

  • функция append() всегда работает только со слайсами
  • разные слайсы могут ссылаться на один и тот же массив, что может привести к изменению элементов в двух слайсах одновременно при попытке изменить элемент только в одном
  • Так как в Go все передаваемое в функцию копируется, то копируется и сама структура слайса, но из за того, что сам слайс не хранит данных а только ссылается на массив с данными, получается что передача слайса происходит по ссылке так как этот слайс содержит ссылку

Загрузка Linux

Загрузку OS Linux можно разделить на несколько Этапов.

Работа BIOS

Первым делом BIOS анализирует один из жестких дисков которые у него прописаны в качестве устройств для загрузки. Он пытается найти на нем таблицу разделов MBR и прочитать от туда первые 512 байт в которых написана информация по разделам на этом диске, а так же что делать дальше и кому стоит передать управление. Так как в 512 байтах особо много логики и возможностей не разместить эта часть диска используется только для хранения кода который способен просто передать управление чему то другому, в данном случае более функциональному загрузчику. Таким загрузчиком может быть GRUB. Этот код из 512 байт загружает код загрузчика GRUB в оперативную память и передает ему управление. Собственно сам GRUB при установке записывает дополнительно код загрузчика в те самые 512 байт. Так что в некотором смысле этот код тоже является частью загрузчика GRUB

Работа загрузчика GRUB

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

Для того, что бы GRUB смог загрузить Linux ему необходимо следующее:

  1. Номер устройства (диска) с которого нужно брать необходимые файлы

  2. Само ядро операционной системы

Ядро операционной системы Linux представляет из себя один файл размером примерно в 5 — 8 Mb и находится в директории /boot. Этот файл может называться по разному, но обычно, он либо называется либо имеет название linux, linuz иди vmlinuz. По мимо этого в названии может присутствовать версия самого ядра, к примеру: linuz-4.10. Буква z обозначает что код ядра был предварительно сжат.

  1. образ системы

Так как в этом файле нет ни каких драйверов устройств, это приводит к тому, что если просто загрузить в оперативную память ядро и передать ему управление оно не сможет дальше ничего сделать, так как не сможет работать ни с одним из устройств или жестких дисков. По этому, для того, что бы решить эту проблему, подготавливается специальный образ системы, который содержит в себе необходимые модули и другие компоненты для нормального функционирования ядра. Обычно этот файл называется или имеет в названии initrd. Он весит от 10 — 20 Mb и располагается там же в /boot

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

Работа ядра

После того как ядро получило управление оно получает доступ к образу системы, которое для него было загружено загрузчиком в оперативную память из файла initrd и монтирует это как корневую директорию. затем ядро передает управление уже самой операционной системе. Для этого оно запускает один единственный процесс которые называется init и обычно расположен в /bin/init. Этот процесс получаете PID равный 1 и проводит всю остальную инициализацию системы.

Работа init

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

Создание загрузочной USB флешки с GRUB

Введение

Обычно, вся память флешки представляет из себя один единственный раздел без таблицы разделов. Для того что бы она стала загрузочной необходимо:
1. создать на ней таблицу разделов MBR
2. Сделать один раздел загрузочным
3. установить загрузчик

Создание таблицы разделов и загрузочного раздела

$ sudo fdisk /dev/sdb

o -> Создать таблицу разделов MBR
n -> создать новый раздел
a -> установить раздел загрузочным
w -> записать изменения и выйти

Форматирование раздела

$ sudo mkfs.ext4 /dev/sdb1

монтирование раздела

$ sudo mount /dev/sdb1 /mnt/

Создание директории для загрузки

$ mkdir /mnt/boot

установка GRUB на флешку

$ sudo grub-install --boot-directory=/mnt/boot /dev/sdb
Указывается директория где будет лежать сам загрузчик и сама флешка в которую нужно будет поместить код загрузчика в первые 512 байт согласно спецификации MBR для того что бы передать управление GRUB’у

Итог

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

Перенаправление портов через ssh

Введение

Перенаправление портов бывает двух типов:

  • Local Port Forwarding
  • Remote Port Forwarding

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

Для установки локального или удаленного перенаправления используется команда ssh с параметром -L или -R соотвественно. После него указывается значение вида <локальный порт>:<адрес назначения>:<порт назначения>, а затем указывается адрес хоста.

Пример 1

Если на удаленном хосте server.ru запущена, например, база данных MySQL, а доступ извне на эту машину по порту 3306 закрыт, но есть доступ по SSH, то для подключения можно перенаправить этот порт следующим образом:

sudo ssh -L 3306:localhost:3306 user@server.ru

В этом случае весь трафик локальной машины на адрес localhost:3306 будет перенаправлен на localhost:3306 удаленного хоста server.ru

Пример 2

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

sudo ssh -R 2222:localhost:3333 user@server.ru

В этом случае все, кто будут обращаться к server:2222 на самом деле будут перенаправлены на localhost:3333 вашей локальной машины.