Продолжение поста «Ностальгия: "DIY-Do it yourself/Сделай сам" Техническая база на переломе тысячелетий»1
На диске было описание и схемы подключения не только для простых, но и для шаговых моторчиков. Сейчас я не смогу сделать его "образ", у меня сейчас нет подключенного CD-ROM, да и за диском лезть далеко. Сейчас я такого в Интернете не нашёл, зато есть куча другой, уже новой, информации, да и микросхемы уже есть посложнее и более продвинутые, так что он вам вряд ли нужен. Если кто-то хочет, напишите в личных сообщениях, придется подождать, но, может быть, как-нибудь руки дойдут. Тому, кто не верит, что я этот диск нашёл — правда-правда! Вот чек:
Нашлись микросхемы, которые управлялись, как раз, напряжением 5В, которое было на моём LPT.
Мне ещё хотелось сделать манипулятор, чтобы можно было подвигать им, что-то захватить или переместить. Подумав, что в манипуляторе тоже используются двигатели, а управление я всё равно подключу похожим образом, я подумал, что в качестве примера для исследования управления манипулятором моя машина хорошо подходит. Она тоже может перемещать предметы, в конце концов, можно будет приделать ей захват. Я решил пробовать подключить для управления с компьютера не что-то собранное заново, а уже имеющуюся у меня машину.
Чтобы подключить что-то к чему-то, сначала нужно сделать плату. Я делал платы из текстолита с медным покрытием, опять же, с Митинского радиорынка. Покрытие нужно покрыть лаком, который повторял бы проводники и контактные площадки, затем протравить лишнее медное покрытие. Для этого нужно пролить хлорное железо на ковёр, испачкать всё и хорошенько пропитать свою одежду цапонлаком. После этого можно покрыть облитый реагентом ковёр пылью от сверления дырок в текстолите под ножки дискретных деталек, испортить несколько листов дорогого, по моим меркам, текстолита. Получается плата, типа, как печатная, только рукотворная.
Микросхема работала следующим образом. Каждая из них управляла одним двигателем. Подавала питание разной полярности на два выхода, в зависимости от наличия напряжение на, кажется, двух её управляющих ножках: вперёд и назад. Я не помню ее точное название. Если нет сигналов, то двигатель не работает. Я купил в том же Чип и Дипе и подключил две таких.
Сначала я нарисовал схему на листке бумаги, затем подключил по ней микросхемы к выходам LPT-порта. Через программу на порт выводится число, где единица присутствует или отсутствует на нужных ножках подключенной к его выходам микросхемы. Когда порт подаёт единицу, то есть, напряжение на нужные ножки — двигатели крутятся. Выходы микросхем соединил с правым и левым двигателями на моём "манипуляторе". Если оба вперёд, то машина двигается вперёд. Если в разные стороны, то поворачивает. Я сделал разворот на месте, как у некоторых настоящих танков.
Следующим шагом должно было стать подключение клавиатуры, но это уже было делом техники. Помимо стандартных для "бродилок" и "стрелялок" WASD для движения я подключил и мышку. Я сделал так, что машина копировала движения оператора ПК. Двигаешь ей вперёд — машина едет вперёд, назад — едет задом. С помощью мышки получился уже, буквально, настоящий манипулятор. Двигаешь мышью в сторону — машина поворачивает. В управлении я задействовал и и кнопки. Нажимается левая кнопка — поворот налево, правая — направо, обе — движение вперёд.
Программа для этого захватывала курсор мышки и прятала его. Но я тут же задался вопросом: если невозможно будет двигать курсором, то как остановить программу? Поэтому я добавил кнопку, на которую автоматически наводился фокус. Чтобы остановить управление, нужно надавить на Пробел, эта кнопка нажмётся, и пользователю вернётся курсор.
Странно, но ни в школе, ни в институте на уроках по программированию нас не учили, что бывают разные версии ПО и как называть переменные, и, соответственно, в моих каталогах для разработки ПО программы хранились под названиями типа: LPT_final, LPT_final2, LPT_final_latest, LPT_final_latest2, ну и так далее. Переменные назывались просто X, Y, O и т. п, и программа на скриншоте называлась, как и многие, для которых я не напрягался, придумывая названия, "Project1.exe".
Я долго испытывал управление и проходимость машины в разных условиях и разными манёврами. Управлять настоящим предметом, используя клавиатуру и мышку, прямо как компьютерным персонажем, было круто! Можно представить, что машина исследует виртуальный мир, а ты ее оператор. В этом мире были и рендер, и разрешение, и физика столкновений получше, чем в компьютерных играх. Особенно реалистичными казались ожоги от соскользнувшего с жала паяльника мне на кожу припоя.
Однако оставалась ещё одна возможность, которую стоило попробовать применить. Что если управлять им по сети? Получится ли и насколько большой будет задержка? Будет ли "пинг" настолько большой, что машиной невозможно будет рулить?
Удалённое управление
Я стал думать, как можно передать числа, которыми управляются двигатели с LPT-порта, по сети. Первое, что пришло в голову — это локальная сеть, благо, у меня был для неё коаксиальный кабель и сетевая карта, тоже снятая с Пентиума, но второго компьютера у меня не было. Не только второго, но и вообще компьютеров не было ни у друзей, ни у соседей. Компьютерами пользовались только те знакомые, кто учился в институте. Даже их родители считали компьютер бесполезной тратой денег, дорогой игрушкой, которая только портит зрение и отвлекает от прополки картошки.
Я перебрал в голове кучу вариантов, но остановился на том же Visual Basic. Для этого в этом языке существовал другой модуль под названием winsock.ocx. В качестве протокола я сначала выбрал TCP, однако меня сразу же озадачила некоторая сложность при потере пакетов. Тогда я переключился на UDP, потому что в нём не нужно было считать отправленные пакеты. Сколько пришло, тем и будем довольствоваться.UDP просто отлично подошёл для моей цели.
Я слегка изменил программу для управления вездеходом, создав внутри неё аналог передачи позиции курсора на выход LPT, но не напрямую, а через сетевые сигналы. Поэтому теперь она разделилась на две части, клиентскую и серверную. Клиент подключался к "серверу" по IP-адресу, вводимому в текстовое поле.
Как я уже упомянул, второго компьютера у меня не было, и управлять, и смотреть на картину движения вездехода, всё равно приходилось с одного и того же ПК. Для этого нужно было запустить и клиентскую, и серверную часть, на моём компьютере, и связать их, введя в клиент IP сервера.
Эта программа на современных ОС уже тоже не запускается.
Для их запуска, возможно, сработает установка Windows 98 на виртуальную машину, однако сейчас я не могу этого сделать.
При программировании в Visual Basic было очень просто вставлять компоненты различных программ прямо в "формы". По-моему, я добавил в неё одним из компонентов NetMeeting, и запаковал всё в "установщик". По крайней мере, сейчас, в одной из ошибок запуска, программа ругается на именно этот неработающий компонент. Файл "Conf.exe" — это и есть программа NetMeeting. Она, в качестве рудимента, дошла до Windows Vista.
Дату изменения исполняемого файла повредил вирус, но внутри установочного CAB все даты правильные.
Получилась программа для удалённого манипулирования машиной. Правда, тестировать работу программы мог только я у себя на компьютере, и я подсоединял программу управления к серверной её части, запускавшуюся на том же компьютере, по IP 127.0.0.1.
Поскольку у меня есть веб-камера, почему бы не попробовать установить её на трактор? Я поставил, но провод от неё был настолько толстый, что управлять ей было не удобно. Чтобы испробовать телеуправление, я решил, что проще наводить камеру на машину, а сам вездеход ездил бы по столу под ней. Пользователь мог видеть перемещения машины на своём экране, через камеру, и управлять движением устройства с помощью мышки и клавиатуры.
Программа состояла из двух частей, программа-клиент и сервер. Управляющий запускал на своём компьютере клиентскую часть, а тот, у кого был компьютер с машиной — серверную. Управляющий смотрел Winipcfg IP-адрес сервера и вводил его в клиентскую часть программы, программа сама подставляла IP-адрес в NetMeeting, и они соединялись. Управление шло с видео: видео и аудио передавались через NetMeeting.
Боевой выезд
Для связи с Интернетом бодро свистел в телефонную сеть PCI-модем 3Com, который, по идее, должен был выдавать 56 килобит в секунду. Одним из крупнейших и самых известных Интернет-провайдеров, представленных на всех выставках и больше всего раздававших там предметов и буклетов с рекламой, был Demos со своим знаменитым доменом SU, что означало Soviet Union: http://demos.su . Однако мой модем с основными провайдерами: MTU Inform, Caravan, Demos и Sitek, не всегда соединялся по Dial-up на заявленной максимальной скорости, и чаще скорость была всего 33,6 килобита в секунду.
Проверить работы удалённого управление было катастрофически не с кем. Друг, с которым мы связывались по видеосвязи, был занят.
Я подумал, что, ведь, в сущности, можно было бы проверить и без обратной связи. Управление будет работать и в том случае, если если кто-то просто запустит клиент на своём компьютере и будет видеть мою камеру. Тогда, водя мышкой, он сможет поуправлять машиной. Этого было достаточно, ну а я ему потом перезвоню, и он расскажет словами, получилось или нет! Пришлось пожертвовать обратной связью в реальном времени, и я не мог получить впечатления об управлении прямо во время сеанса связи.
Пусть оператором машины буду не я, и пусть я не буду видеть и слышать водителя машины, пусть придётся только позже услышать его впечатления. Однако нужно было провести тестирование новой системы. Без этого я не мог понять перспективы и работоспособность такого подхода к удалённому управлению.
На помощь пришёл второй друг, которого звали просто Анатолич. У него был компьютер, и тоже был модем, не было ни микрофона, ни камеры. С компьютерами разговаривать было не принято.
Я позвонил ему.
— Привет, хочешь, я тебе покажу кое-что новое?
— Хочу, давай!
Я вкратце описал, как управлять моей системой с его компьютера. Программа просто устанавливалась: я постарался, чтобы от пользователя требовалось наименьшее количество самостоятельных действий, и включил все компоненты, включая программу для видеосвязи, в архив для установки. Установочный файл я передал Анатоличу на дискете, так как он жил недалеко, и для этого было достаточно спуститься к подъезду.
— Сначала мы созвонимся по модему, ты вот сюда набирай: Winipcfg, там смотри цифры, вставляй адрес вот сюда.
— Так, понял, записал. А что дальше?
— Кнопки работают так, у тебя откроется изображение. По видео контролируешь. Потом расскажи, что получилось!
Я стал ждать. И, в какой-то момент, металлический звонок дискового телефона зазвонил, однако соединение по медным телефонным линиями тут же перехватил модем 3Com, "подняв трубку" первым. Сначала я просто смотрел на машину, но ничего не происходило. "Что же я подключил не так?" — было, успела промелькнуть у меня мысль. Похоже, что Анатолич всего лишь искал мой IP и подключался через программу-клиент. И затем машина задвигалась.
Вездеход поехал вперёд, развернулся. Он ездил вперёд и назад, влево и вправо, повторяя движение мышки в руке Анатолича. Машина поворачивала на месте, исследуя стол и перекручивая свои провода. Анатолич быстро разобрался с управлением. Пару раз танк чуть не свалился со стола, и пришлось ловить его руками, прямо в кадре у оператора.
Невероятно, но сейчас передо мной, в 2002 году, телеуправляемый вездеход исследовал письменный стол. Он передавал видео с одной из первых веб-камер через видео- и аудиопотоки, сжатые для передачи по медным проводам одними из первых кодеков. Мой друг направлял машину своей мышкой с удалённого компьютера и наблюдал за её движением через одну из самых первых программ для передачи видео, подключавшую собеседников тогда ещё напрямую, через IP-адрес.
Похоже, Анатолич вошёл в раж первооткрывателя новой технологи. Мне показалось, что ему нравилось не только ездить, но и просто смотреть в камеру на машину с разных сторон. Мне часто приходилось распутывать провода, запутавшиеся после разворотов вокруг колёс стол вездехода.
Когда я перезвонил Анатоличу через настольный телефон и спросил его о работе технологии, он подробно рассказал, как и что он делал и что видел, и что всё работало, как я и сказал.
Результат тестирования и отзыв оператора
Друг рассказал, что задержка при управлении в долю секунды почти не мешала вождению, и что ему очень понравилось.
Долгое время я не хотел устанавливать на компьютер Windows XP, который вышел недавно. С одной стороны, интерфейс Windows 98 мне нравился больше, а, с другой, мне не хотелось терять быстродействие компьютера. Ведь XP, хоть и хвалился скоростью своей работы, на практике был заметно медленней, чем Windows 98.
Видимо, чтобы простимулировать популярность XP, производители нового ПО стали стремительно прекращать поддержку Windows 98, и выбора не оставалось: пришлось обновить и ОС. Когда я запустил свою программу под XP, я увидел, что в ней убрали возможность прямого управления портами.
Оказалось, что моя видеокамера Kensington внезапно также перестала работать с какими-либо Windows, старше Windows Millenium. Поэтому я не мог ее использовать, и долгое время оставался без веб-камеры. Лишних "Денег" на новую у меня не было.
Microsoft прекратила поддержку NetMeeting и MSN Messenger. Поскольку в Windows XP "vbio32.dll" уже не посылал сигналы на выходы LPT-порта, я с головой погрузился в другие проекты. Отложив идею в долгий ящик!
Для того, чтобы попробовать подключение к современному, на то время, PC и модемному Интернету, нужно было какое-то устройство, которое было бы, с одной стороны, просто собрать, а с другой, которое бы показало дальнейшие перспективы управления подобным образом. Из положительного заключения оператора созданного устройства по результатам тестирования, стало понятно, что, несмотря на некоторые неудобства, скорости 33,6 кбит/с и видео и аудио, сжатых первыми кодеками, хватало на управление по видеосвязи, и задержка не мешала движению и контролю над подключённой машины.
Неудобства заключались в том, что было слишком сложно созваниваться и искать IP-адрес, каждый раз предоставлявшийся провайдером заново, и в том, что во время связи нельзя было разговаривать по телефону.
Только представьте, что управлять удалённым устройством, при правильном подходе, можно было из любой точки мира и видеть результаты своих действий в прямом эфире, прямо на экране! Пусть и на пузатом экране семнадцатидюймового ЭЛТ-монитора.
Ностальгия: "DIY-Do it yourself/Сделай сам" Техническая база на переломе тысячелетий1
Техническая база на переломе тысячелетий
Воспоминания с товарищами за рюмкой чая. На дворе стоял 2000 год. Старые времена плавно погружаются в Лету вместе с осколками предыдущей империи, по телевизору идут "Звёздный час" и "Сам себе режиссёр", я потихоньку разжёвываю кусочки от гранита науки. В те жутковатые годы купить что-то из деталей для создания чего-то электронного, для души, было не такой уж лёгкой задачей.
Пока вы читаете эту статью, я побуду там, на пороге перемены веков. Я покажу вам, что вокруг меня происходит, и проведу путём создания прототипа своего нового устройства. Текст поможет нам просочиться сквозь время, ну потом вы, уже в своём времени, в комментариях напишите своё мнение, или поспрашивайте, что не понятно, я, пока посижу я тут и поотвечаю на ваши комментарии.
Когда-то, в стране советов, страна поддерживала радиолюбителей, и тогда были и магазины радиодеталей, и кружки по интересам, и даже Дворцы Пионеров, где можно было что-то сделать или спросить совета. Сейчас же, когда кругом был полнейший разгром, от этого не осталось и следа. Дворцы Пионеров сдали в аренду торговцам джинсами и помидорами.
Это потом, в эпоху Интернета, технопарков, кода, написанного нейросетями и 3D-принтеров, всё для этого вы сможете найти в продаже, прямо не сходя с дивана. Хочешь — закажи печатную плату, а хочешь — выточку или выплавку детали под твои нужды, хоть с со своим выгравированным на них именем. Да хоть с доставкой прямо вам на диван. Вот только уже с одной разницей: почти всё, что вы захотите сделать сами, уже продаётся в магазине. Для этого не будет необходимости.
Проще всего какие-то детали можно было раздобыть, разобрав какое-то сломанное устройство, а также на радиорынках, например, на Митинском, Савёловском или Царицынском. Иногда что-то появлялось в магазинах электротоваров. Как-то я узнал, что в других странах есть целые магазины и торговые центры, в которых продаются товары для хобби под названием DIY. Меня тогда поразил большой контраст с нашей повседневностью, потому что найти все для своего устройства в одном месте вообще не было возможности, и магазинов "Сделай сам" (как и переводится DIY) у нас просто не существовало.
В то время у одного из нас только-только появился первый персональный компьютер. Это был Compaq Presario, моноблок с процессором SX486 и памятью, кажется, 8 мегабайт. Управлялся он ОС Windows 95. Windows 98 на нём подтормаживал.
В моноблоке были встроенные микрофон и динамики, CD-ROM, дисковод для дискет 1.44" и модем. Модем позволял устанавливать связь с Интернетом на скорости 33,6kbps. Очень удобно, когда в настольном компьютере есть всё нужное для работы и развлечений, но уже на то время он был устаревшим. Мне приходилось подолгу искать игры, которые на нём бы пошли. Игры тогда продавались с прилавков, покрытых картонками, на радиорынках. Их продавали, разумеется, как "лицензионные", а по факту, просто скопированные на болванки, крякнутые и с буклетом, напечатанным на принтере. Среди них, надо сказать, встречались и прекрасного качества типографские буклеты, аккуратно вложенные в компакт-диск. В них подробно, пошагово, рассказывалось, как правильно взломать игру прилагающимся на диске файлом.
Что касается подключения к Интернет, то в то время провайдеры продавали доступ во Всемирную Сеть по времени: например, один доллар в минуту. Похоже, что Интернета на всех не хватало, иначе как объяснить, что доступ к Сети был "по талонам" — провайдеры продавали карточки, по телефону, указанному на которых, надо было звонить со своего модема, а номинал был на них указан в долларах. На них под стираемым, как на лотерейных билетах, слоем, были написаны логин и пароль для доступа, который расходовался быстрее, чем сейчас остывает твой чай.
Анекдот про чай был придуман позже, уже при доступном проводном Интернете, поскольку по карточкам в Интернете столько просидеть было совершенно невероятно: Подключился, нашёл что-то, скопировал себе на диск, отключаешься и запускаешь программу или читаешь.
Как остудить горячий чай? Надо включить компьютер, залезть в интернет и бац! Чай остыл.
Ещё более точную информацию по ценам я помню из расклеенных повсюду объявления в 1997 году:
"Интернет по самой низкой цене: 1 цент в секунду!"
Ограничивающий фактор
Каждому, кто умел подключать светодиоды к источнику электричества, приходила в голову идея подключить что-то к компьютеру. Подключение чего-то к портам компьютера просилось уже несколько лет назад, когда я исследовал возможности программирования на Спектруме в Бейсике. Тогда любой компьютер, даже Спектрум или его наши аналоги "Нафаня" и т. д. были пределом мечтаний, и своего у меня не было, поэтому я брал его попользоваться у соседа. Программы в него загружались с простого магнитофона, и я пробовал подключать вместо него портативные плееры. Потом я проверял, можно ли загружать программы звуком через микрофон, подключал микрофон вместо магнитофона. Программы прекрасно загружались, и тогда я исследовал возможности загрузки программ с магнитофона друга по телефону.
Когда я разбирал свой Compaq, то видел, что все устройства в моноблоке были распаяны на материнской плате. Сама она вытаскивалась вместе с задней крышкой и, из-за ее уникальности, замену я бы ей найти ни за что не смог.
Прототип
Сейчас я вижу в качестве конструктора, который почему-то используется для создания прототипов самодвижущихся устройств чаще всего, Lego. Мне же кажется, что металлические конструкторы, наподобие тех, что были доступны Советском Союзе, с множеством деталек, крепящихся с помощью болтов и гаек, подходят для этого больше. Сравнительно недавно для Лего стали появляться подключаемые к собранным из него фигурам электронные компоненты, типа моторов, реостатов, редукторов и различных датчиков. Однако детали металлических конструкторов поставляются самых разных форм, поэтому к ним можно прикручивать обычные электронные компоненты и крепить теми же болтами прямо из набора, и тут ты уже не ограничен в своём творчестве тем, что тебе положили в коробку.
Поскольку я не особо в то время знал магазины электроники, я использовал детали, которые у меня оставались от разобранных сломанных электронных устройств, отданных родственниками за ненадобностью. Как-то на прилавке у продавца на Митинском радиорынке я увидел маленький мотор и из любопытства купил.
Поскольку для создания чего-то самодвижущегося мне нужно было два таких, а найти такой же у меня нигде не получалось, то я его покрутил в руках, повключал и отложил до лучших времён. В то время, в основном, в продаже у нас имелись только советские моторы, гораздо большего размена и за обе щёки пожирающие ваши батарейки любой формы и ёмкости, работающие довольно громко и постоянно ломающиеся:
И вот, на моё счастье, у кого-то сломался кассетный плеер, и я достал оттуда еще один мотор. Это уже прогресс! Я смогу создать что-то маленькое, что не займёт много места, будет ездить тихо и не будет потреблять слишком много энергии для своего движения.
Мотор был вот такой:
Я хотел сделать что-то проходимое и на гусеницах. Напомню, что гусеницы для самодельной машины в то время купить было негде, и из чего их сделать, я так и не нашёл. В журнале "Юный Техник для умелых рук" была статья о том, как сделать самодельные гусеницы с помощью спичечных коробков и катушек от ниток, но я счёл этот способ слишком трудоёмким, я подумал, что моторчики от плеера не "потянут" такую нагрузку.
Тем не менее, самым простым способом поворачивать мне все равно представлялось два независимых мотора, управляющих движителями с каждой стороны машины. У моторчиков оказалась довольно маленькая мощность, а колёсики делать слишком маленькими не хотелось, поэтому нужен был редуктор. Нетрудно догадаться, что редуктор купить было просто не реально, а из имеющихся у меня были только непарные. Редукторов нужно было два, по одному на каждую сторону.
В сложившейся ситуации, после долгих раздумий и испытаний нескольких различных вариантов, было принято решение сделать редуктор в виде шкивов. Для этого я взял самые большие колёса, имевшиеся в наборе конструктора Юность-3:
В качестве передатчиков крутящего момента я установил пассики от того же кассетного плеера, но потом заменил их на резинки для связки пачек денег. У меня были и пачки денег, ага: несколько лет назад случилась дикая инфляция, и расплачиваться за пирожки в столовой можно было прямо запечатанными пачками, только что из банка. А потом и сами деньги поменялись, но ничего не стоящие пачки с того времени у меня остались лежать в столе. Правда, в банке они скреплялись бумажными лентами, но резинки для них тоже применялись.
В задачу других колёс входило только обеспечение лёгкого поворота. Сначала я сделал одно свободно поворачивающееся колесо, но оно оказалось слишком сложным, и часто выходило из строя, поэтому я заменил его двумя микро подшипниками, которые я когда-то нашёл на земле. Достать такие где-то в магазине для меня не представлялось возможным, я просто не знал, где такие продаются.
Для скрепления всего на скору руку, я применил алюминиевую проволоку в белой оплётке, которой было полно на улице. Вы можете спросить, как же просто материалы для поделок, например, проволока, валялись на тротуарах и во дворах, ведь дворники там убираются? что строители разбрасывали свой мусор где придётся, и никому до этого не было дело. В те времена было много непонятных вам вещей и событий, в то время казавшихся самим собой разумеющимися.
Дети ломали ноги на стройках, где не было никаких сторожей, нюхали в недостроенных домах клей среди валяющихся на грязном полу шприцов, вперемешку со стройматериалами.
Раму корпуса и оси я взял из конструктора "Механик". Получился самодвижущаяся машина в стиле , с огромными ведущими колёсами и маленькими вспомогательными.
Сходство с ним получилось не спроста — ведь его создатель тоже пытался получить преимущество гусениц за счёт свойств проходимости больших колёс.
Следующим шагом нужно было как-то подключить ее к компьютеру. Манипулятор был готов, и я сейчас управлял им джойстиком от Спектрума. Джойстик от своего Спектрума мне отдал сосед после того, как у него он сломался. Я его разобрал, заменил исполнявшие в нём роль кнопок концевики, подключил к питанию моторами на каждое из ведущих колес, и с джойстика можно было управлять движением и поворотами машины.
Я, было, собрался как-то его связать со своим компьютером, и я стал взвешивать все "за" и "против". Я понимал, что, если я что-то подключу к своему моноблоку не так, то я лишусь самого дорогого устройства в квартире.
Смена положения вещей
К концу года для учёбы мне требовался более современный компьютер, и поэтому у меня появился компьютер совершенно другого уровня: Pentium Pro с частотой 200МГц, оперативкой в 32Мб и жёстким диском на 850Мб. В корпусе АТ, а не ATX, как сейчас. Ну, вы помните эту надпись. Оххх...., были ВРЕМЕНА!)
Скорость его работы просто поражала: Internet Explorer 3 грузился за секунды, почти без тормозов работал Office 97, шустро открывался почтовый клиент The Bat, а Windows 98 устанавливался в несколько раз быстрей! Ведь мы же все знаем, что это был тогда важный параметр, потому что раз в несколько месяцев, или даже недель — кому как — приходило время, когда Windows, как ни крути, должен был быть переустановлен.
Самая важная полезная особенность для меня было в нём — это то, что он не был монолитным устройством, и я мог, при возможном сбое, заменить какую-то деталь. У меня появилась возможность подумать, как к нему подключить моё передвигающееся устройство.
А через некоторое время завелось у меня, для того времени, что-то ещё, совершенно невероятное. Штука, которую было совершенно не понятно как применить. Чудо-чудное, диво-дивное: веб-камера Kensington Videocam VGA Digital PC Camera производства 1999 года.
Для меня это было первое цифровое устройство, с которого можно было захватывать изображение прямо на компьютер. Да и, наверное, первое из подключающихся по USB. Тогда больше ни для чего этот порт я применить не мог, так как флешки, если уже и были, то только появлялись, и были дико дорогими. Да и мы до сих пор везде пользовались дискетами. Помню, я еще, в дополнение, устанавливал в него дисковод 5,25" для того, чтобы брать у преподавателей в институте программы, писавшиеся для зачётов и курсовых в прошлые годы.
Её максимальное разрешение было 400х300, но это только для фотографий. Видео она могла снимать лишь в 320х240 или 352х288. Благодаря ей, я сегодня могу добавить в эту статью фотографии. У меня здесь, а мы уже в 2001 году, фотки для этой статьи, по вашим меркам, не очень.
До изображения, подходящего к вставке сюда, и лучшего для просмотра на современных мониторах, мне поможет их довести нейросеть для увеличения разрешения.
Подключение к компьютеру
Я стал выбирать порт, чтобы подключить свою машину к компьютеру. По USB информации в Интернете было мало. Были еще разъем для клавиатуры DIN, последовательный и параллельный порт. Из COM и LPT я выбрал последний. В те времена, когда мышкам нужно прочищать колёсико, а на домашних телефонах были диски для набора номера, к этому порту подключали принтер.
Мне он показался проще для подключения внешних устройств. Смотришь распайку, подаешь на выходы числа, напряжение или есть, или нет.
Программа
В качестве языка программирования я использовал Visual Basic. Под Windows 95 и 98 в нём можно было управлять LPT. Под Windows XP было уже нельзя. Поскольку я не торопился менять Windows 98 на другую ОС, то у меня всё работало, а, возможно, я тогда уже установил Windows Millenium.
Я стал искать информацию о работе с различными портами. Скачав статьи по теме доступа к портам, скачанными с сайтов — а, так как подключение было по Dial-Up, то я их скачивал на жёсткий диск и с него открывал — и всякими справочниками по Visual-Basic в различных форматах, среди которых встречались и TXT, и HTM, и CHM. Одним из самых известных сайтов был VBstreets.ru, где было публиковалось больше всего полезной для меня, на тот момент, информации.
В этом языке есть библиотека для работы с портами ввода/вывода: "vbio32.dll". Используя её, я предпринял первую попытку подать сигналы на LPT. Сначала я просто выводил числа на порт. Я поместил в программу, открывающуюся сейчас из папки 2001 года, поле для ввода числа и две кнопки для посылки числа на порт и снова сброса его на ноль.
Вводишь число, нажимаешь кнопку — и число появляется на выводах LPT-порта в двоичном коде. Его можно пощупать тестером.
Хорошо. Числа передаются, тестером прощупываются. Я прикинул, как можно было бы сигналами управлять машиной. Просто подавать на порт нужные числа в зависимости от нужного от двигателей действия. Ну что ж, это полдела, отлично!
Программы овеивают вас своим электронным дыханием того времени и уже с новых компьютеров радуют наш взгляд своими остроугольными интерфейсами, пережив поломки многочисленных жёстких дисков, бэд-блоки, вирус-шифровальщик и переносы с диска на диск при их сменах. Поскольку все свои программы я запаковал в архив, тогда ещё для экономии места, а архив пострадал от сломанных секторов жесткого диска, то сейчас я могу открыть не все программы, которые я тогда написал. Шутка ли — всеми возможными путями выкроить место на диске в 850Мб! Потерялись и многие из сурс-кодов этих программ. Однако исходников осталось на диске гораздо больше, чем скомпилированных файлов и, наверное, можно из них собрать программы заново.
И у некоторых файлов поменялась дата последнего изменения файла: после то ли какого-то сбоя жёсткого диска, то ли после вируса-шифровальщика, не помню когда, некоторые даты поменялись на 31.01.2020 и исчезли длинные имена файлов, оставив после нескольких знаков "~1". Зашифровать он успел не всё, когда я заметил подозрительную активность жёсткого диска, я сразу выключил компьютер. Однако после лечения Доктором Вебом или Касперским, даты некоторых исполняемых файлов просто стали неправильными. Похоже, как раз, я "поймал" вирус в 2008 году, так как антивирус расшифровывал и пересоздавал спасённые файлы.
Запрограммировать, как надо, вывод на LPT у меня получилось не сразу, но я на каком-то сайте нашёл пример. Программу, написанную неким Алексом Новожиловым, которая выводила на порт последовательности чисел. Я увидел, что она написана, как раз, на VB и это придало мне сил, к тому же, как раз в ней была нужная мне библиотека "vbio32.dll".
Однако напрямую двигатели, как это, казалось бы, было проще всего сделать, к порту подключать нельзя. Подсоединить машину для управления клавиатурой я еще не мог.
Pentium Pro, хотя и пробыл у меня не так долго, но подарил мне надежду, что не всё в компьютере будет так уязвимо к повреждениям, и что я уже смогу разбирать компьютер и что-то в нём заменять и добавлять, поэтому я смог лазить тестером ему в порты ввода-вывода.
Первые попытки выхода на белый свет
После широкого распространения персональных компьютеров, Савёловский рынок окончательно перепрофилировался в компьютерный, и там я, для дальнейшего улучшения условий учёбы, с помощью друга и семисот долларов, приобрёл нового помощника — Duron 700, с памятью 128Мб и видеокартой GeForce MX200. В него я переставил модем из Pentium Pro-200.
С помощью своей веб-камеры я стал предпринимать попытки с кем-то увидеться через компьютерный экран. Оказалось, что среди всех моих знакомых веб-камера была только у одного друга.
У всех уже была ICQ, но в ней можно было только писать текст и, уже несколько позже, пересылать файлы. Ещё был IRC, но он был менее удобный. После долгих поисков в Интернете, я нашёл две программы, с помощью которой можно было общаться в Интернете. Одна представляла собой прямое соединение пользователей по IP и позволяла общаться, в отличие от ICQ, голосом а тем, у кого есть камера, и с видео. Она называлась Microsoft NetMeeting.
Вторая звалась MSN Messenger. В нём можно было найти различные группы, где общались иностранцы, в основном, из США, под названием MSN Groups или MSN Chat rooms. Они обсуждали что-то или сидели в чатах просто так и шутили на английском. Однако в некоторых чат-группах люди уже использовали веб-камеры.
NetMeeting был проще, а, что касалось разговоров с несколькими пользователями в группах, то тут скрывалась и проблема.
В школе у нас не было английского, так как учителя часто увольнялись, а новых найти долго не могли. Я собрался с духом и стал исследовать возможности соединения по этим обоим программам. Первый блин разговора в MSN Messenger, как и водится, получился комом.
Я помню, что одним из первых моих собеседников был дед, смотревший в камеру в огромных наушниках и здоровенных очках, окружённый массой радиотехники. На экране он выглядел древним, как сама Земля. Со скидкой на возраст, вид у него был примерно такой:
Он сидел среди забитых электроникой полок и говорил в отдельный, стоящий на столе, большой микрофон.
Тем не менее, это был самый вежливый, внимательный и терпеливый собеседник, которого я тогда встретил. Он вслушивался, в своих невероятного размера наушниках, в каждое моё слово. Я его понимал, а он моё произношение разбирал с трудом. Общение не складывалось, но он не сдавался. Дед просил меня повторить что-то, переспрашивал, просил проговорить по буквам. Пытался узнать, кто я, откуда, интересы и предпочтения в еде. Я тогда растерялся. Я никогда до этого не разговаривал на английском через компьютер, да даже по телефону. Я стеснялся говорить громко по-английски, потому что боялся, что меня не поймут.
Хотя он просил меня этого не делать и уверял, что у нас получится разговор, я отключился. Я потом уже понял, то о чём он меня просил и что рассказывал:
"Сынок, просто произноси слова почётче. Я был радистом во время войны во Вьетнаме, и всякое повидал. Нужно только говорить погромче, и у нас заведётся отличный разговор. Я слышал тысячи людей по радио с разными качествами сигнала, и я умею разбирать звуки в радиоэфире даже среди сильных помех. Видишь, я тебя уже понимаю!"
Я поколебался и "повесил трубку".
И я тебя сейчас понимаю, дед. Спасибо — если бы не ты, мне было бы гораздо труднее научиться понимать собеседника и отвечать ему на другом языке. Я тогда упустил полезную практику, которую можно было бы пройти в тот день, и на несколько недель потерял возможность влиться в эти голосовые чаты. Только спустя несколько дней после разговора с радистом я осознал, что люди, в общем-то, могут меня понимать. Пришлось перебрать много конференций и собеседников, чтобы добиться такого разговора, который бы все его участники могли поддерживать.
Я был потрясён тем, что собеседника можно не только слышать, но и видеть. Напомню, что тогда самым популярным мессенджером была ICQ, в ней люди посылали свой адрес электронной почты, и уже по Email пересылали фотки с плёночного фотоаппарата, отсканированные сканером. По телевизору шла программа "Сам себе режиссёр", которая состояла из были видео, снятых на камеры с магнитными кассетами, и которые её участники присылали в телестудию по обычной почте. А тут: ты сам видишь окружение, природу, людей не только рядом с тобой, но и из разных стран! Я поначалу просил собеседников просто помахать в камеру или покрутить перед ней кружкой или книжкой, настолько казалось невероятным видеть собеседника.
Второй случай произошёл немного позже. В одной из комнат, где люди общались в общем чате, я включил камеру какого-то мужика. Увидев в списке тех, кому показывается его видео, мужское имя, он посмотрел в неё и спросил:
— Зачем ты на меня смотришь?
Я сказал, что просто хочу пообщаться. А на кого мне еще смотреть?
Он сказал:
— Смотри на девушек!
"Чёрт возьми, — подумал я тогда, —наверное, в будущем у веб-камер будут и правда стоящие применения".
Через другую программу, NetMeeting, можно было подключиться к собеседнику напрямую, введя IP-адрес. Мы попробовали общаться так через камеру с моим другом.
Для того, чтобы поговорить с видео, мы созванивались по модему через обычную телефонную линию, потом смотрели свой IP через Winipcfg, запускали NetMeeting. Один вводил IP другого, и так устанавливался видеозвонок. По-русски говорить было проще, чем по-английски, и, казалось бы, звони — не хочу, но больше созваниваться из друзей было не с кем. К тому же, нельзя было надолго занимать общий телефон, а разговаривать по телефону и лазить в Интернете в одно и то же время было невозможно. Если во время связи снять трубку телефона, то в ней будет слышен писк модемов.
Неожиданная находка и связующее звено
Мне не очень хотелось городить сложную схему из отдельных микросхем и дискретных деталей, и для простого управлением машины с LPT-порта мне была нужна связывающая моторы и порт микросхема.
В поисках подходящих микросхем я обыскал весь Интернет образца 2001 года, скачал каталоги в виде DOS-программ, даже сходил в библиотеку, но и там ничего про микросхемы, подходящие мне, не было. В отношении новых программ и программирования вообще, время тогда не летело так быстро, и программы могли писаться годами. Передо мной стояли примеры работ разных преподавателей, аспирантов и дипломников кафедры, когда вынашивали идею, разрабатывали подход к её решению, план ПО, по нескольку лет. Каталоги микросхем под DOS, которые я скачал, оказались сильно устаревшими.
Показать её работу, увы, не получится.
Когда ко мне в очередной раз приехал двоюродный брат, уже в начале следующего года, он поведал, что в Москве открылся "Такой магазин, в котором ты называешь название детали — и тебе ее продают."
— Не может быть!
— Да правда. Пошли, проверим!
И мы пошли проверять. Этим магазином, так стремительно ворвавшимся в мир творчества и радиолюбителей, и оказавшимся, уже после, лучше западных "Сделай сам", был Chip&Dip. Сначала там, насколько я сейчас помню, продавались только микросхемы, светодиоды, транзисторы-резисторы всех номиналов, но не было такого ассортимента, как сейчас. И таким образом, благодаря сарафанному радио, я нашёл недостающий элемент для моего компьютерного управления. На меня, поблёскивая глянцем прозрачного пластика, смотрел компакт-диск с названием "Микросхемы для управления электродвигателями".
В виду ограничения фотоматериалов
ПРОДОЛЖЕНИЕ СЛЕДУЕТ...
Пишем один «exe», который работает на 3-х разных ОС без перекомпиляции
Нет, это не шутка и не кликбейт. Такое действительно возможно - правда через небольшой хак.
Недавно я задался вопросом: а возможно ли написать для ARM нативную программу, которая будет бесшовно работать сразу на 4-х операционных системах без необходимости перекомпиляции для разных платформ и ABI. Мне очень хотелось реализовать возможность писать кроссплатформенные эльфы для мобильных телефонов из нулевых и попытаться портировать на них эмуляторы ретро-консолей. Погрузившись в документацию на исполняемые форматы, я пришёл к выводу, что да - это возможно и смог реализовать такую программу на практике без читерства по типу VM! Всех гиков приглашаю под кат!
❯ Зачем и почему?
Давным-давно, в далёком 2001 году, мир увидел легендарный японский телефон - Sony CMD-J70. Ещё до создания совместного подразделения с Ericsson, Sony выпускала достаточно занимательные девайсы, которые привлекали внимание не только рядовых пользователей, но и моддеров всех мастей. Уже через пару лет после выхода, в программном плане телефон копали все кому не лень: кто-то менял графику, кто-то писал патчи, а со временем написали даже бинлоадер (PRGLoader) - загрузчик внешних "экзешников", позволявший запускать на телефоне произвольный софт, написанный на ассемблере!
Сейчас сложно себе представить, но в те годы это был нереальный отвал башки: на большинстве телефонов были доступны разве что Java/Mophun-приложения, которые обладали ограниченным функционалом и уж тем более не позволяли лезть в дебри прошивки телефона, а здесь были программы которые буквально позволяли делать с телефоном всё что захочешь: светомузыку из подсветки, кастомные игры, обои на главный экран... всё это было доступно только на куда более дорогих смартфонах с Symbian и Windows Mobile на борту!
Недавно мы с вами вспоминали о легендарном Siemens M55 и узнали, что у него находится под капотом. Несмотря на диковинную архитектуру Infineon C166, даже под этот телефон делались патчи и была написана как минимум одна кастомная игра. Но рассвет моддинг-сцены Siemens произошёл с выходом платформы S-Gold на базе стандартного ядра ARM926EJ-S, когда в ~2004 году энтузиасты полностью взломали алгоритм генерации BootKEY для загрузчика, а затем в 2006 году реализовали полноценный эльфлоадер, который позволял загружать программы написанные на C и скомпилированные самым обычным компилятором ADS. В отличии от бинлоадера для CMD-J70, "эльфятник" позволял угонять функции RTOS для создания потоков и привносил в бюджетные телефоны полноценную вытесняющую многозадачность с настоящим диспетчером задач и возможностью запуска несколько программ одновременно:
Энтузиасты раскапывали прошивку в дизассемблере, изучали её и пытались понять как работают разные её подсистемы. Результатом стало появление нативного клиента почты с предком пуш-уведомлений, аськи (NatICQ), порты самых разных эмуляторов ретро-консолей и даже полная программная поддержка MP3 в тех телефонах, где её отродясь не было! И представьте себе, почти все эти программы можно было свернуть и продолжить работу в браузере или, например, Card Explorer'е! Одним из эльфописателей был Хабровчанин @ilya_ZX
Но если вы думаете что одними телефонами Siemens энтузиасты были едины, то вы ошибаетесь - ведь круче были только "моторолки"! В 2004-году, недорогая Motorola E398 с двумя громкими динамиками, светомузыкой и поддержкой MicroSD-флэшек, стала настоящим бестселлером и привлекла к себе не меньше энтузиастов, чем Siemens. Ребята сплотились на форуме MotoFan, нашли уязвимость в загрузчике и хакнули верификацию RSA-подписи у прошивок, позволив не только модифицировать Seem'ы (что-то типа NVRAM), но и создавать для телефона кастомные прошивки - монстрпаки, которые прибавляли громкость и без того не самым тихим динамикам и в различных аспектах изменяли главное меню устройства. Со временем, @Andy51 и ещё несколько энтузиастов реализовали эльфлоадер (EP1) для E398, раскопали прошивку и написали много полезного софта, время от времени переключаясь на Linux-телефоны от Motorola...
Вероятно многие читатели подумают мол "было и было, мой айфон/сяоми может запускать любой произвольный софт и эти ухищрения давным-давно неактуальны...". Но как бы не так: про моторолки и сименсы не просто всё чаще вспоминают, у них есть до сих пор активное моддерское коммьюнити, которое продолжает пилить для них кастомный софт и далее колупать прошивку. Всё тот же @EXL портировал крутой софтрендер для E398 и в 2025 году наконец-то взломал C350, @Azq2 пилит аппаратный эмулятор Infineon S-Gold и многие другие делают свой вклад в моддинг сцену уже не таких мейнстримных, но отнюдь не устаревших устройств!
Однако порог вхождения для написания эльфов достаточно высокий: нет никакой отладки кроме printf, любая ошибка в приложении приводит к зависанию или ребуту телефона (на сименсах с характерным "пик"), а API напрямую импортируется из прошивки телефона и может быть достаточно комплексным - ни о каких кроссплатформенных эльфах и речи не идет. Поэтому в какой-то момент мне стало интересно: а возможно ли написать такой эльфлоадер, который за своим рантаймом будет прятать детали реализации работы с аппаратной начинкой телефона и при этом загружать один и тот же бинарник на всех поддерживаемых платформах без особых патчей и изменений? Принявшись за изучение ABI ARM и спецификации Elf, я начал дизассемблировать и изучать самые маленькие тестовые программы...
❯ Формат ELF, ABI ARM и тулчейн
Начнём с самого простого: что же такое эти самые эльфы? Elf - формат исполняемых файлов, широко применяемый как в мире Unix-систем, так и в embedded-устройствах. Самые распространенные тулчейны - GCC и clang/llvm, по умолчанию собирают программы именно в этом формате и по своей сути, это прямой аналог .exe (PE) файлов из Windows. Помимо кода, Elf также содержит в себе множество секций и различных данных, при этом разработчики формата старались сделать его настолько гибким, чтобы его можно было использовать на любых архитектурах: от x86, до risc-v.
Каждая программа состоит из так называемых секций - участков кода, данных и метаданных, необходимых для её загрузки в память. Среди секций простой программы можно выделить как минимум четыре основных:
.text - хранит в себе код программы и обычно записывается в память с флагами MMU R X (чтение и выполнение)
.data - преинициализированные данные, имеет флаги R W (чтение и запись). Например, заполненная структура в C:
int a[] = { 1, 2, 3 };
.bss - не инициализированные данные, иными словами глобальные переменные, которые при старте программы должны быть забиты нулями. Имеет те же флаги, что и .data.
.rodata - различные константы: строковые, const-преинициализированные массивы, а также структуры и т.п, имеет только флаг R и на системах с MMU попытка запись в эту секцию повлечет SIGSEGV.
За загрузку всех этих секций отвечает загрузчик Elf в ядре ОС. Однако это справедливо только для простых программ, которые загружаются в фиксированный адрес виртуальной памяти и которые не используют внешние библиотеки (.so, аналог в Windows - .dll). Поскольку адрес загрузки для всех библиотек предсказать невозможно, разработчики ABI придумали позиционно-независимый код (PIC и его производное - PIE), который может загружаться в любую область памяти и оттуда выполняться.
Реализация PIC может достигаться тремя разными способами:
Первый способ заключается в использовании глобальной таблицы смещений (GOT) и релокаций. Релокации - специальные данные в Elf, которые позволяют переместить программу в другой адрес путём патчинга адресов в секции .got "на лету": иными словами, сам код (.text) остаётся позиционно-независимым (дабы библиотеку можно было загрузить один раз и использовать во множестве процессов) и обращается к GOT относительно PC, но в самом GOT (который представляет из себя массив void* addresses[]) указатели на остальные сегменты находятся так, будто программа загружается по смещению 0x0. Задача динамического линкера - посчитать абсолютный адрес для всех указателей в GOT: в простейшем случае, это got[address] += baseAddress.
Релокации могут затрагивать сразу literal pools в обход GOT, если архитектура предусматривает их наличие.
Релокацией занимается динамический линкер или интерпретатор в мире Unix (тот самый ld.so, что часто "not found" :) ), а самих релокаций есть много разных видов в зависимости от архитектуры процессора. В ARM чаще всего встречается R_ARM_REL32
Второй способ заключается в том, что мы компилируем программу так, будто она должна загружаться по фиксированному адресу 0x0 - то есть без PIC, однако просим линкер (--emit-relocs) создать информацию о всех обращениях к памяти в виде всё тех же релокаций. Вместо R_ARM_REL32, линкер создаёт релокации R_ARM_ABS32, которые можно разрешить обычным сложением.
С таким подходом количество релокаций кратно увеличивается, однако из-за отсутствия GOT немного повышается быстродействие программы (вместо трёх LDR для загрузки слова из памяти нужно всего два: из Literal pool в регистр и затем из фактической памяти).
Третий способ поддерживается не везде, но в ARM он является одним из самых распространенных в embedded-среде: код собирается с флагами /rwpi и /ropi полностью не зависит ни от GOT, ни имеет каких либо релокаций. Вместо этого, для адресации базового адреса программы он использует выделенный регистр R9, который загрузчик должен заполнить адресом, куда он загрузил программу (mov r9, textSectionBase). Такой подход теоретически чуточку быстрее, чем GOT, но медленнее второго подхода из-за необходимости добавлять сложение регистра с PC перед каждым фетчем из памяти.
Поскольку в телефонах MMU обычно не используется, эльфлоадеры загружают программы по тому адресу, что им выделяет системный аллокатор памяти и вынуждены использовать PIC. Чаще всего используются релокации (как минимум на Siemens и Motorola), на некоторых платформах используется второй подход с использованием регистра R9.
Для большей гибкости, я решил выбрать второй подход и построить свой эльфлоадер поверх уже существующих загрузчиков, обернув API прошивок в ряд собственных стандартизированных функций: работа с дисплеем, вводом, файлами, а также звуком. При этом эльфы должны собираться современным компилятором clang с поддержкой C99, чтобы была возможность легко портировать современные single-header программы по типу эмуляторов, да и в целом не писать код на манер Ansi C, когда переменную нигде нельзя объявить кроме начала блока.
Далее я сутками игрался с компиляторами и пытался заставить выдать их подходящий для моих целей код и по итогу написал скрипт для линкера, который для простоты загрузки файла объединяет все секции в один .text (таким образом остаётся всего один Program Header):
OUTPUT_FORMAT("elf32-littlearm")
SECTIONS
{
. = 0x0;
.text : {
*(.r9ptr)
*(.text*)
*(.data*)
*(.bss*)
*(.rodata*)
*(.functions)
}
.rel : {
*(.rel*)
}
/DISCARD/ : {
*(.ARM.*)
}
}
И следующий набор опций для компилятора, который устанавливает архитектуру и целевой процессор, ABI для FPU, включает генерацию релокаций и отключает выравнивание в линкере для выходного файла (иначе файлы забиты нулями и весят целых 64Кб:
CLANGFLAGS = -mno-unaligned-access -O3 -ffast-math -ffixed-r9 -T ld.script -target armv5e-none-eabi -nostartfiles -fno-exceptions -fno-rtti -mfloat-abi=soft -I$(ELFROOT) -Ilibnesemu/
LDDFLAGS = -Wl,-zmax-page-size=1,--emit-relocs
Когда компилятор наконец-то начал выдавать корректный код, я принялся писать сам эльфлоадер. За качество кода и отсутствие нормальной структуры не ругайте - это эмбеддед, тут можно ;))
На входе лоадеру поступает адрес загруженного в память эльфа и его длина. Задача эльфятника - верифицировать заголовок и убедится что он собран с подходящими параметрами:
// Read and verify ELF header
Elf32_Ehdr* hdr = (Elf32_Ehdr*)data;
PRINT("Loading ELF...");
if(hdr->e_machine != EM_ARM)
{
PRINT("Not an EM_ARM executable");
return 0;
}
if(hdr->e_ident[EI_DATA] != PLATFORM_ELF_ENDIANESS)
{
PRINT("Endianess mismatch");
return 0; // Wrong endianess
}
Проанализировать таблицу заголовков с служебной информацией о том, что находится по тому или иному смещению в файле: загружаемая секция, таблица символов или строк, а затем загрузить все секции в участок памяти, который нам выдал аллокатор. На MMU-системах адрес должен быть выровнен по размеру страницы, иначе система не даст выдать страницам флаг EXEC!
ret = (ExecInfo*)ExecAlloc(sizeof(ExecInfo));
sections = (Elf32_Phdr*)(&data[hdr->e_phoff]);
sh = (Elf32_Shdr*)&data[hdr->e_shoff];
symSectionIndex = hdr->e_shstrndx;
codeSize = 0x0;
PRINT("Processing program headers");
// Process program headers and determine total size
for(i = 0; i < hdr->e_phnum; i++) {
Elf32_Phdr hdr = sections[i];
if(hdr.p_type == PT_LOAD) {
if(hdr.p_offset == 0x0)
continue;
codeSize += hdr.p_memsz;
}
}
PRINT("Allocating memory for .text");
textSection = (char*)ExecAlloc(codeSize);
textOffset = textSection;
ret->CodeSection = textSection;
if(!textSection)
{
free(ret);
PRINT("Failed to allocate .text section");
return 0;
}
Далее найти секцию с таблицей символов и с строками, где содержатся имена символов:
PRINT("Analyzing section table");
for(i = 0; i < hdr->e_shnum; i++)
{
Elf32_Shdr sec = sh[i];
if(sec.sh_type == SHT_STRTAB && i != hdr->e_shstrndx && strTable == 0)
{
strTable = &data[sec.sh_offset];
PRINT("Found string table");
}
if(sec.sh_type == SHT_SYMTAB)
{
PRINT("Found symbol table");
symbols = (Elf32_Sym*)&data[sec.sh_offset];
symNum = sec.sh_size / sizeof(Elf32_Sym);
}
if(sec.sh_type == SHT_REL && relocs == 0)
{
UtilPrint("Found relocations");
relocs = (Elf32_Rel*)&data[sec.sh_offset];
relNum = sec.sh_size / sizeof(Elf32_Rel);
}
if(sec.sh_type == SHT_RELA)
{
PRINT("Found unsupported relocation types");
return 0;
}
}
if(!strTable || !symbols)
{
free(ret);
PRINT(".strtab or .symtab not found");
return 0;
}
А затем найти функцию ElfMain, которая служит точкой входа и пропатчить таблицу импортированных функций! На этом, загрузка эльфа завершена - можно устанавливать регистр R9 и вызывать Main!
PRINT("Relocation fix-up");
for(i = 0; i < relNum; i++)
{
Elf32_Rel rel = relocs[i];
int sym = ELF32_R_SYM(rel.r_info);
switch(ELF32_R_TYPE(rel.r_info))
{
case R_ARM_ABS32:
*((unsigned int*)&textSection[rel.r_offset]) += (unsigned int)textSection;
break;
case R_ARM_JUMP24:
break;
case R_ARM_CALL:
break;
default:
PRINT("Unsupported relocation type");
}
}
PRINT("Patching import table");
// Analyze symbol table and patch all imported function pointers to real counterparts
for(i = 0; i < symNum; i++)
{
Elf32_Sym sym = symbols[i];
uint8_t* symName = &strTable[sym.st_name];
int symType = ELF32_ST_TYPE(sym.st_info);
if(symType == STT_OBJECT && strstr((const char*)symName, "SYS_"))
{
int funcNumber = ExecFindFunction(symName);
if(funcNumber == -1)
{
PRINT("Failed to import function: ");
UtilPrint((char*)symName);
PRINT("");
continue;
}
//drawDebug(FuncExportTable[funcNumber].Pointer == 0 ? "Not OK" : "OK");
*((unsigned int*)&textSection[sym.st_value]) = (unsigned int)FuncExportTable[funcNumber].Pointer;
}
if(symType == STT_FUNC && strstr((const char*)symName, "ElfMain"))
{
PRINT("ElfMain function is found");
ret->Main = (ExecMainFunction)&textSection[sym.st_value];
}
В Elf уже есть механизм импорта функций из сторонних библиотек, называется Platform Linkage Table. Для импорта функций прошивки, эльфлоадер Siemens использует SWI (сисколлы, что-то типа программных прерываний в x86 - int 10h и т.п.), Motorola же патчит thunk-функции на лету, которые сами вызывают настоящую функцию:
А я решил поступить несколько изящнее. В моем эльфятнике, функции импортируются с помощью специального макроса, который создаёт переменную-указатель на функцию, который изначально располагается в секции .functions. При этом с помощью ключевого слова asm, символу присваивается иное имя - с префиксом SYS_, которое означает то, что загрузчик эльфа должен пропатчить адреса функций на реальные (которые предварительно зарегистрированы в рантайме) в процессе загрузки программ и таким образом, избежать thunk-функций и позволить оптимизатору легко выкидывать указатели на неиспользуемые функции:
#ifndef LOADER
#define IMPORT(name, ret, ...) __attribute__ ((section(".functions"))) ret (* name )( __VA_ARGS__ ) asm( "SYS_" #name )
#define IMPORTNOARGS(name, ret) __attribute__ ((section(".functions"))) ret (* name )() asm( "SYS_" #name )
#else
#define IMPORT(name, ret, ...) ret name( __VA_ARGS__ )
#define IMPORTNOARGS(name, ret) ret name()
#endif
Что самое забавное, лучший способ отладить эльфлоадер - в QEMU с GDB под Linux. Однако я решил время не терять и отлаживал его сразу на смартфоне с Windows Mobile. А раз WM стал первой поддерживаемой платформой - на нем мы с вами и реализуем рантайм.
❯ Портируем на Windows Mobile (CE)
Поскольку всю жизнь я сижу в основном на Windows, а WinAPI в CE практически полностью копирует десктопную версию, никаких проблем с портированием рантайма не возникло. Единственный выбор который передо мной встал: стоит ли прокидывать stdlib из хост-системы в "эльфятник", или же воспользоваться реализацией newlib в clang/gcc. В процессе портирования на другие платформы выяснилось, что нормально libc реализован, по сути, только на Windows, во все остальных реализациях были лишь самые основные функции по типу malloc, free, memcpy, strcmp и т.п. Поэтому я решил не городить велосипеды и прокинул из хост-системы лишь аллокатор - т.е malloc и free:
// stdlib
IMPORT(elf_malloc, void*, int size);
IMPORT(elf_free, void, void* ptr);
/*IMPORT(elf_strcmp, int, char* str1, char* str2);
IMPORT(elf_strcpy, char*, char* dst, char* src);
IMPORT(elf_strlen, int, char* str);
IMPORT(elf_strstr, char*, char* string, char* substring);
IMPORTNOARGS(elf_rand, int);
IMPORT(elf_memcpy, void*, void* dst, const void* src, uint32_t length);
IMPORT(elf_memset, void*, void* dst, int what, uint32_t length);
IMPORT(elf_memmove, void*, void* dst, void* src, uint32_t length);*/
Далее я сразу решил, что платформозависимые функции для работы с дисплеем использовать не буду и из хост-системы мне нужен будет лишь указатель на фреймбуфер, а блиттинг, рисование текста и прочие операции я реализую сам. На первый взгляд может показаться что это единственное верное решение, однако на практике в некоторых телефонах (Motorola E398, Razr V3) активно использовались 2D GPU от ATI и Nvidia, которые рисуют (BitBLT) изображение значительно быстрее любой программной реализации.
Ниже представлена черновая реализация без преобразования пиксельформатов (поскольку на подавляющем числе телефонов использовался 565) и поддержки прозрачности через колоркей. Её можно оптимизировать до быстрого копирования по сканлайнам через memcpy:
for(i = 0; i < bitmap->Height; i++)
{
for(j = 0; j < bitmap->Width; j++)
{
LCD_PLOT_565(clamp(x + j, 0, lcd->Width), clamp(y + i, 0, lcd->Height), bmp[i * bitmap->Width + j]);
}
}
С точки зрения отрисовки текста, нативные функции платформ тоже предоставляют крутые фичи по типу сглаживания, поддержки не-моноширинных шрифтов, множества кодировок, а также различные типы выравнивания. Но здесь встаёт вопрос с портативностью таких решений: разные рендеры шрифтов оперируют по разному и не все из них используют в качестве системы координат пиксели. Соответственно, я пошёл по олдовому "эмбеддерскому" пути и сделал обычные битмапные шрифты, которые (пока) статически слинкованы с самим эльфятником.
__inline int LcdDrawChar(LcdInfo* lcd, char chr, uint32_t x, uint32_t y, uint16_t color)
{
if(x >= 0 && y >= 0 && x + FONT_WIDTH < lcd->Width && y + FONT_HEIGHT < lcd->Height)
{
int i, j;
unsigned char* glyph = &embedded_font[chr * 8];
for(i = 0; i < FONT_HEIGHT; i++)
{
short* fb = &((short*)lcd->Pixels)[(y + i) * lcd->Width + x];
for(j = 0; j < FONT_WIDTH; j++)
{
if((*glyph >> (FONT_WIDTH - j)) & 0x1)
*fb = color;
fb++;
}
glyph++;
}
return true;
}
return false;
}
void LcdDrawString(LcdInfo* lcd, char* str, uint32_t x, uint32_t y, uint16_t color)
{
SWITCH_CONTEXT;
if(lcd && x >= 0 && y >= 0)
{
unsigned int i;
for(i = 0; i < strlen(str); i++)
{
if(!LcdDrawChar(lcd, str[i], x, y, color))
return; // Out of screen
x += FONT_WIDTH;
}
}
END_CONTEXT;
}
Отладив эльфлоадер, я написал небольшую тестовую программу для вывода картинки и текста:
#include <system.h>
int ElfMain(void* ptr)
{
LcdInfo* lcd = lcdInit();
lcdDrawBitmap(lcd, bitmap, 0, 0);
lcdDrawString(lcd, "Test", 0, 0, COLOR_BLUE)
return 100;
}
И получил следующий результат:
Вот теперь всё работает! Пришло время портировать эльфятник на весьма необычную платформу, о потенциалах моддинга которой знают единицы...
❯ Портируем на MRP/MRE
И имя этой платформе, вернее даже двумя платформам - MRP и WRE. Эти платформы использовались на бюджетных китайских телефонах с 2007 по 2016 год. Встретить их можно было везде: легендарная Nokla TV E71/E72, клоны 6700, бюджетные телефоны Fly/Explay/DEXP и даже в оригинальных телефонах Nokia на платформе S30+ (например 230)!
И хотя люди часто считали такие устройства бесполезными в плане установки сторонних приложений, многие ранние "нонейм"-телефоны поддерживали запуск нативных программ через небольшой костыль - установку специального "загрузчика" dsm_gm.mrp и ввод комбинации *#220807# в номеронабиратель. Конечно, знали об этом костыле единицы и в 2010 году MediaTek решила сделать свою платформу под названием MRE (MAUI Runtime Environment), приложения для которой можно было запускать прямо из проводника без установки! SDK для обеих платформ сейчас свободно лежит в сети.
Обе платформы, по сути, занимаются тем же самым, что и мой эльфятник - прокидывают нативные функции MMI (оболочка телефона) в приложения и для загрузки позиционно-независимых программ используют третий подход с регистром R9, который обязательно необходимо где-то хранить и восстанавливать. Изначально мой эльфятник использовал такой же подход, из-за чего я написал отдельный костыль для "свичнга" контекстов, причем восстановление R9 я делал в отдельной функции из-за бага ассемблера в ADS:
#define SWITCH_CONTEXT unsigned int staticBase; __asm { MOV staticBase, sb;
LDR r0, [sb];
MOV sb, r0 }
#define ELF_CONTEXT(ptr) unsigned int staticBase; void* elfStaticBase = ptr; __asm { MOV staticBase, sb; \
MOV r9, elfStaticBase }
#define END_CONTEXT RestoreSB(staticBase);
Но я не учел то, что MMI хоть и построены по event-based принципу, в них нельзя так просто взять и сделать while(true) {}, а необходимо использовать таймеры, что влечет за собой постоянные костыли с свичингом контекстов что по итогу только снижает производительность. По итогу я перешел на релокации и реализовал проброс таймеров.
Во всем остальном, MRP и MRE простые как табуретка, никаких проблем с пробросом ввода и графики не возникло:
LcdInfo* LcdInit()
{
LcdInfo* ret;
ret = (LcdInfo*)malloc(sizeof(LcdInfo));
ret->Width = screenInfo.width;
ret->Height = screenInfo.height;
ret->Pixels = (void*)w_getScreenBuffer();
return ret;
}
void LcdFree()
{
}
void LcdLock(LcdInfo* info)
{
}
void LcdFlush(LcdInfo* info)
{
mrc_refreshScreen(0, 0, 240, 320);
}
И вот, наша программа уже запускается на двух совершенно разных ОС без каких либо проблем!
❯ А если что-то посложнее Hello, world?
Наверняка у читателя возникнет вопрос мол "окей, твой эльфятник может и способен запускать простые программы, но как насчет чего-то посложнее?". И конечно-же, для тестов я решил портировать не абы что, а целый эмулятор NES! В конце-концов, одна из целей разработки такого эльфятника - возможность запускать Java-игр и эмуляторов на многих кнопочных телефонах из нулевых.
Какое то время назад, я обнаружил весьма шустрый эмулятор NES от неизвестного разработчика из Китая. Код был неважного качества, никаких копирайтов в нём не было. Но поскольку сам эмулятор был быстрый (быстрее, наверное, только vNesC, который является прямым source-портом Java-эмулятора vNes на C), я отвязал его от целевой платформы и превратил в небольшую библиотеку для легкого портирования на любые платформы путем вызова всего нескольких функций:
typedef struct {
uint16_t* FrameBuffer;
uint8_t* JoyState;
} emuContext;
emuContext* emuInitialize();
uint8_t emuLoadROM(void* rom, int length);
void emuReset();
void emuDoFrame();
void emuShutdown();
И, соответственно, базовый порт на наш эльфятник выглядит примерно так:
#include <string.h>
#define FUNC_PROTOTYPES
#include <system.h>
#include <nes.h>
#include "nes_rom.h"
emu_context* ctx;
LcdInfo* lcdInfo;
void EmuTick()
{
emuDoFrame();
LcdLock(lcdInfo);
short* pixels = (short*)lcdInfo->Pixels;
for(int i = 0; i < EMU_FRAMEBUFFER_HEIGHT; i++)
{
memcpy(&pixels[i * lcdInfo->Width], &ctx->FrameBuffer[i * EMU_FRAMEBUFFER_WIDTH], lcdInfo->Width * 2);
}
LcdFlush(lcdInfo);
}
void EmuSetupTimer()
{
TimerAttach(1, EmuTick); // As fast as possible
}
void EmuSetupRegularLoop()
{
while(true)
EmuTick(); // TODO: If elfloader port will be usable on Android, add FPS limit :)
}
int ElfMain(unsigned int* basePtr, void* test)
{
lcdInfo = LcdInit();
ctx = emuInitialize();
if(!emuLoadROM(nes_rom, sizeof(nes_rom)))
{
UtilPrint("Failed to load ROM");
return 100;
}
emuReset();
switch(GetMainLoopType())
{
case PLATFORM_LOOP_MMI_TIMER:
EmuSetupTimer();
break;
case PLATFORM_LOOP_REGULAR:
EmuSetupRegularLoop();
break;
}
return 100;
}
А вот и результат:
❯ Заключение
Вот так и можно написать программу, которая бесшовно работает на трёх разных операционных системах, которые не имеют ничего общего друг с другом! На первый взгляд всё это кажется сложным, однако на практике очень просто и интересно! Нужно лишь взять дизассемблер в зубы и немножечко изучить то, что выдаёт компилятор.
А если вам интересна тематика ремонта, моддинга и программирования для гаджетов прошлых лет — подписывайтесь на мой Telegram-канал «Клуб фанатов балдежа», куда я выкладываю бэкстейджи статей, ссылки на новые статьи и видео, а также иногда выкладываю полезные посты и щитпостю. А ролики (не всегда дублирующие статью) можно найти на моём YouTube канале.
Очень важно! Разыскиваются девайсы для будущих статей!
Друзья! Если вам понравилась сегодняшняя статья про разработку эльфов, то спешу объявить: для подготовки будущих материалов с разработкой самопальных игрушек под необычные устройства, объявляется розыск телефонов и консолей! В 2000-х годах, китайцы часто делали дешевые телефоны с игровым уклоном — обычно у них было подобие геймпада (джойстика) или хотя бы две кнопки с верхней части устройства, выполняющие функцию A/B, а также предустановлены эмуляторы NES/Sega. Фишка в том, что на таких телефонах можно выполнять нативный код и портировать на них новые эмуляторы, чем я сейчас занимаюсь, а затем написать об этом подробную статью и записать видео! Если у вас есть телефон подобного формата и вы готовы его задонатить или продать, пожалуйста напишите мне в Telegram (@monobogdan) или в комментарии. Также интересуют смартфоны-консоли на Android (на рынке РФ точно была Func Much-01), там будет контент чуточку другого формата :)
А также я ищу старые (2010-2014) подделки на брендовые смартфоны Samsung, Apple и т. п. Они зачастую работают на весьма интересных чипсетах и поддаются хорошему моддингу, парочку статей уже вышло, но у меня ещё есть идеи по их моддингу! Также может у кого-то остались самые первые смартфоны Xiaomi (серии Mi), Meizu (ещё на Exynos) или телефоны на Linux (например Motorola EM30, RAZR V8, ROKR Z6, ROKR E2, ROKR E5, ZINE ZN5 и т. п., о них я хотел бы подготовить специальную статью и видео т. к. на самом деле они работали на очень мощных для своих лет процессорах, поддавались серьезному моддингу и были способны запустить даже Quake!). Всем большое спасибо за донаты!
Ностальгия: "dBaseII v2.3b" работа с базой данных на Osborne OCC1
dBase — семейство широко распространённых систем управления базами данных, а также язык программирования, используемый в них. Самая первая СУБД этого семейства называлась dBase II (см. #dBase II) и была выпущена в 1980 году компанией Ashton-Tate под CP/M, позже появились версии для Apple II, Apple Macintosh, UNIX, VMS и IBM PC под DOS. Версия для PC вместе с пришедшими ей на смену dBase III и dBase IV были несколько лет одной из самых продаваемых программ. Долгое время dBase не портировали под Microsoft Windows, в результате чего в этой нише у программы оказались сильные конкуренты — Paradox, Clipper, FoxPro и Microsoft Access.
В 1991 году компания Borland купила Ashton-Tate. В 1999 все права на dBase перешли к новообразованной dBase Inc, которая в 2004 году сменила своё название на «dataBased Intelligence Inc».
Поскольку формат данных dBase не был закрытым, с середины 80-х множество компаний стало производить свои диалекты языка и версии системы. В результате появилось множество похожих на dBase программ — FoxPro (современная Visual FoxPro), Arago, Force, dbFast, Clipper, Xbase++, FlagShip, Recital, CodeBase, MultiBase, Harbour/xHarbour. Собирательно их всех именуют xBase.
История создания
Инженер NASA Уэйн Рэтлифф (Wayne Ratliff), в то время работавший по контракту в JPL, написал систему управления базами данных сообразно собственному видению этой новой тогда технологии. Автор дал программе амбициозное название «Вулкан», и пытался — правда, без особого успеха — продавать её. Однажды «Вулкан» попался на глаза Джорджу Тейту (George Tate) — ловкому дельцу, занимавшемуся программным бизнесом.
Судьба Джорджа, в основном, напоминает рекламную открытку американского образа жизни — это типичная история «сэлф-мэйд-мэна», написанная с поправкой на антураж ещё не родившегося тогда стиля «киберпанк». Исключенный из школы молодой человек без специальности и особых планов на будущее стал легкой добычей армейских вербовщиков. Джордж Тейт служил в ВВС США, а затем работал мастером по ремонту радиоаппаратуры. Игра случая — в 1974 г. в числе других энтузиастов он приобрел набор для сборки компьютера «Альтаир». Закончив сборку, Джордж Тейт вдруг обнаружил, что все его знания о машине сводятся к тому, как она включается. Но заряд увлеченности оказался настолько силен, что начинающий «чайник» со временем не только осилил начала компьютерной «премудрости», но и стал отличным специалистом в этой области. Тем более, что на тех порах, чтобы владеть компьютером, необходимо было хорошо разбираться в радиоэлектронике, а растущая армия простых пользователей была, мягко говоря, далека «от всей этой премудрости», поэтому у человека, занимающегося ремонтом радиоаппаратуры, были все шансы далеко продвинуться в этой области. Джорж Тэйт стал подрабатывать ремонтом компьютеров, потом устроился в фирму, производящую компьютерные терминалы управляющим по сбыту. В 1980 г. он вместе со своим приятелем Хэлом Лашли занялся продажей программного обеспечения. Прослышав о существовании малоизвестной тогда системы «Вулкан», Тейт и Лашли заключили с Рэтлиффом контракт, который предусматривал их исключительное право на распространение этой программы. Поскольку к тому времени на название «Вулкан» уже заявила свои права другая компания, партнеры решили наименовать данное изделие как-то иначе.
dBase II
Название «dBase II» предложил рекламный агент. По его мнению, оно звучало весьма респектабельно с технической точки зрения и, кроме того, содержало тонкий намек на то, что это некая новая и, видимо, улучшенная версия своего предшественника — системы dBase.
Конечно, никакого предшественника, который следовало бы улучшить, не было и в помине, однако система dBase II действительно имела ощутимые преимущества по сравнению с другими программами, ориентированными на решение данного класса задач.
В январе 1981 г. по всей стране началась шумная реклама этой системы, очень скоро ставшей новым «бестселлером». И почти столь же стремительно Рэтлифф, Лашли и Тейт пополнили все возрастающие ряды миллионеров, сделавших состояния на программном обеспечении.
dBase III
dBase III и её расширенная версия dBase III+ появились в 1986 году. Снабженные оригинальной средой разработки и некоторыми средствами манипуляции данными, они стали наиболее популярными СУБД для IBM PC. Успех dBase III+ предопределил появление на рынке многочисленных клонов и языков программирования, объединённых прижившимся среди профессионалов понятием «xBase». Значительного успеха добилась компания Fox Software, Inc., выпустившая собственную версию СУБД под названием FoxBase. В её состав входил псевдокомпилятор, значительно ускорявший работу финального приложения, и достаточно комфортная (для того времени) среда разработки. Преимущества FoxBase быстро выдвинули её в первые ряды коммерческих СУБД, однако с появлением в 1987 году компилятора Clipper Summer’87 именно он стал основным средством разработчиков-профессионалов.
dBase IV
dBase IV была первоначально выпущена фирмой Ashton-Tate в 1988 году, с 1991 года продукт был выкуплен Borland inc
dBASE Mac
dBase Mac - это система управления базами данных для Apple Macintosh, выпущенная компанией Ashton-Tate в 1987 году. Хотя графический интерфейс хвалили в прессе, приложение было настолько медленным, что стало чем-то вроде шутки в отрасли. Продажи были плачевными, и Ashton-Tate в конце концов решила отказаться от dBase Mac и вместо этого перенести dBase IV на Mac с интерфейсом, похожим на DOS. Затем продукт был продан ряду сторонних разработчиков, но они не имели большого успеха, и он исчез с рынка в середине 1990-х годов.
Язык программирования dBase
Для обработки данных dBase предоставила подробные процедурные команды и функции для[30] открывайте и просматривайте записи в файлах данных (например, USE, SKIP, GO TOP, GO BOTTOM и GO recno), управляйте значениями полей (ЗАМЕНЯЙТЕ и СОХРАНЯЙТЕ) и управляйте текстовыми строками (например, STR() и SUBSTR()), числами и датами. dBase - это язык разработки приложений и интегрированная навигационная система управления базами данных, которую Эштон-Тейт назвал "реляционной", но она не соответствовала критериям, определенным реляционной моделью доктора Эдгара Ф. Кодда. В нем использовалась архитектура интерпретатора среды выполнения, которая позволяла пользователю выполнять команды, вводя их в командной строке "точечная подсказка". Аналогичным образом, программные скрипты (текстовые файлы с расширениями PRG) запускались в интерпретаторе (с помощью команды DO). Программы dBase были просты в написании и тестировании; бизнесмен, не имеющий опыта программирования, мог разрабатывать приложения. Со временем конкуренты Ashton-Tate представили так называемые продукты-клоны
Ностальгия: "Norton Utilities 8.0" процесс работы
Тот, кто застал эпоху «до Microsoft Windows», прекрасно помнит эти «синенькие панельки». Файловый менеджер Norton Commander (как позже и его клон — Volkov Commander) безраздельно царствовал на персоналках конца восьмидесятых и начала девяностых. Любопытно, но факт: эту легендарную программу написал не Питер Нортон, как многие считают, а совершенно другой разработчик — Джон Соча. К слову, Norton Commander никогда не был флагманским продуктом компании Peter Norton Computing.
Питер Нортон появился на свет 14 ноября 1943 года в городе Абердин, штат Вашингтон, но вскоре после его рождения семья перебралась в Сиэтл. Окончив школу, Нортон поступил в колледж Рид в городе Портленд, штат Орегон. Успешно закончив учебу в 1965 году, молодой программист поступил в компанию Boeing, где работал с мейнфреймами, позже он устроился в лабораторию реактивного движения НАСА. Когда в 1981 году корпорация IBM выпустила на рынок свою персоналку IBM PC, Питер Нортон стал одним из ее первых пользователей.
В начале восьмидесятых правительство США решило оптимизировать расходы на развитие аэрокосмической промышленности, и Питер Нортон попал под сокращение. Чтобы хоть как-то свести концы с концами, он стал писать программы под MS-DOS на заказ. Однажды Питер случайно удалил разрабатываемую им программу, но вместо того чтобы написать код заново, он придумал специальную утилиту, с помощью которой сумел восстановить файл. Приложение получило название Norton Unerase. Этот инструмент очень понравился его друзьям и коллегам — в MS-DOS не было «корзины», а случайное удаление нужных файлов считалось обычным делом. Дополнив свое детище еще несколькими полезными программами, Питер Нортон получил набор утилит, который так и назвал — Norton Utilities. А для продажи этого продукта в 1982 году он основал компанию «Peter Norton Computing».
Ядром Norton Utilities стал тот самый инструмент для восстановления удаленных файлов в файловой системе FAT, если кластеры, которые файл занимал до удаления, еще не были перезаписаны. Фактически, Питер Нортон изобрел новый класс программного обеспечения для PC: средства для восстановления данных. Вскоре в этой коммерческой нише у него появились конкуренты, в частности, пакет программ PC Tools, но, тем не менее, Нортон являлся здесь первопроходцем.
Peter Norton Computing стала одной из первых фирм, продававших коммерческий софт для MS-DOS, хотя существовала версия Norton Utilities и для IBM PC DOS. Компания обладала стартовым капиталом в 30 000 долларов — это были все накопления Питера Нортона — и одним-единственным компьютером IBM PC. Собственно, поначалу и сотрудник в ней числился всего один: он же директор, он же учредитель. Питер Нортон продавал диски с утилитами, посещая в качестве коммивояжера офисные центры и распространяя рекламные буклеты на различных компьютерных выставках и мероприятиях.
Однако первыми на него обратили внимание не потенциальные покупатели утилит, а корпорация Microsoft, вернее, ее издательское подразделение: в 1983 году Microsoft Press предложило Питеру Нортону написать книгу по программированию. Эта книга, вышедшая в 1985-м под названием «Руководство программиста Питера Нортона по IBM PC», быстро стала бестселлером. Первое время писательство приносило автору не меньший доход, чем софтверная компания, при этом книга стала отличным рекламным инструментом, повысившим узнаваемость бренда.
В 1984 году, когда Питер Нортон трудился над собственной книгой, аспирант факультета прикладной физики Корнельского университета Джон Соча работал над файловым менеджером для MS-DOS, который он назвал Visual DOS, или, сокращенно, VDOS. «Видос» был написан на Си с применением Ассемблера, его интерфейс включал две настраиваемых панели со списками файлов, а операции над ними можно было выполнять с помощью набора горячих клавиш. При нажатии CTRL и ALT можно было использовать дополнительные функции клавиш, панели позволяли переключаться между разными дисками, а при желании на них можно было вывести древовидную структуру папок или развернутую информацию о выбранном файловом объекте. В общем, получился удобный, компактный, быстрый и полезный инструмент для работы с файлами и папками без помощи мыши, которого в MS-DOS очень не хватало.
Джон Соча – человек, который придумал термин «заставка». И, может быть даже создал первую заставку. На самом деле в зачаточном состоянии заставка (ночное небо со звездами) была второй отличительной чертой Norton Commander 3.0 вместе с двумя панелями синего фона. Эту экранную заставку называли классической DOS заставкой и ассоциировали не с Нортон, а с DOS. В 2001 году Джо Форстер написал Звездную ночь, которая точно воспроизводит классическую заставку Norton Commander. Помимо создания программ у Сочи был и другой источник дохода: он подписал контракт на несколько книг с Microsoft Press. Именно в этом издательстве Соча и познакомился с Питером Нортоном. Быстро оценив рыночные перспективы нового файлового менеджера (у которого на тот момент существовал только один конкурент, программа XTree), Нортон предложил молодому разработчику сотрудничество. Джон Соча стал директором по исследованиям и разработкам Peter Norton Computing, а VDOS был выпущен на рынок под названием Norton Commander 1.0.
Вскоре этот файловый менеджер завоевал огромную популярность среди пользователей, и самую большую — в странах Восточной Европы и СССР. Многие пользователи даже не подозревали, что это не «родной» интерфейс DOS, ассоциируя операционную систему с самим Norton Commander. К слову, Джон Соча является автором еще одного изобретения — «экранной заставки». То самое знаменитое «звездное небо» впервые дебютировало именно в Norton Commander, и также воспринимается многими, как необъемлемая часть MS-DOS, хотя никакого отношения непосредственно к операционной системе она на самом деле не имеет.
Вскоре этот файловый менеджер завоевал огромную популярность среди пользователей, и самую большую — в странах Восточной Европы и СССР. Многие пользователи даже не подозревали, что это не «родной» интерфейс DOS, ассоциируя операционную систему с самим Norton Commander. К слову, Джон Соча является автором еще одного изобретения — «экранной заставки». То самое знаменитое «звездное небо» впервые дебютировало именно в Norton Commander, и также воспринимается многими, как необъемлемая часть MS-DOS, хотя никакого отношения непосредственно к операционной системе она на самом деле не имеет.
Важной частью маркетинговой политики Peter Norton Computing стало использование фотографии самого Питера Нортона на всех упаковках продуктов этой компании (традиция сохранилась даже после покупки фирмы холдингом Symantec). Тогда, в восьмидесятых, в сфере IT еще не существовало понятия «личный бренд», и Питер Нортон был одним из первых бизнесменов, решивших активно развивать его — позже по этой проторенной тропинке пройдут Джон Макафи, Евгений Касперский и другие предприниматели. В 1986 году доход Peter Norton Computing достиг 5 миллионов долларов — довольно неплохой показатель для небольшой компании с численностью персонала до сотни сотрудников.
Еще одним продуктом Peter Norton Computing, практически незнакомым русскоязычной аудитории, стал формат Norton Guides — электронные руководства и справочники в гипертекстовом формате для DOS, появившемся еще до рождения HTML. В этом формате публиковались все мануалы к продуктам Питера Нортона, а также несколько электронных книг — по Ассемблеру, Си, Бейсику и языку Forth. «Гайды» распространялись на дискетах, а многие разработчики софта использовали этот формат для создания собственных руководств пользователя. В марте 1990 года Peter Norton Computing выпустила программу для резервного копирования Norton Backup — одну из первых программ с подобным функционалом, а в июле вышла версия Norton Utilities для Apple Macintosh. Но эти программы стали фактически последними самостоятельными разработками фирмы Питера Нортона.
Коллеги вспоминали, что Питер Нортон исповедовал простой принцип: «мы будем заниматься бизнесом, пока это весело». Веселье закончилось в 1990 году, когда Питер продал Peter Norton Computing компании Symantec за 70 миллионов долларов, а сам получил одну треть акций Symantec на сумму около 60 миллионов и место в совете директоров Symantec. Следующий флагманский продукт — Norton AntiVirus — был выпущен в декабре 1990 года, когда компания Питера Нортона уже находилась под управлением Symantec.
Сейчас Питер Нортон наслаждается жизнью на пенсии в калифорнийском городке Санта-Моника. Он входит в советы директоров Калифорнийского технологического института, Калифорнийского института искусств, школы Crossroads в Санта-Монике, Музея современного искусства в Нью-Йорке, а еще является почетным попечителем колледжа Рид, где когда-то учился. Автор Norton Commander Джон Соча покинул компанию, организовал несколько успешных стартапов и вполне успешен в бизнесе. А программные продукты под торговой маркой «Norton» продолжают развиваться по сей день.
Минута ностальгии
Я откопал свои первые игры на диске, на болванке :) 2006 года мне тогда было 16 лет, и это был мой первый компьютер. Уже тогда это был ооочень старый компьютер пень 3 причём тот который "на картридже" и аж 512мб ОЗУ и графикой нвидэ с 32 МЕГАБАЙТАМИ и HDD на 40 гигов с 3 мя разделами и виндой 98 на борту:) Для меня тогда комп был сравни космическому кораблю, я до сих пор помню что мать на день рождения попрятала все части по дому и я их утром искал думая что это наверное сон.
Как потом узнал мать на комп копила несколько лет и это был БУ комп за 10 тысяч который она привезла на электричке из другого города на своём горбу. Я конечно же говорил что он для учёбы :))) И внезапно я на нём и правда учился, я его ломал потом чинил так я научился сам переставлять винду и ставить софт :) Причём тогда интернета в нашем посёлке не было и всё было ТОЛЬКО на дисках. И так как мне было интересно то у меня был на компе и фотошоп, и автокад, и видеоредакторы и аудиоредакторы (и я был очень терпеливым чтобы на этом работать на таком компе) . И вот одной из моих покупок был диск на котором красовалась надпись VIsual Basic 6 и самоучитель к нему :)))) И это и был мой первый язык программирования который я освоил сам вообще без посторонней помощи, тогда в 16 лет я не умел писать циклы зато я научился писать условия :))) И я пытался вообще все задачи решать через условия :))
И вот в 2025 я нашёл диск на который я записал проекты которые думал могут когда то пригодиться или типо того важный софт как я тогда думал, игры всего 2 и они не закончены. И чё то я решил поделиться сим чудом из расчёта наверное просто проржать :)))
Проекта по этой игре у меня не сохранилось есть только сама игра
Ко второй игре есть проект :)
В общем вся эта фигня вот тут
если кто то захочет это поколупать :) для запуска проекта Just Lice Heaven надо скопировать папку 125 в с программ файлс
Эхх ностальгия :))



















































































