- Play snake on any x86_64 CPU
- Let's have fun!
- Dynamic memory management
- The snake can grow!
- Interrupt handling
- We can read the keyboard!
- Async/Await support
- We can update the world and read user input at the same time!
- Only 212kB kernel size
- You can even put this on a 8-inch floppy disk!
Az szerző az alapötletet a Writing an OS in Rust blogból merítette. A projekt megtalálható a GitHub-on.
- A hozzászóláshoz be kell jelentkezni
- 942 megtekintés
Hozzászólások
'Only 212kB kernel size' nem nagy az egy text mode snakehez ?
Valaki emlegszik meg mekkora volt DOS 5.0/3.3 'sys a:' utani foglalas, ill menyi volt quickbasic demo jatek merete ?
https://en.wikipedia.org/wiki/Nibbles_(video_game)
Amit nem lehet megirni assemblyben, azt nem lehet megirni.
- A hozzászóláshoz be kell jelentkezni
(Minden mondatom elé képzeljétek oda, hogy "úgy rémlik", mert már nagyon régen volt.)
Mintha az alap DOS 5.0 többet evett volna, mint 212kB. 3.1 -> 3.3 közöttt is elég nagy ugrás volt. A 3.1-es kód (talán) nem címzett ki 64kB-ból, szóval az bufferekkel, meg gwbasic-kel együtt is bele kellet férjen 192kB-ba.
Dolgoztam egy IBM PC-vel, amiben összesen csak 256kB volt. Nem 512, vagy 640. Azon biztosan futott a 3.1-es DOS és a gwbasic.
- A hozzászóláshoz be kell jelentkezni
Szerintem ez vagy 32 bites vagy 64. Nem 16, mint a DOS. Maga a bináris méret is nő, meg amúgy is több dolog kell a modern módokhoz.
- A hozzászóláshoz be kell jelentkezni
Hat igen, gondolom ez tartalmaz egy komplett usb host layer-t, keyboard hid-et, stb. Az mar onmagaban joval bonyolultabb mint egy kigyos jatek ;]
- A hozzászóláshoz be kell jelentkezni
Nincs usb, classikus PC keyboard es megszakitas kezelo.
Amit nem lehet megirni assemblyben, azt nem lehet megirni.
- A hozzászóláshoz be kell jelentkezni
ASM/C-ben biztos kisebb lenne, de akkor nem Rustban lenne. :)
- A hozzászóláshoz be kell jelentkezni
https://github.com/johnthagen/min-sized-rust
Csodák nincsenek. Ha van benne kód ami csinál dolgokat, az nagyobb bináris méretet eredményez, ha ezeket kivesszük, akkor kisebb lesz a bináris. Cserébe azt nem tudjuk használni, amit kivettünk. :)
- A hozzászóláshoz be kell jelentkezni
Hát igen, a Rust-ból elkezdünk C-t csinálni:
Cargo.toml állományba berakjuk:
[dependencies]
libc = { version = "0.2", default-features = false }
[profile.release]
lto = true
panic = "abort"
Az általad hivatkozott példafájlon túl, ha write!()/writeln!() makrókat akarjuk low level kiterjeszteni, no_std módon csak core dolgokat használva:
#![no_std]
#![no_main]
#[panic_handler]
fn my_panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}
use core::fmt::{self, Write};
struct Stdout;
// write!() és writeln!() kiterjesztése
impl Write for Stdout {
fn write_str(&mut self, s: &str) -> fmt::Result {
let ret = unsafe { libc::write(libc::STDOUT_FILENO, s.as_ptr() as *const _, s.len()) };
if ret == s.len() as isize {
Ok(())
} else {
Err(fmt::Error)
}
}
}
#[no_mangle]
extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize {
let _ = write!(&mut Stdout, "Hello world! ");
let _ = writeln!(&mut Stdout, "Hello world!");
0
}
Eredmény x86_64 architektúrára való lefordítás és strip után: 14392 byte.
Összehasonlításként C-ben egy
#include <stdio.h>
int main() {
printf("Hello world!");
}
gcc -O2 -s után 14464 byte,
clang -O2 -s után 14472 byte.
Ritka eset lehet, amikor Rust esetén a méret miatt ennyire bűvészkednénk. Mikrovezérlőn eleve no_std van használatban, oké.
Talán OpenWRT-s kicsi memóriás routerekben futó Linuxoknál jöhet az iménti trükk jól.
- A hozzászóláshoz be kell jelentkezni
Megjegyzem, akkor is kicsi lesz maga a Rust bináris, ha az alap dolgokat ki lehet rakni majd shared lib-be, ahogy a libc esetén is kint van.
Ekkor egy sima println!("Hello World"); is kicsi lesz (14392 byte), a többi a /usr/lib/ mappában mind dinamikus LIB lesz.
Dinamikus fordításhoz a projektnél a .cargo/config.toml -be ennyit kell beírni:
[build]
rustflags = ["-C", "prefer-dynamic",]
Viszont addig nem futtatható az ilyen bináris, amíg nem lesznek benne a /usr/lib/ -ben az alap Rust LIB-ek.
- A hozzászóláshoz be kell jelentkezni
Hat, probalok rajonni igy szemmel valo nezegetessel hogy mire gondolt a kolto mit is csinalnak ezek a rust programok, de... de ez meg mindig nem egy szep nyelv :/
- A hozzászóláshoz be kell jelentkezni
:)
Egyik hátránya a Rustnak, hogy nehéz a tanulási görbéje. Főleg az ownership környékének készségszintű elsajátítása a vízválasztó.
Na meg sokkal összetettebb nyelvi elemei vannak. A fenti példa egyébként nem a kezdő szint, ezek már a haladó szint.
A normál szint kb. a
fn main() {
println!("Hello, world!");
}
És hasonlók. Szépen felhasználva a Rust std libjét, benne sok-sok finomsággal és tényleg csak használni és továbbépíteni a lib-eket.
A fenti bonyolítás főleg a mikrovezérlős low-level lib-ek esetén jön elő. Jó hír viszont, hogy napjainkban azt is csak be kell rántani a crates.io-ról és a te programod innentől kulturált kinézetű marad, a low level részek a berántott crate-ban vannak.
Lásd még:
https://crates.io/crates/stm32-hal
https://crates.io/crates/stm32-hal2
https://crates.io/crates/stm32-eth
...
Tehát a nem kezdőknek szánt részek a crate-kban már le vannak programozva, azokat csak használod.
Nézd meg például a mikrovezérlős ethernet kezelő rész felhasználását az utolsó linken.
- A hozzászóláshoz be kell jelentkezni
Hat, eleg sokat foglalkozom az SMT32Fxxx-esekkel, mondhatni. Ugy altalaban eleg jol ismerem a lelkivilagukat... de hogy ez mit csinalhat vajon:
fn pin_config(&self, pin: usize) -> &stm32f1xx::GPIOBitbandConfigBlock {
let registers: &stm32f1xx::GPIOBitbandRegisterBlock = ::bitband::to_bitband_address(self);
®isters.config(pin)
}
Szoval oke hogy meredeken indul a tanulasi gorbe, de utana cserebe exponencialisan megmeredekebb lesz :))
- A hozzászóláshoz be kell jelentkezni
Igen, a modulok használata az modul dokumentáció + lexika.
Az általad kérdezett például visszatér a
pub struct GPIOBitbandConfigBlock {
mode_low: VolatileCell<u32>,
mode_high: VolatileCell<u32>,
cnf_low: VolatileCell<u32>,
cnf_high: VolatileCell<u32>,
}
struktúra referenciájával. De ez a struktúra ne érdekeljen, csak legyen példányosítva. Helyette nézd meg milyen metódusok vannak alább:
https://docs.rs/stm32-hal/0.2.0/src/stm32_hal/gpio.rs.html#32
És ezeket a metódusokat hivogasd és "jó lesz neked". Lásd a dokumentációját a példával:
https://docs.rs/stm32-hal/0.2.0/stm32_hal/gpio/index.html
// Modifies corresponding GPIO configuration bits without reads
gpioc.pin_config(13).output2().open_drain();
Ennyi és nem több vele a feladatod. A low level dolgokkal nem kell foglalkoznod. Ha igen, akkor viszont
- nincs kész a modul
- jön a "haladó szint" (lehet a félkész modullal szívni)
- A hozzászóláshoz be kell jelentkezni
Helyette nézd meg milyen metódusok vannak alább: https://docs.rs/stm32-hal/0.2.0/src/stm32_hal/gpio.rs.html#32
Igenigen, pont innen masoltam be az elrettento peldat ;)
Egy teljes konfiguralast tudnal mutatni itten peldanak? Pl hogy a PB6/PB7-re rameppelem az USART1 TX/RX-et, es el is kezdem hasznalni? Pl ha van adat, akkor beolvasom, ha kisbetu akkor nagybetuve alakitom, majd megy vissza a feladonak?
- A hozzászóláshoz be kell jelentkezni
Remélem lesz kis időm a következő héten. Van valahol egy bluepill lapkám és összedobok egy alap UART példát.
Addig érdekességképpen egy USB-soros: https://github.com/stm32-rs/stm32f4xx-hal/blob/master/examples/usb_seri…
Itt látszik, hogy az egyébként bonyolult USB device kezelő rész annyira szépen meg van alkotva egy crate-ben, hogy a metódusok felhasználása minimális kódolást igényel. Az inicializálás, típus és descriptor beállítás szintén faék egyszerűen alkalmazható (43. sor).
Az már csak ráadás, hogy pont a 0x61 -> 0x41 konverziót láthatod a belsejében, mint ASCII nagybetűsítést. :)
Megjegyzem, normál esetben amikor Rust std-t használunk, akkor UTF8 Stringek vannak és minden nyelv betűit amit lehet nagybetűsíti a to_uppercase metódus, azaz nem csak az ASCII-re fókuszál. Ez mikrovezérlőnél nem játszik, itt no_std a praktikus irány. Rust std-vel UTF8 Stringek nagybetűsítésre lásd ezt a példát [RUN].
- A hozzászóláshoz be kell jelentkezni
Sorost összeraktam, leteszteltem Bluepill lapkán. ASCII nagybetűre alakít, ahogy kérted.
#![no_std]
#![no_main]
extern crate panic_halt;
use cortex_m_rt::entry;
use stm32f1xx_hal::{pac, prelude::*, serial};
#[entry]
fn main() -> ! {
let p = pac::Peripherals::take().unwrap();
let mut flash = p.FLASH.constrain();
let mut rcc = p.RCC.constrain();
let clocks = rcc.cfgr.freeze(&mut flash.acr);
let mut afio = p.AFIO.constrain(&mut rcc.apb2);
let mut gpioa = p.GPIOA.split(&mut rcc.apb2);
let tx = gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);
let rx = gpioa.pa10;
let mut usart1 = serial::Serial::usart1(
p.USART1,
(tx, rx),
&mut afio.mapr,
serial::Config::default().baudrate(38400.bps()),
clocks,
&mut rcc.apb2,
);
loop {
if let Ok(x) = usart1.read() {
let _ = usart1.write(x & !0x20);
}
}
}
- A hozzászóláshoz be kell jelentkezni
„Kb. egy hónapja elkezdtem írni egy Coelho-emulátort, ami kattintásra generál random Coelho-kompatibilis tartalmat.”
"Az Antikrisztus ledarálja Mészáros Lőrincet."
- A hozzászóláshoz be kell jelentkezni
Azt hiszem, hogy láttam erről egy videón a YouTube-on. A fazon kicsit fogalomzavarban van, mert attól, hogy ő egy Rust OS projektből lopkodta össze a dolgokat, az nem azt jelenti, hogy ez egy OS. Ezt a műfajt úgy hívják, hogy bare metal programozás, ilyenek a 80-as, 90-es években is voltak, hogy programozók hobbiként, meg gyakorlásként írtak ASM-ben ilyen 256-512 bájtos bináris kódokat, amik belefértek az MBR-be, így bootloader se kellett, természetesen kernel se. Ez a SnakeOS csak annyiban más, hogy mennie kell modern UEFI-s gépen is, meg védett 64 bites módból kell gazdálkodjon, így már bootloader kell, meg egy nagyon minimális extra kód, de még így se nevezhető OS-nek. Még mindig bare metal.
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni
Most is vannak 256 byte intrók, nem csak a '80-as, '90-es években voltak. Itt van pl. az egyik a 2020-as Revision party-ról. 8 effekt és hang, 256 byte-ban!
Memories - Hellmood / Desire
https://youtu.be/Imquk_3oFf4
Android: https://play.google.com/store/apps/developer?id=Artex+Games
iOS: https://apps.apple.com/developer/artex-studios-inc/id399983944
- A hozzászóláshoz be kell jelentkezni