Забавные новости 0й-Ti :)

Тема в разделе "WASM.HEAP", создана пользователем UbIvItS, 18 июн 2018.

  1. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.445
    Адрес:
    Россия, Нижний Новгород
    Это как?)
     
  2. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.347
    Ну, тогда классно. А то там выше один крендель какие-то тулчейны кастомные пересобирал на ночных сборках раста (не уточнил, правда, сколько тот хелловорлд в итоге компилился по времени), чтобы один файлик скомпилить.
     
  3. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.295
    Это когда спецы не разобрались и на ровном сесте обвинили тебя чем-то.
     
  4. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.445
    Адрес:
    Россия, Нижний Новгород
    Да: дело в том, что в каждом языке есть набор предкомпилированных библиотек под целевую архитектуру или платформу.
    Согласен, совсем неясно, как так получилось, что под чрезвычайно популярный 16-битный bare metal из восьмидесятых не оказалось std из коробки.
    Но мы исправили это упущение, пересобрав стандартную либу под нас.

    И заметь, мы один раз настроили проект, привязав его к нужной архитектуре, и затем каждый может собрать его одним cargo build: сначала скачается и соберётся сам тулчейн, затем соберётся проект.
    В одну команду!
    То есть, сборка любого проекта, независимо от зависимостей и целевых архитектур, независимо от хостовой операционки выглядит примерно так:
    Код (Text):
    1. git clone https://github.com/user/project
    2. cd ./project
    3. cargo build
    И более того, мы можем привязаться не просто к каналу stable/beta/nightly, но и к конкретному билду компилятора, чтобы была гарантированная воспроизводимость сборок. Это актуально для nightly, поскольку в нём могут быть ломающие изменения.
    Насчёт nightly в целом - согласен, писать на нём в продакшн не очень хорошо. Но мы и не пишем в продакшн 16-битные змейки, будем честны)

    Уточняю: около семи секунд на сборку всего тулчейна на i9-9900k. А все последующие сборки мгновенные.

    На то они и спецы, их слово закон, фундамент)

    Но мы уходим от темы: rmn, сказал "А" говори и "Бэ" - жду ссылочки на первоисточники.
     
  5. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    456
    В айти мире, как в аптеке, всё имеет суть и вес.
    Языку, как человеку, имя нужно позарез.
    Имя вы не зря даёте, я скажу вам наперёд,
    Как язык вы назовёте, так он обществу зайдёт.
    Как язык вы назовёте, так он обществу зайдёт.

    Назовите си плюс-плюсом и скомандуйте вперёд,
    И язык полюбят люди, опенсорц и Microsoft.
    А вот «ржавым» назовёте, не уйдёте от беды,
    Его хейтить будут люди из-за каждой ерунды.
    Его хейтить будут люди из-за каждой ерунды.

    [​IMG]
     
    CaptainObvious, Rel и Mikl___ нравится это.
  6. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.445
    Адрес:
    Россия, Нижний Новгород
    Итак, мы попробовали x32, попробовали x16. В нашем триптихе безумия не хватает x64.
    Сегодня мы не будем жестить: мы напишем маленькое приложение для UEFI.

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

    Спецификацию UEFI можно найти на официальном сайте.
    Эталонной реализацией является EDKII, он же Tianocore - именно на нём производители железа основывают свои прошивки.
    Альтернативной реализацией является Project Mu от Microsoft, который, впрочем, тоже основан на EDKII.

    UEFI предоставляет приложению набор интерфейсов - протоколов. У каждого протокола своя область ответственности: например, отдельный протокол для обработки ввода, отдельный протокол для работы с GPU и т.д.
    Наборы протоколов объединены по смыслу в отдельные "пакеты" (папки с суффиксом Pkg в корне EDKII).
    Производитель по желанию реализует дополнительный функционал в отдельных пакетах, но один пакет должен быть всегда - это пакет MDE (Module Development Environment).
    Все дополнительные модули основываются на MDE, а тот, в свою очередь, реализует базовый функционал: аллокаторы, поддержку многопроцессорности и файловых систем, ввод и подобное.

    Готовое приложение представляет собой обыкновенный майкрософтовский PE-файл с расширением .efi.
    Чтобы запустить приложение, достаточно отформатировать флешку в FAT32, положить приложение в /efi/boot/bootx64.efi, затем отключить в BIOS'e SecureBoot (если он включен) и загрузиться с флешки.

    Для Rust существует несколько биндингов UEFI: uefi-rs, r-efi или efi.
    Мы будем использовать uefi-rs как самый удобный и распространённый.

    А что же мы будем писать? А писать мы будем то, о чём вы всегда мечтали, но стеснялись попросить: мы нарисуем портрет Остина Пауэрса!
    Итак, cargo new austin, let's go!

    Первым делом подключаем нужные либы: uefi и какой-нибудь декодер jpeg, работающий в no_std - мой выбор пал на zune-jpeg. А для логов возьмём log.
    Код (Text):
    1.  
    2. [package]
    3. name = "austin"
    4. version = "0.1.0"
    5. edition = "2021"
    6.  
    7. [profile.dev]
    8. panic = "abort"
    9.  
    10. [profile.release]
    11. panic = "abort"
    12. lto = true
    13.  
    14. [dependencies]
    15. log = "0.4"
    16. uefi = { version = "0.26", features = ["alloc"] }
    17. uefi-services = "0.23"
    18. zune-jpeg = { version = "0.4", default-features = false }
    19.  
    UEFI передаёт в точку входа указатель на таблицу BootServices, в которой есть функции для запроса протоколов и для получения информации об окружении - например, для доступа к файловой системе, с которой мы загрузились.
    За работу с файловой системой отвечает протокол SimpleFileSystem, за графику - GraphicsOutputProtocol (или GOP, как общепринятое сокращение).
    А дальше дело за малым: прочитать с диска картинку, раздекодить её в массив BGRA (именно в таком виде фреймбуффер хранит пиксели, игнорируя байт альфа-канала), вписать её в размеры экрана и записать итоговую картинку во фреймбуффер.
    Код (Rust):
    1. #![no_std]
    2. #![no_main]
    3. #![warn(clippy::pedantic)]
    4.  
    5. extern crate alloc;
    6.  
    7. use alloc::vec::Vec;
    8. use uefi::proto::console::gop::{BltOp, BltPixel, BltRegion, GraphicsOutput};
    9. use uefi::{prelude::*, CStr16};
    10. use uefi::proto::media::file::{Directory, File, FileAttribute, FileMode, FileType, RegularFile};
    11.  
    12. use zune_jpeg::zune_core::colorspace::ColorSpace;
    13. use zune_jpeg::zune_core::options::DecoderOptions;
    14. use zune_jpeg::JpegDecoder;
    15.  
    16. fn read_file(dir: &mut Directory, path: &CStr16) -> uefi::Result<Vec<u8>> {
    17.     // Open the file:
    18.     let fs_entry = dir.open(path, FileMode::Read, FileAttribute::READ_ONLY)?;
    19.     let FileType::Regular(mut file) = fs_entry.into_type()? else {
    20.         // Not a file:
    21.         return uefi::Result::Err(uefi::Error::new(Status::INVALID_PARAMETER, ()));
    22.     };
    23.  
    24.     // Query the file size:
    25.     file.set_position(RegularFile::END_OF_FILE)?;
    26.     let file_size = file.get_position()?;
    27.     file.set_position(0)?;
    28.  
    29.     // Read the whole file:
    30.     let mut content = alloc::vec![0_u8; file_size as usize];
    31.     let read_bytes = file.read(&mut content)?;
    32.     content.resize(read_bytes, 0_u8);
    33.  
    34.     Ok(content)
    35. }
    36.  
    37. fn downscale(
    38.     image: &[BltPixel],
    39.     original_size: (usize, usize),
    40.     downscaling_coeff: usize) -> (Vec<BltPixel>, (usize, usize))
    41. {
    42.     let downscaled_size = (
    43.         original_size.0 / downscaling_coeff, // Width
    44.         original_size.1 / downscaling_coeff  // Height
    45.     );
    46.  
    47.     let mut resized = alloc::vec![];
    48.  
    49.     for scanline in image.chunks(original_size.0).into_iter().step_by(downscaling_coeff) {
    50.         for chunk in scanline.chunks(downscaling_coeff) {
    51.             if chunk.len() != downscaling_coeff {
    52.                 break; // The last chunk which will be dropped
    53.             }
    54.  
    55.             let accum = chunk.into_iter().fold(
    56.                 (0_usize, 0_usize, 0_usize),
    57.                 |accum, entry| (
    58.                     accum.0 + (entry.red as usize),
    59.                     accum.1 + (entry.green as usize),
    60.                     accum.0 + (entry.blue as usize)
    61.                 )
    62.             );
    63.  
    64.             // Push the averaged color:
    65.             resized.push(BltPixel::new(
    66.                 (accum.0 / downscaling_coeff) as u8,
    67.                 (accum.1 / downscaling_coeff) as u8,
    68.                 (accum.2 / downscaling_coeff) as u8
    69.             ));
    70.         }
    71.     }
    72.     (resized, downscaled_size)
    73. }
    74.  
    75. fn as_image(raw: &[u8]) -> &[BltPixel] {
    76.     unsafe { core::slice::from_raw_parts(raw.as_ptr().cast(), raw.len()) }
    77. }
    78.  
    79. #[entry]
    80. fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
    81.     // Initialize UEFI services:
    82.     uefi_services::init(&mut system_table).expect("Unable to init the `uefi_sevices`");
    83.     let bs = system_table.boot_services();
    84.  
    85.     // Read the image:
    86.     let mut fs = bs.get_image_file_system(image_handle).expect("Unable to get the image file system");
    87.     let mut volume = fs.open_volume().expect("Unable to open volume");
    88.     let content = read_file(&mut volume, cstr16!("austin.jpg")).expect("Unable to read the file");
    89.  
    90.     // Decode the image:
    91.     let decoder_options = DecoderOptions::default().jpeg_set_out_colorspace(ColorSpace::BGRA);
    92.     let mut decoder = JpegDecoder::new_with_options(&content, decoder_options);
    93.     let image = decoder.decode().expect("Unable to decode the JPEG file");
    94.     let (img_width, img_height) = decoder.dimensions().expect("Unable to get the dimensions");
    95.     log::info!("Image: {img_width}x{img_height}");
    96.  
    97.     // Query graphics services:
    98.     let gop_handle = bs.get_handle_for_protocol::<GraphicsOutput>().expect("Unable to query the GOP handle");
    99.     let mut gop = bs.open_protocol_exclusive::<GraphicsOutput>(gop_handle).expect("Unable to open the GOP protocol");
    100.     let (screen_width, screen_height) = gop.current_mode_info().resolution();
    101.  
    102.     // Resize the image to fit the screen:
    103.     let ratios = (img_width / screen_width, img_height / screen_height);
    104.     let max_ratio = usize::max(ratios.0, ratios.1) + 1;
    105.     let mut resized_image = None;
    106.     if max_ratio > 1 {
    107.         resized_image = Some(downscale(as_image(&image), (img_width, img_height), max_ratio));
    108.     }
    109.  
    110.     // Get an actual image and its size:
    111.     let (actual_image, (actual_width, actual_height)) = if let Some((ref resized, (width, height))) = resized_image {
    112.         (resized.as_slice(), (width, height))
    113.     } else {
    114.         (as_image(&image), (img_width, img_height))
    115.     };
    116.  
    117.     // Fill the background:
    118.     const BACKGROUND: BltPixel = BltPixel::new(237, 86, 223);
    119.     gop.blt(BltOp::VideoFill { color: BACKGROUND, dest: (0, 0), dims: (screen_width, screen_height) }).expect("Unable to fill the screen");
    120.  
    121.     // Blit the image:
    122.     gop.blt(BltOp::BufferToVideo {
    123.         buffer: actual_image,
    124.         src: BltRegion::Full,
    125.         dest: (screen_width / 2 - actual_width / 2, screen_height / 2 - actual_height / 2),
    126.         dims: (actual_width, actual_height)
    127.     }).expect("Unable to BitBlt");
    128.  
    129.     loop { bs.stall(1000 * 1000); }
    130. }
    В Rust есть готовый тулчейн для сборки под UEFI, поэтому нам не надо собирать кастомный и мы можем остаться на stable-ветке.
    Добавим его:
    Код (Text):
    1.  
    2. rustup target add x86_64-unknown-uefi
    3.  
    Собираем:
    Код (Text):
    1.  
    2. cargo build --target x86_64-unknown-uefi --release
    3.  
    Запустить можно или на настоящем железе, отформатировав флешку в FAT32 и положив получившийся austin.efi в /efi/boot/bootx64.efi, или в QEMU.
    Мы пойдём вторым путём. Для запуска понадобится OVMF с реализацией EDKII. Скачать OVMF можно здесь.
    Затем понадобится виртуальный диск, который мы отформатируем в FAT32. Сделаем VHD: Пуск -> Параметры -> Система -> Память -> Дополнительные параметры хранилища -> Диски и тома -> Создать VHD
    upload_2024-1-29_0-1-33.png

    В качестве таблицы разделов выбираем GPT, файловую систему ставим FAT. Букву диска любую - например, X.
    Теперь кладём наше приложение из /target/x86_64-unknown-uefi/release/austin.efi в /efi/boot/bootx64.efi:
    upload_2024-1-29_0-4-28.png


    Затем берём ваш любимый jpeg с Остином Пауэрсом и кладём его в корень нашего диска - в X:\austin.jpg
    upload_2024-1-29_0-11-50.png
    И делаем батник для запуска Qemu:
    Код (Text):
    1.  
    2. @start "" "T:\Program Files\Qemu\qemu-system-x86_64w.exe"^
    3.     -smp 8^
    4.     -display gtk,show-tabs=on,show-menubar=on^
    5.     -drive if=pflash,format=raw,readonly=on,file=code.fd^
    6.     -drive if=pflash,format=raw,readonly=on,file=vars.fd^
    7.     -drive format=raw,file=fat:rw:X:\
    8.  
    code.fd и vars.fd - путь до OVMF, который мы скачали ранее (берём из папки x64).

    Запускаем батник - и мы счастливы!

    upload_2024-1-29_0-9-24.png

    — Do I make you horny?
     
    Последнее редактирование: 29 янв 2024
    Marylin, Thetrik, Mikl___ и ещё 1-му нравится это.
  7. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.207
    угу, пишешь сишный код ржакой, то бишь повторяешь достижение Кая :grin:
    --- Сообщение объединено, 29 янв 2024 ---
    на сишке писать легче всего, пч сишный бинарь ПОЧТИ ИДЕАЛЬНО интегрируется с отладочными схемами - вот попробуй ржачные бинари ладить.. да, даже на питохе сложней писать, чем на сихи, пч по мере выгребания багов код становится тупо тормознутым/ единственно жаба смогла обойти сиху, пч дико портабельна и её тормозуху на облаках можно компенсировать дешёвым железом :)
     
  8. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.445
    Адрес:
    Россия, Нижний Новгород
    Того, который сложил из осколков слово «вечность» и обрёл свободу?
    Неплохая аллегория, так и было!
     
  9. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.207
    https://wasm.in/threads/godnota-na-rzhaku.34990/page-2#post-441013
    вообще, никому не нужны новые яп-ы, пч все они лишь увеличивают фрагментацию кодов и проблемы с совместимостью.. вот на кой чёрт стандартные либы сишки переписывать на новые яп-ы.. в чём профит????????
     
  10. HoShiMin

    HoShiMin Well-Known Member

    Публикаций:
    5
    Регистрация:
    17 дек 2016
    Сообщения:
    1.445
    Адрес:
    Россия, Нижний Новгород
    Наверно они просто не знали, что существует си, а так бы конечно выбрали его.
    А их не переписывают, их выбрасывают.

    Кстати, насчёт libc. Как там дела с файлами?
    Выделяющий память fopen - это ведь чтобы было blazing fast?
    А fseek + tellg, чтобы узнать размер файла - это в алфавите буква У - удобно.
    Such amazing лангуаге.
     
  11. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.207
    асм/си + пай + жаба == остальное СОМНИИИТЕЛЬНО :)
    угу, через несколько десятков летов и со скрипом :)
    не совсем просекаю суть Твоего недовольства :)
     
  12. algent

    algent Member

    Публикаций:
    0
    Регистрация:
    11 апр 2018
    Сообщения:
    101
    UbIvItS, ну, не знаю, может они не знают о существовании кнопок Find Selected и Find Next?? Вот:
    Двойной щелчёк по указателю или хендлу, требующим особого внимания, затем при помощи Find Selected(Find Next) проверяем корректное наличие/отсутствие всех free, delete, close и пр.
    Хотя, кажется Rel говорил, что бывает так, что кодер не понимает свой код... :scratch_one-s_head: Ну тада наверно и правда, остаётся только Rust.
     
    UbIvItS нравится это.
  13. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.207
    свой код каждый кодер действительно перестаёт понимать по ходу просадки зрения / памяти и способности к долгой концентрации внимания.. но это другая тема.
    ржака - это чудовищно неудобная штука: корявый компиль с кривыми крейтами + отказ от однопоточного кода и глобальных переменных заставляет писать через Ж.. О.. П.. У.. :)
     
  14. algent

    algent Member

    Публикаций:
    0
    Регистрация:
    11 апр 2018
    Сообщения:
    101
    UbIvItS нравится это.
  15. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.295
    Я даже не знаю, смеяться с этого утверждения, или фейспалмить... но в принципе - ничего нового.
     
  16. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.207
    сложность зависит не столько от яп-а, а от задачи, кою Ты решаешь. питоха же штука очень тормознутая, тч каждый новый чекер в цикле становится новой болью :)
     
  17. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    456
    Марсолёт Ingenuity отлетал своё, но тут вскрывается весьма интересное.
    Этот марсо–коптер был дополнительной нагрузкой к основной миссии, пробным шаром, и оказывается создатели пошли по пути урезания осетра инопланетных технологий перед дилеммой как вместить в четырёхкилограммовую тушку и батарей и двигателей и камер и средств связи и процессора.
    Так вот они установили в него не дорогой космический радиационно–проверенный чип за сотни тысяч долларов (например чип RAD750 схемотехнически из 90–х на марсоходе Perseverance стоит четверть миллиона долларов), а банальный Qualcomm Snapdragon 801 из недорогих мобилок.
    Так вот этот крохотный процессор в сто раз вычислительно мощнее, чем всё, что Jet Propulsion Laboratory отправляла дальше орбиты Земли _вместе взятое_. От всех марсоходов и зондов к другим мирам до пресловутого Джеймса Уэбба. Всё вместе взятое в сто раз меньше биткойнов способно зарабатывать, если бы задались таким упражнением.
    Подозреваю, конечно, что в какую–нибудь свинцовую коробочку электронику всё–таки положили, но это изумительный факт.
    Источник (англ.): https://arstechnica.com/space/2024/01/now–that–weve–flown–on–mars–what–comes–next–in–aerial–planetary–exploration/
     
  18. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    579
    aa_dav, Ну эти вертолётики весьма требовательны по мощности киберпилота. Старые но крепкие по радиации не хватало вычислительной мощности, либо через чур дорого, вот они воткнули что было, и отработал же. Хотя конечно корпусировать чип надо в вольфрам, от альфа и беты полностью, а гамма уже не так. Остаётся только написать надёжное ПО, типа если 2+2 не четыре, то это исключение как-то надо обработать. И конечно никакого питухона.
     
  19. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.207
    aa_dav, есть мнение, что вся ся радость никуда не летала == уж очень забавно, что наиболее бурный прогресс наблюдается в абстрактных темах :)
     
  20. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.207
    • один поток забрал и тихо упал.
    • другой тупо ждёт адЪЪЪ инфинитум.
    =====================
    по-хорошему мьютекс всегда надо делать с таймаутом :)