LINUX.ORG.RU

Избранные сообщения LeNiN

Мои мысли про kubernetes

Форум — Talks

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

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

Кратко что это вообще такое

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

  1. Объединяет несколько разных компьютеров в один логический кластер.

  2. Позволяет создавать и запускать контейнеры. Сильно похоже на docker-compose, но k8s позволяет не указывать конкретный компьютер, на котором будет запущен контейнер, а сам его выбирает.

  3. Обеспечивает виртуальную сеть между всеми контейнерами в пределах кластера, обеспечивает т.н. service discovery, а также обеспечивает балансировку нагрузки междду сервисами внутри этой виртуальной сети. Т.е. я могу во-первых в своей программе по днс-имени postgres-1 узнат IP-адрес первого контейнера с постгресом, а во-вторых по днс-имени postgres-ro получить дважды виртуальный IP-адрес, при соединении на который моё соединение уйдёт на случайный инстанс постгреса.

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

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

На самом деле современный k8s работает не поверх докера, а поверх легковесной абстракции CRI и её реализации обычно в виде containerd, но это частности

Кому это надо и какие альтернативы

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

Альтернативы я знаю следующие:

Hashicorp Nomad. Штука похожая на k8s, но гораздо менее распространённая. По слухам настраивать гораздо проще. Сам не пробовал. Я человек мейнстрима и выбираю то, что выбирает большинство.

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

Проприетарные облачные решения. У всех крупных вендоров они есть. К примеру AWS Fargate. Главный минус: ваше приложение будет прибито гвоздями к этому вендору. Съехать с него малой кровью не получится.

Ценность kubernetes вижу в следующем:

  1. Независимость от вендора. У каждого облака есть managed kubernetes. И хотя детали у них отличаются, но всё же сам kubernetes один и тот же. Переехать с одного облака на другое не намного сложней, чем переехать с Debian на RHEL.

  2. Опция селф-хоста. Если ни одно облако не нравится, всегда есть опция купить ящик с SuperMicro и поставить всё туда.

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

Как это использовать

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

Если своими силами поднимать кластер, надо понимать, что для кластера имеются следующие требования:

  1. Кластеру нужен балансировщик нагрузки. Это когда у вас есть публичный IP-адрес, и N адресов. И соединения, приходящие на этот публичный адрес будут равномерно распределяться на эти N адресов. Балансировщик нагрузки должен мониторить доступность клиентов и вовремя включать/выключать их.

  2. Кластеру нужно сетевое хранилище. Это когда вы можете какой-то сетевой диск подключить к любому (одному) компьютеру и потом в линуксе он должен появиться, как /dev/sdc.

Первый пункт можно сделать самому через haproxy. Но не очень просто, если делать по уму (отказоустойчиво). Ну крутые дядьки, наверное, чем всякие там cisco такое могут делать вообще уровнем ниже, с резервированием на уровне проводов. Впрочем у них и грохается всё круто.

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

Также можете тупо дать каждому серверу публичный адрес и все их вбить в DNS с коротким TTL. Не знаю, можно ли считать это балансировкой нагрузки, но с какими-то оговорками работать будет… Ну это так, из разряда дёшево и сердито.

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

Обе проблемы легко решаются, если вы своими силами поднимаете кластер, используя облачного провайдера, который предоставляет вам вышеописанные сервисы. Я именно так и делаю: мой провайдер использует OpenStack и Ceph и балансировщик нагрузки с сетевыми дисками у него доступен (под капотом балансировщик нагрузки это тупо две виртуалки с haproxy, но для меня это не важно).

Ещё с сетевыми дисками важно, чтобы был CSI-драйвер для них. Для OpenStack такой есть. Т.е. kubernetes должен этому драйверу отдавать команду «подключи мне диск pvc-7672ffed-9ddc-4df4-affd-a717a1c11c79 на сервер 10.160.3.160» а драйвер должен отвечать «смонтировано в /dev/sdg».

Для своего кластера есть следующие подходы:

  1. kubeadm. Это набор софта от разработчиков kubernetes, который устанавливает и обновляет компоненты кластера. Я использую этот подход. Под низом стоит обычный линукс. У меня это debian minimal. Проблем с ним я не испытывал. Вообще народ обычно убунту использует, меня от неё воротит. По идее можно и на центоси, есть и более экзотичные варианты вроде CoreOS, я не вижу смысла тут использовать что-то необычное.

  2. Talos Linux. Это офигенная штука: ядро линукса плюс необходимый набор софта плюс сам кубернетес. Это всё идёт как один ISO и грузится в память. Ему даже диск не нужен. И сразу работает. Короче это по сути kubernetes как ОС. Я слишком поздно про него узнал, вероятно я бы его предпочёл. Надо понимать, что штука относительно новая и экзотичная, но я от него в восторге. По крайней мере в концептуальном восторге, может на практике вылезут нюансы.

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

  4. Kubernetes the hard way. Это когда ты руками всё настраиваешь сам, ставишь каждый компонент и тд. В целом ничего сверхъестественного тут нет, весь kubernetes это несколько сервеных программ плюс кучка настроек для них вроде своего УЦ с сертификатами и прочим. Но это ненужное усложнение и оправдано только для изучения потрохов. Сам я его не делал и страданий от этого не испытываю. В общем что-то вроде Linux From Scratch.

Управляемые решения я сам не использовал. В целом они решают некоторые проблемы и добавляют свои. Самый главный плюс управляемого решения: хостер будет сам управлять серверами. К примеру при росте нагрузки хостер сам создаст дополнительные серверы, установит туда k8s и добавит их в кластер. При снижении нагрузки он эти серверы выведет из кластера и уничтожит. Это называется node autoscaling. В моём кластере такого нет. В принципе это можно и самому сварганить, если снизу инфраструктура с каким-то API, которая позволяет создавать и удалять серверы. Но это нетривиально и требует программирования.

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

Неочевидные преимущества Kubernetes

Первое преимущество Kubernetes похоже на преимущество докера, которое я не сразу осознал. В докере помимо технологии есть ещё и коммьюнити. Это тысячи людей, которые собирают готовые пакеты. Если мне нужен postgres или wordpress или ещё что угодно, скорей всего это кто-то уже собрал. И даже если я решу собирать свой образ, я как минимум смогу посмотреть на чужие докерфайлы, а скорей всего мне хватит чужих. Это экономит много времени и сил. В кубернетесе похожая тема: для него создано куча софта и деплойментов, которые позволяют в пару строк деплоить в кластер довольно сложные конфигурации. К примеру прометей, собирающий метрики, локи, собирающий логи, ещё кучка вспомогательных агентов и графана, уже настроенная на отображение всего этого, ещё и с кучей готовых дашбордов, которые не стыдно директору показать. Почти для любого софта, который я хочу запустить в своём кластере, есть хельм от производителя, в котором всё уже прописано. И даже если я решу писать дескрипторы сам, я в этот хельм смогу посмотреть.

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

Третье преимущество в том, что есть некоторые уникальные софтины. К примеру я пускаю БД в кластере. БД управляется через оператора. Оператор это такая программа (которая тоже запущена в кластере) которая создаёт контейнеры с БД, настраивает их как надо и как бы следит за ними. К примеру я буквально несколькими строчками настроил запуск постгреса в двух копиях с периодическими бэкапами в S3 и постоянными бэкапами wal-логов туда же. В итоге имею high-available СУБД кластер с бэкапом и возможностью откатиться с гранулярностью в 5 минут. Руками такое настраивать я бы наверное несколько дней минимум потратил. Понятно, что если сломается, то в общем случае для починки придётся разбираться что там как устроено. Ну пока не ломалось. Может и не сломается.

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

Недостатки Kubernetes

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

  1. Требования к железу. Для полноценного высокодоступного кластера требуется три сервера по 4GB RAM и 2 CPU, которые будут использоваться исключительно для Kubernetes (мастера). Также на каждом рабочем сервере нужно зарезервировать примерно 20% оперативной памяти. Также Kubernetes до недавнего времени не работал со свапом, а с недавнего начал работать в экспериментальном виде, но про это никто не пишет и не знает. В общем можно считать, что свопа нет. Для крупных проектов эти требования не очень существенны, если же весь ваш проект это 2GB VPS за $5, то kubernetes вам не подойдёт. Нужно свой бюджет расширять хотя бы до 8GB за $20.

1.1. А ещё желательно иметь два кластера. Один тестовый, а один боевой. И тестировать свои эксперименты на тестовом. Лично у меня такой возможности нет, я работаю в компании, которая экономит на всём, и $300 в месяц на тестовый кластер это дораха. Поэтому я написал нужные terraform скрипты и прочее, что позволяет мне поднимать тестовый кластер за 15 минут, а потом опускать его. Но лучше не экономить на спичках и держать два одинаковых кластера.

  1. Требования к квалификации. Для того, кто с k8s не работал, там всё будет новое. И хотя ничего особенно сложного там нет, но объём знаний всё же существенный. В целом готовьтесь потратить несколько месяцев на изучение и работу с тестовым кластером. Не вздумайте сходу переводить прод на k8s, если он нужен кому-то кроме вашей мамы. Также надо понимать, что kubernetes очень плотно работает с линуксом. cgroups, iptables, ebpf - эти слова не должны вводить вас в ступор (ebpf меня в ступор вводят, в частности поэтому я отказался от cilium).

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

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

  1. В нём «из коробки» нет многого, что можно было бы ожидать от него. К примеру есть ингрессы (это описание входных точек для внешних сервисов), но ингресс-контролера нет, нужно выбирать и ставить, а их, между прочим, штук 15 разных. Да что там ингресс-контролер, там даже этой самой вышеописанной виртуальной сети нет, есть только некие интерфейсы, а реализацию, которая будет эту сеть «настраивать» - надо ставить самому (собственно это первое, что вы будете ставить в только что созданный кластер). Причём этих реализаций опять же штук 10 разных. И муки выбора - flannel, calico, а может модный cilium, а вот тут на реддите ещё про что-то писали, ааа, вот это при некотором складе характера может мучить. Меня мучает. Я боюсь сделать неверное решение. Если что, я выбрал ingress-nginx и calico для вышеописанных пунктов, как наиболее понятные и консервативные решения. Не жалею.

  2. Он провоцирует ставить и настраивать то, что вам в общем-то не особо и надо. Ну вот жили мы с докер-композом, проставляли реплики в конфиге руками и ладно. А тут вроде есть horizontal pod autoscaler, который будет в зависимости от нагрузки запускать больше или меньше реплик, круто же. А для него метрики нужны, надо ещё компонент для метрик поставить. А вот про istio прочитали, он вообще даёт возможность смотреть все запросы между сервисами, а-а-а, это же просто огонь. В общем вроде и не сказать, что это плохо, т.к. это всё даёт лишние возможности, но всё же тут важно не увлекаться. Может оно вам не так уж и надо, раз жили без этого. Каждая софтина это время на изучение документации, это постоянные затраты времени на чтение ченджлогов, обновления, обновления конфигов. А если это ещё и штука вроде istio, которая не сбоку-припёку, а влезает прям между вашими сервисами, то это ещё и потенциальная причина того, что всё сломается и вам придётся ковыряться в ихних кишках в самое неудачное время. Ну и ресурсы тоже каждая софтина требует, ага. Вроде и всё на го написано, вроде и не ресурсоёмко по большому счёту, но потихоньку набегают гигабайты…

  3. Несмотря на то, что я выше написал про докер, на самом деле с самим докером он плохо совместим. И если вам хочется сделать такую простую и понятную штуку, как запуск вашего CI в кластере - типа коммит прошёл, теперь надо docker build сделать, вот это простое желание на самом деле таит в себе столько нюансов, что я в итоге отказался от этого желания и для CI завёл тупо отдельный сервер с докером.

  4. Кубернетес из коробки адски небезопасен. Легко создать под, в котором будет подмонтирован корень вашего сервера. И удалить там всё, азаза. При этом, конечно же, есть все возможности закручивать гайки сколько угодно, но это надо делать. Когда пишешь helm install, обычно оно ставится от cluster-admin и в общем случае может делать с кластером что угодно. Если у вас отдел девопсов, которые там каждый ямл обнюхают и будут это делать каждую неделю, ставя новую версию, ну классно. А если весь ваш девопёс это я, занимающийся этим, когда других задач нет, и джуниор, который сам всё поломает, только доступ дай, то не классно. Поэтому см. пункт выше про отдельный тестовый кластер.

  5. Гитопс. Гитопс это круто и здорово, но я так и не впечатлился. В общем не рекомендую. С одной стороны - да, весь ваш кластер должен лежать у вас в гите, а не в голове и при необходимости подниматься несколькими командами (или несколькими десятками команд, не принципиальная разница, у меня второй вариант). С другой стороны внедрять прям 100% гитопс, когда вам реально надо коммитить в гит, чтобы там что-то срабоатло, я долго пытался это делать на flux, я его неплохо изучил, но в итоге отказался. Опять же если у вас отдел девопсов, которые будут там друг друга ревьюить и мерджить, то наверное ок. Если вам нужно держать не один кластер, а сто кластеров, развернутых и обновляемых из одного репозитория, то конечно ок (хотя тогда вы сами меня учить будете, а не читать это). А если вас один-два человека, ну я решил, что оно не надо. У меня весь репозиторий это terraform-шняга, которая просто создаёт серверы, на этих серверах через cloud-init при создании ставится containerd, kubelet и прочая ерунда, потом я туда по ssh захожу и вбиваю kubeadm join и всё. Это инфраструктура. Второй репозиторий это во-первых кучка скриптов (в основном helm update, чтобы не запоминать это всё), во-вторых кучка kustomize-ов, которые уже ставят либо то, что в helm не обернули (или я не захотел этим пользоваться), либо, собственно, тот софт, ради которого весь этот кластер вообще существует.

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

ports:
  - name: http
    containerPort: 3100

вместо

ports:
  http: 3100

или вся эта копипаста

spec:
  selector:
    matchLabels:
      app: loki
  template:
    metadata:
      labels:
        app: loki
    spec:
      containers:

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

  1. Также из коробки поставленный через kubeadm кластер не стабилен и сервер легко роняется одним подом, который решил сожрать всю память (у меня сервер просто перестал отвечать, где там были все эти ваши оом киллеры, я не знаю). Это меня неприятно удивило. А чтобы сделать его стабильным, мне потребовалось потратить не один час на чтение документации и разного рода настройки (в основном резервирование памяти для кублета, системы и тд). Что мешает kubeadm-у прописывать лимиты самому, я не понимаю.

  2. Если у вас три сервера, один сервер упал и вы ожидаете, что кубернетес в ту же секунду, радостно повизгивая, побежит перезапускать все поды на других серверах, то вы сильно ошибаетесь. Во-первых он вообще не сразу поймёт, что сервер упал. Во-вторых он ещё минут 5 подождёт. Ну вдруг тот не упал, а просто устал немножко и присел отдохнуть. Про 5 минут не уверен, кстати, может быть даже 15 минут, сорри, лень смотреть. В общем, как говорится, eventually он таки - да, перезапустит поды на других серверах. Но к вам за это время уже успеют прибежать и наорать, что ничего не работает.

Поэтому high availability это все ваши сервисы, запущенные в двух копиях минимум. Иначе это eventual availability. Что тоже неплохо и лучше, чем unavailability.

Вышеописанные таймауты можно настроить, если что. Но, наверное, не нужно. Я не стал.

Из этого, кстати, вытекает 12. Настроек очень много. Туториалов о том, как эти настройки настраивать - ещё больше. И на ютубе и в тексте. А вот какие значения нужно проставлять, какие плюсы, какие проблемы - тут все резко затыкаются.

  1. Будьте готовы читать много кода на go, копаться в исходниках и issues. Ну может мне так повезло или у меня такой стиль решения проблем. Но такого, как в традиционном линуксе - когда почитал man iptables или IPTABLES HOWTO и нашёл ответы на все вопросы - тут часто не получается. Какая-то мелкая, но нужная софтинка. В доке ничего не понятно, приходится лезть в исходники и смотреть - что там на самом деле. Или гуглишь - ничего релевантного. Залазишь в гитхаб issues, ищешь там и, таки, находишь ответ на свой вопрос.

 ,

vbr
()

Наконец-то консоль с GNU/Linux из коробки

Галерея — Рабочие места

Само собой это давно уже не новость, но довольно прикольно кроме консоли заполучить полноценный рабочий компьютер с GNU/Linux на борту.

Из минусов: придётся освоить flatpak (pacman что-то не работает, точнее работать, но поставить с помощью него ничего не получается), про локализацию тут конечно слышали, но похоже не думали, как и про терминал, который конечно есть, но с каким-то fish.

Из плюсов: работает таки из коробки, emacs установить можно. Больше плюсов появится когда со всем этим удастся разобраться получше.

Спойлер: это я про Steam Deck + Docking station тут всё понаписал.

Внешний монитор от Uperfect (держалка от Armmedia), клавиатура и мышка от Logitech, что-то вроде колонок в tws-режиме от xiaomi. Да, как игровая приставка Steam Deck само собой работает.

>>> Просмотр (4032x3024, 2762 Kb)

 

Evgueni
()

А как Proxmox монтирует mountpoint (второй «диск») к контейнеру? Не вижу настроек.

Форум — Admin

Если создать unprivileged контейнер в вебморде и на этапе настройки указать второй диск, то никаких проблем. А вот ручками создал thin том, примаунтил через конфу и denied. Понятно, unprivileged, bla-bla-bla. А вопрос не о том, а как Proxmox так делает по дефолту, что ни в конфигурации контейнера, ни во всяких subuid никаких следов и всё работает? Тоже так хочу, без этих заморочек с маппингом.

PS Правда я в конфе size не указал, но не из-за этого же denied

 , ,

TepakoT
()

[жж] словил сбойные сектора на nvme ssd

Форум — General

Дорогой Уважаемый ЛОР,

Я словил первое в своей жизни проявление сбойных секторов на SSD. Пациент — Samsung SSD 970 EVO 2TB с прошивкой 2B2QEXE7, в эксплуатации примерно год. Пару-тройку дней назад мне почему-то захотелось сделать копию вообще всех данных из домашней директории, включая файлы, которые легко скачать из сети при надобности. Некоторые из этих файлов лежали там с момента миграции на накопитель, без обращений. И при копировании одного из таких файлов программа сказала: «А я, кажись, чот не могу». После того, как потихоньку пришло осознание произошедшего, я глянул в лог и увидел там:

blk_update_request: critical medium error, dev nvme0n1, sector 313199872 op 0x0:(READ) flags 0x80700 phys_seg 8 prio class 0

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

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

За время тестов в логи свалилось 546 строк с «blk_update_request: critical medium error», но ошибки иногда сыпались так часто, что в сумме набралось 888 «callbacks suppressed». В статусе накопителя написано, что ошибок доступа к носителю было 1484. Так как в логи основной системы не попало происходившее на LiveUSB, можно считать, что числа сходятся. К сожалению, не помню, были ли там ошибки до недавних событий. Всего различных сбойных секторов было 167 штук.

В данных из плохих секторов нашлись обрывки Packages из Debian. Судя по версиям пакетов, эти куски из очень старых Packages, возможно ещё из 2016. Если это так, они приехали во время миграции на накопитель, и с тех пор не перезаписывались и не читались. Один кусок оказался очень похож на файл переводов и нашёлся в /usr/share/locale/gl/LC_MESSAGES/coreutils.mo, который конечно же ни разу не читался с момента последней переустановки пакета coreutils в начале августа 2019.

smartctl:

=== START OF SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

SMART/Health Information (NVMe Log 0x02)
Critical Warning:                   0x00
Temperature:                        41 Celsius
Available Spare:                    100%
Available Spare Threshold:          10%
Percentage Used:                    1%
Data Units Read:                    162 937 114 [83,4 TB]
Data Units Written:                 65 584 401 [33,5 TB]
Host Read Commands:                 691 234 670
Host Write Commands:                544 796 594
Controller Busy Time:               3 278
Power Cycles:                       719
Power On Hours:                     2 249
Unsafe Shutdowns:                   82
Media and Data Integrity Errors:    1 484
Error Information Log Entries:      1 783
Warning  Comp. Temperature Time:    0
Critical Comp. Temperature Time:    0
Temperature Sensor 1:               41 Celsius
Temperature Sensor 2:               42 Celsius

Error Information (NVMe Log 0x01, max 64 entries)
No Errors Logged

Терабайт тридцать-сорок я добавил чтением накопителя во время тестов.

Думаю, из произошедшего можно сделать, как минимум, следующие выводы:

  • полгода без чтения страницы на SSD достаточно для последующих ошибок чтения;
  • чтение такой страницы не заставляет SSD подменять страницу на новую, он с радостью выдаёт ошибку чтения на одном и том же месте много раз подряд;
  • trim не означает очистку всех неиспользуемых блоков ФС, они же меньше страницы. Некоторые данные могут жить в закоулках годами;
  • SSD желательно периодически прочёсывать чтением, чтобы словить сюрпризы пораньше;
  • если такое происходит на TLC 3D V-NAND, страшно подумать, что будет на QLC.

Upd.
Узнал, что в NVMe есть фича 0x10, которая управляет температурами, при которых SSD должен начать тормозить для снижения нагрева. Правда для 970 EVO эти температуры дожны быть в диапазоне 80–82 °C, а попытка установить любые значения кроме 0 для фичи 0x10 завершаются неудачай.


Upd. 11 мая 2021, то есть примерно через год и два месяца после первого раза, появились новые ошибки чтения. При повторном чтении тех же мест ошибки повторялись, но через некоторое время пропали.


Upd. 5 июня 2021. Аккумулятор оказался вздут в той секции, что прилегает к SSD. Видимо, предупреждение о температурном лимите в 65°C на аккумуляторе написано не просто так.


Upd. 20 февраля 2022. Накопитель отправился на пенсию.

 , , , , ,

i-rinat
()

SSD изнашиваются от чтения?

Форум — Linux-hardware

Привет, ЛОР:) Есть мнение, что при чтении со временем падает заряд ячейки и контроллер её перезаписывает.

Ваши мысли или пруфы?

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

Ширпотребный диск на 500 Гб.

Оффтор. Ещё говорят SSD надо подзаряжать раз в 3 месяца. За 2 года бездействия ничего не пропало :)

Важное дополнение: файловой системы нет, блоки читаются напрямую с диска, соответственно noatime и т.п. неактуальны. Определенная программа только 1 раз записывает нужный объем информации (около 100 Гб) и далее только читает на максимальной скорости. Больше никакой записи нет!

Перемещено hobbit из general

 , ,

NotWin
()

Посоветуйте видеокарту с хорошей поддержкой для линукса

Форум — Linux-hardware

Посоветуйте видеокарточку-затычку, а то моя HD7970 нехорошо себя ведет, думаю долго не протянет. Из игр может буду играть в игры на движке RPGMaker и Crusader Kings 2, и Oblivion. Бюджет 5000-10000. Желательно чтобы поддерживалось апаратное ускорения для видео в браузере для такой карточки. Пока думаю над тем чтобы взять AMD Radeon R7 240.

 

vbcnthfkmnth123
()

mc-4.8.29::gentoo

Форум — General

Прилетело мне значит обновление.
mc.ext он по моему вообще не читает.
Открыл /usr/libexec/mc/ext.d/sound.sh
Вообще ничего не пойму чё в нём писать.
У меня вот по старому для mp3 было
Open=/usr/bin/mpv -ao alsa --no-video %s
Как по новому сделать?

 , ,

koxoho4192
()

Device Tree + два расширителя портов

Форум — Linux-hardware

Всем привет!

Начинаю описывать dt[s|b] для железки на которой планируется запустить Linux. Ранее я только правил готовые решения, а тут прям всё с ноля.

Вот читаю и не могу понять получится ли у меня такое или нет...
Смысл такой, у меня есть 2 (два) расширителя портов по i2c шине. В частности pca9554, но их прерывания соединены в одно и висят по факту на одной ноге процессора.

Судя по инструкции на модуль, каждому такому блоку можно описать «внешнее» прерывание:

gpio@20 {
    ...
    interrupt-parent = <&gpio3>;
    interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
}


Так собственно вопрос, а можно указать одно и то же прерывание двум блокам? Будет ли это «работать»?

 ,

Spider55
()

где вы берете эти ваши торренты?

Форум — Talks

Я вылез из криокамеры и понял что хочется че то посмотреть, есть умный телевизор ми какой то там и проживание в РФ.

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

Поставил себе ktorrent по старой памяти, пытаюсь закачать - большая часть торрентов нерабочая (нет никого на раздаче). Как это сейчас делается и делается ли вообще?

ЗЫ воткнул в телевизор флешку с .avi файлом - он сказал что такое показывать не умеет. Совсем опечалился, придется его как то цеплять к ноуту что ли…

 ,

AntonI
()

Вопрос о кеше Transmission

Форум — General

Система - на SSD, в настройках transmission папка для сохранения - на HDD.

Вопрос: использует ли transmission как-то SSD в данном случае? Может кеширует, например, не знаю.

 , ,

devorg
()

Порекомендую хорошую книгу по электронике

Форум — Talks

Practical Electronics for Inventors. Купил, читаю и очень доволен. На английском языке. Вроде есть русское издание от BHV, его не читал. Объясняется очень доступно, без заумностей. Но в то же время с нужными формулами, есть разделы, где объясняется физика явлений для желающих. Английский довольно простой, я его знаю так себе, но проблем с чтением не возникло.

Оно продаётся в электронном виде, если денег жалко, наверняка есть рипы на торрентах. У меня версия с DRM, к сожалению поделиться не смогу.

 , ,

Legioner
()

вопрос по скриптам компоновщика для arm

Форум — Development

Вот есть скрипт компоновщика:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
MEMORY
{
    ROM  (rx) : ORIGIN = 0x08000000, LENGTH = 64K
    RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
}

SECTIONS
{
    .isr_vector ORIGIN(ROM) :
    {
        KEEP(*(.isr_vector))
    } >ROM
    
    .text ALIGN(4) :
    {
        *(.text*);
    } > ROM
    
    
    .common ORIGIN(RAM) (NOLOAD) :
    {
        *(COMMON)
    } >RAM
    
    .bss ALIGN(4) (NOLOAD): {
        PROVIDE(__bss_start__ = .);
        *(.bss*)
        PROVIDE(__bss_end__ = .);
    } > RAM
    
    .data ALIGN(4):
    {
        PROVIDE(__data_start__ = .);
        *(.data*)
        PROVIDE(__data_end__ = .);
    } > RAM AT>ROM
    
    PROVIDE(__data_lma__ = LOADADDR(.data));    
    PROVIDE(__stack_top__ = ORIGIN(RAM) + LENGTH(RAM));
}

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

А вот часть кода , который использует эти переменные ,чтобы перенести значение из флеша в оперативу:

extern uint8_t __data_start__, __data_end__, __data_lma__, 
   __bss_start__, __bss_end__;
 
uint32_t *dst;
dst = &__bss_start__;
while (dst < &__bss_end__)
    *dst++ = 0;
dst = &__data_start__;
uint32_t *src = &__data_lma__;
while (dst < &__data_end__)
    *dst++ = *src++;

Как я понимаю, значение экспортируемых переменных - это адрес соответствующих участков памяти.

В строках 4, 5 объявляется указатель dst значение которого адрес переменной __bss_start__ . Вопрос: почему в цикле применяется одна операция разыменовавыния (*dst++), ведь таким образом мы получаем адрес который храниться в переменной __bss_start__, но дальше мы не обращаемся к памяти по этому адресу, а работаем с ним как с обычным числом. Почему здесь не (**dst++) ?

 , ,

Kito
()

Не получается выдать белый ipv6 с vpn сервера клиенту

Форум — Admin

Хостер отдаёт мне /125 подсеть. Шлюз хостера находится в /48. Конфиг systemd-networkd на сервере (касающееся ipv6):

[Match]
Name=ens3

[Network]
Address=2a0c::120/48
Gateway=2a0c::1

Конфиг wireguard:

[Interface]
Address = 2a0c::121/125
ListenPort = 5000
MTU = 1500
PrivateKey = xx

[Peer]
PublicKey = xx
AllowedIPs = 2a0c::122/128

net.ipv6.conf.all.forwarding=1

В ip6tables всё открыто.

$ ip -6 r s
::1 dev lo proto kernel metric 256 pref medium
200::/7 dev ygg proto kernel metric 256 pref medium
2a0c::120/125 dev wg6 proto kernel metric 256 pref medium
2a0c::/48 dev ens3 proto kernel metric 256 pref medium
fe80::/64 dev ens3 proto kernel metric 256 pref medium
fe80::/64 dev ygg proto kernel metric 256 pref medium
default via 2a0c::1 dev ens3 proto static metric 1024 pref medium
$ ip -6 a
ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 2a0c::120/48 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe2c:1d4b/64 scope link
       valid_lft forever preferred_lft forever
wg6: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 state UNKNOWN qlen 1000
    inet6 2a0c::121/125 scope global
       valid_lft forever preferred_lft forever

Конфиг WG клиента:

[Interface]
Address = 2a0c::122/125
PrivateKey = xx
MTU = 1500

[Peer]
AllowedIPs = ::/0
Endpoint = xx
PersistentKeepalive = 21
PublicKey = xx

В ip6tables всё открыто.

$ ip -6 r s
::1 dev lo proto kernel metric 256 pref medium
200::/7 dev ygg proto kernel metric 256 pref medium
2a0c::120/125 dev wg6 proto kernel metric 256 pref medium
2000::/3 via 2a0c::121 dev wg6 metric 1024 pref medium
fe80::/64 dev ygg proto kernel metric 256 pref medium
fe80::/64 dev eno1 proto kernel metric 1024 pref medium
$ ip -6 a
wg6: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1500 state UNKNOWN qlen 1000
    inet6 2a0c::122/125 scope global
       valid_lft forever preferred_lft forever
$ ping -6 2a0c::121
64 bytes from 2a0c::121: icmp_seq=1 ttl=64 time=47.5 ms
$ ping -6 2a0c::120
64 bytes from 2a0c::121: icmp_seq=1 ttl=64 time=46.9 ms (DIFFERENT ADDRESS!)
$ ping -6 2a0c::1
From 2a0c::121 icmp_seq=1 Destination unreachable: Address unreachable

Сервер:

$ ping -6 2a0c::1
64 bytes from 2a0c::1: icmp_seq=1 ttl=64 time=1.14 ms

При пинге клиентом 2a0c::1, сервер передаёт следующее:

# ip6tables -t mangle -A POSTROUTING -j LOG
$ journalctl -f -g 'SRC='
kernel: IN=wg6 OUT=ens3 MAC= SRC=2a0c:0000:0000:0000:0000:0000:0000:0122 DST=2a0c:0000:0000:0000:0000:0000:0000:0001 LEN=104 TC=0 HOPLIMIT=63 FLOWLBL=920934 PROTO=ICMPv6 TYPE=128 CODE=0 ID=14 SEQ=1

Ещё присутствует такое:
kernel: IN=ens3 OUT=ens3 MAC=00:00:00:00:00:00:00:00:00:00:00:00:00:00 SRC=fe80:0000:0000:0000:5054:00ff:fe2c:1d4b DST=2a0c:0000:0000:0000:0000:0000:0000:0001 LEN=72 TC=0 HOPLIMIT=255 FLOWLBL=0 PROTO=ICMPv6 TYPE=135 CODE=0
kernel: IN=ens3 OUT=ens3 MAC=00:00:00:00:00:00:00:00:00:00:00:00:00:00 SRC=fe80:0000:0000:0000:5054:00ff:fe2c:1d4b DST=ff02:0000:0000:0000:0000:0001:ff00:0001 LEN=72 TC=0 HOPLIMIT=255 FLOWLBL=0 PROTO=ICMPv6 TYPE=135 CODE=0

Prerouting при том же пинге:

# ip6tables -t mangle -A PREROUTING -j LOG
$ journalctl -f -g 'SRC='
kernel: IN=wg6 OUT= MAC= SRC=2a0c:0000:0000:0000:0000:0000:0000:0122 DST=2a0c:0000:0000:0000:0000:0000:0000:0001 LEN=104 TC=0 HOPLIMIT=64 FLOWLBL=920934 PROTO=ICMPv6 TYPE=128 CODE=0 ID=15 SEQ=1

Также без пинга есть это:
kernel: IN=ens3 OUT= MAC=33:33:00:00:00:12:00:00:5e:00:02:01:86:dd SRC=fe80:0000:0000:0000:327c:5e08:ae98:3c80 DST=ff02:0000:0000:0000:0000:0000:0000:0012 LEN=80 TC=224 HOPLIMIT=255 FLOWLBL=0 PROTO=112

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

 , , ,

stripwire
()

Арм64. Линукс десктоп готов для гика, из доступной андроид-тв.

Форум — Talks

Собственно имею что сказать. Немного подразобрался с проблемами, словом из бывшей андроид-тв S78 на Amlogic S922 стабильно работает на ядре 5.15 из гентушных сорсов. Да, я ещё не знаю, как в DTB сделать вайфай, но пока что есть: а есть довольно шустрый десктоп, 4гб хватает, если соблюдать цифровую гигиену. Программы все популярные для десктопщика есть, всё собирается на арме локально. Одних браузеров Мидори, Прозрение, Фэлкон, Кьютебраузер, но для ЛОРа, почты, вкшечки нетсурф-гтк хватает, и он не болеет жором оперативы. Видео 60фпс 1080р без проблем, с 30-40% макс. нагрузкой на ЦПУ. Игры есть, Супертукскарт, картинка красивая, ФПС-ов 30. Стратежки типа опенра, вот Опенмв попробовал, опенсценеграф собрался за:

Wed Nov 30 14:38:10 2022 >>> dev-games/openscenegraph-openmw-3.6_p20211017-r1
       merge time: 55 minutes and 36 seconds.
А сама игра:
Wed Nov 30 15:18:29 2022 >>> games-engines/openmw-0.47.0-r1
       merge time: 40 minutes and 19 seconds.
Игра без проблем вобще, думал на арме так не бывает. В зданиях ФПС-ы 60, на открытых локациях до 25-30 проседает, настройки не слабые. Зачем теперь нужен гроб x86-amd64, если со всем справляется штучка с ладонь размером?

 , , tv-box

burato
()

Пара вопросов про одноплатники

Форум — Linux-hardware

Да я уже задолбал с вопросами про железо для десктопа но тем менее. Денег нема поэтому решил попробовать крайний вариант. Но есть вопросы: Насколько они производительны - видеоролики в 1080p, монтаж, компиляция, игры? Насколько на них хорошо работает ванильный ~и не очень~ андроид? Расширяемость, энергопотребление? Звук? Какой вообще одноплатник взять?

 

Dumppper001
()

Me DevOps: пусть разработка будет комфортной

Статьи — Администрирование
Me DevOps: пусть разработка будет комфортной

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

( читать дальше... )

 , , ,

vvn_black
()

ARM ассемблер - не пойму, заинлайнилась ли функция?

Форум — Development

Пишу под STM32 (BluePill).

Есть вот такая функция:

__attribute__((always_inline, section(".ramfunc")))
uint16_t readAddressBus()
{
    // Для ускорения адрес вначале считается 32-х битным чтобы проще работать
    // с 32-х битным регистром PA, и только в конце он один раз преобразуется в 16 бит
    uint32_t addr = 0;

    // Установка на мультиплексоре сегмента адреса 00
    GPIOB->BSRR = 0 | (GPIO_BSRR_BR3_Msk | GPIO_BSRR_BR4_Msk );

    // Считывается и запоминается значение ножек сегмента 0
    addr = ((GPIOA->IDR & 0x0F00) >> 8);


    // Установка на мультиплексоре сегмента адреса 01
    GPIOB->BSRR = 0 | (GPIO_BSRR_BS3_Msk | GPIO_BSRR_BR4_Msk );

    // Считывается и запоминается значение ножек сегмента 1
    addr = addr | ((GPIOA->IDR & 0x0F00) >> 4);


    // Установка на мультиплексоре сегмента адреса 10
    GPIOB->BSRR = 0 | (GPIO_BSRR_BR3_Msk | GPIO_BSRR_BS4_Msk );

    // Считывается и запоминается значение ножек сегмента 2
    addr = addr | (GPIOA->IDR & 0x0F00);


    // Установка на мультиплексоре сегмента адреса 11
    GPIOB->BSRR = 0 | (GPIO_BSRR_BS3_Msk | GPIO_BSRR_BS4_Msk );

    // Считывается и запоминается значение ножек сегмента 3
    addr = addr | ((GPIOA->IDR & 0x0F00) << 4);

    return (uint16_t) addr;
}

Она вызывается из main loop:
__attribute__((noinline, section(".ramfunc")))
void mainLoop()
{
    ...
            // Нужно получить текущий адрес с ША
            uint16_t addr=readAddressBus();
    ...
}

В дизассемблере ARM это дело представлено таким образом:
Disassembly of section .ramfunc:

080004d0 <readAddressBus>:
 80004d0:	f44f 13c0 	mov.w	r3, #1572864	; 0x180000
 80004d4:	490d      	ldr	r1, [pc, #52]	; (800050c <readAddressBus+0x3c>)
 80004d6:	4a0e      	ldr	r2, [pc, #56]	; (8000510 <readAddressBus+0x40>)
 80004d8:	480e      	ldr	r0, [pc, #56]	; (8000514 <readAddressBus+0x44>)
 80004da:	610b      	str	r3, [r1, #16]
 80004dc:	6893      	ldr	r3, [r2, #8]
 80004de:	6108      	str	r0, [r1, #16]
 80004e0:	6890      	ldr	r0, [r2, #8]
 80004e2:	f3c3 2303 	ubfx	r3, r3, #8, #4
 80004e6:	0900      	lsrs	r0, r0, #4
 80004e8:	f000 00f0 	and.w	r0, r0, #240	; 0xf0
 80004ec:	4318      	orrs	r0, r3
 80004ee:	4b0a      	ldr	r3, [pc, #40]	; (8000518 <readAddressBus+0x48>)
 80004f0:	610b      	str	r3, [r1, #16]
 80004f2:	6893      	ldr	r3, [r2, #8]
 80004f4:	f403 6370 	and.w	r3, r3, #3840	; 0xf00
 80004f8:	4318      	orrs	r0, r3
 80004fa:	2318      	movs	r3, #24
 80004fc:	610b      	str	r3, [r1, #16]
 80004fe:	6893      	ldr	r3, [r2, #8]
 8000500:	011b      	lsls	r3, r3, #4
 8000502:	f403 4370 	and.w	r3, r3, #61440	; 0xf000
 8000506:	4318      	orrs	r0, r3
 8000508:	4770      	bx	lr
 800050a:	bf00      	nop
 800050c:	40010c00 	andmi	r0, r1, r0, lsl #24
 8000510:	40010800 	andmi	r0, r1, r0, lsl #16
 8000514:	00100008 	andseq	r0, r0, r8
 8000518:	00080010 	andeq	r0, r8, r0, lsl r0

0800051c <mainLoop>:
 800051c:	e92d 47f0 	stmdb	sp!, {r4, r5, r6, r7, r8, r9, sl, lr}
 8000520:	2100      	movs	r1, #0
 8000522:	f44f 15c0 	mov.w	r5, #1572864	; 0x180000
 8000526:	f04f 0c18 	mov.w	ip, #24
 800052a:	f44f 3480 	mov.w	r4, #65536	; 0x10000
 800052e:	f04f 0e01 	mov.w	lr, #1
 8000532:	4a20      	ldr	r2, [pc, #128]	; (80005b4 <mainLoop+0x98>)
 8000534:	4820      	ldr	r0, [pc, #128]	; (80005b8 <mainLoop+0x9c>)
 8000536:	4e21      	ldr	r6, [pc, #132]	; (80005bc <mainLoop+0xa0>)
 8000538:	4f21      	ldr	r7, [pc, #132]	; (80005c0 <mainLoop+0xa4>)
 800053a:	f8df 8088 	ldr.w	r8, [pc, #136]	; 80005c4 <mainLoop+0xa8>
 800053e:	6893      	ldr	r3, [r2, #8]
 8000540:	f013 0fc0 	tst.w	r3, #192	; 0xc0
 8000544:	d005      	beq.n	8000552 <mainLoop+0x36>
 8000546:	2900      	cmp	r1, #0
 8000548:	d0f9      	beq.n	800053e <mainLoop+0x22>
 800054a:	f8c2 e010 	str.w	lr, [r2, #16]
 800054e:	2100      	movs	r1, #0
 8000550:	e7f5      	b.n	800053e <mainLoop+0x22>
 8000552:	6115      	str	r5, [r2, #16]
 8000554:	6883      	ldr	r3, [r0, #8]
 8000556:	6116      	str	r6, [r2, #16]
 8000558:	f3c3 2a03 	ubfx	sl, r3, #8, #4
 800055c:	6883      	ldr	r3, [r0, #8]
 800055e:	6117      	str	r7, [r2, #16]
 8000560:	ea4f 1913 	mov.w	r9, r3, lsr #4
 8000564:	6883      	ldr	r3, [r0, #8]
 8000566:	f009 09f0 	and.w	r9, r9, #240	; 0xf0
 800056a:	f8c2 c010 	str.w	ip, [r2, #16]
 800056e:	f403 6370 	and.w	r3, r3, #3840	; 0xf00
 8000572:	ea49 090a 	orr.w	r9, r9, sl
 8000576:	ea43 0909 	orr.w	r9, r3, r9
 800057a:	6883      	ldr	r3, [r0, #8]
 800057c:	011b      	lsls	r3, r3, #4
 800057e:	f403 4370 	and.w	r3, r3, #61440	; 0xf000
 8000582:	ea43 0309 	orr.w	r3, r3, r9
 8000586:	f483 4900 	eor.w	r9, r3, #32768	; 0x8000
 800058a:	f1b9 0f04 	cmp.w	r9, #4
 800058e:	bf8f      	iteee	hi
 8000590:	f04f 0988 	movhi.w	r9, #136	; 0x88
 8000594:	4443      	addls	r3, r8
 8000596:	f5a3 4300 	subls.w	r3, r3, #32768	; 0x8000
 800059a:	f893 9000 	ldrbls.w	r9, [r3]
 800059e:	6893      	ldr	r3, [r2, #8]
 80005a0:	b29b      	uxth	r3, r3
 80005a2:	ea43 2309 	orr.w	r3, r3, r9, lsl #8
 80005a6:	60d3      	str	r3, [r2, #12]
 80005a8:	2900      	cmp	r1, #0
 80005aa:	d1c8      	bne.n	800053e <mainLoop+0x22>
 80005ac:	6114      	str	r4, [r2, #16]
 80005ae:	2101      	movs	r1, #1
 80005b0:	e7c5      	b.n	800053e <mainLoop+0x22>
 80005b2:	bf00      	nop
 80005b4:	40010c00 	andmi	r0, r1, r0, lsl #24
 80005b8:	40010800 	andmi	r0, r1, r0, lsl #16
 80005bc:	00100008 	andseq	r0, r0, r8
 80005c0:	00080010 	andeq	r0, r8, r0, lsl r0
 80005c4:	20000000 	andcs	r0, r0, r0

И я вижу, что код функции readAddressBus() оттранслировался в отдельные адреса. Но я нигде не вижу вызова этой функции. При этом я вижу искаженный код данной функции внутри mainLoop(), значит readAddressBus() вроде как заинлайнилась.

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

Исходник на Си: https://github.com/xintrea/mikroshamem/blob/c00c10606dca71d3531c45f70b1169732...
Ассемблер: https://pastebin.com/gpc4tA03

 , , ,

Xintrea
()

Funtoo from Scratch

Статьи — Разработка

Руководство по сборке Funtoo в окружении, не основанном на Funtoo Linux. Цель — показать процесс создания stage3 Funtoo в «произвольном» linux-окружении на примере GNU сборки.

( читать дальше... )

 , ,

vvn_black
()

Transmission 4.0.0 beta1

Форум — General

Cлучайно набрел на свежую мажорную версию transmission (beta).

Pre-release: https://github.com/transmission/transmission/releases/#All-Platforms

Загрузить: https://transmissionbt.com/

Просто делюсь новостью.
А может кто-то уже пробовал?

 , ,

mexx
()

Где найти скрипт генерации gentoo minimal?

Форум — Desktop

Есть необходимость в своём livecd, с необходимыми пакетами. Хотелось бы взять скрипт, с помощью которого генерируют gentoo minimal install и добавить туда нужные пакеты

 ,

serg002
()