OS自作入門【1】

wasmに入門したりprismaにハマったりいろいろありますが、以前から興味のあった自作OSというものに手を出してみます。 この書籍を参考にしています。 ゼロからのOS自作入門 | 内田 公太 |本 | 通販 | Amazon 機械語でHello World! まずはバイナリの編集に使用するエディターをダウンロードします。 sudo apt install okteta エディターがダウンロードできたら、ひたすらHello Worldを実装します。 以下に上がっていますが、本見ながら写経しました。チカレタ。。 mikanos-build/day01/bin/hello.efi at master · uchan-nos/mikanos-build · GitHub 実際はこんな感じです。痺れますね。 これをBOOTX64.efiとして保存します。 ちゃんとコーディングできていれば、sumコマンドでチェックサムが12430となっています。 % sum ../../study/custom_os/BOOTX64.efi 12430 2 ではこれをエミュレーターで実行します。 QEMUをダウンロードしましょう。 Download QEMU - QEMU 公式にダウンロードのためのshがあったので使ってみます。 wget https://download.qemu.org/qemu-8.1.0-rc4.tar.xz tar xvJf qemu-8.1.0-rc4.tar.xz cd qemu-8.1.0-rc4 ./configure make しかし./configureのあたりでエラーになってしまいました。。 % ./configure Using './build' as the directory for build output python determined to be '/home/username/.anyenv/envs/pyenv/shims/python3' python version: Python 3.8.12 mkvenv: Creating non-isolated virtual environment at 'pyvenv' mkvenv: checking for meson>=0.63.0 mkvenv: installing meson>=0.63.0 mkvenv: checking for sphinx>=1.6.0, sphinx-rtd-theme>=0.5.0 'sphinx>=1.6.0' not found: • Python package 'sphinx' was not found nor installed. • mkvenv was configured to operate offline and did not check PyPI. Sphinx not found/usable, disabling docs. ERROR: Cannot find Ninja なんかpython使っているっぽいです。 ...

8月 21, 2023 · にあえん

Rustで100本ノック【1】

ろくにRustに触らないままでwasmをやってしまっていましたが、ちゃんと触っておこうと思って100本ノックに挑みました。 言語処理100本ノック 2015 その際の備忘録を残します。 Q00: 文字列の逆順 逆順にするだけなのに、結局ググってしまった。。 Conversion between String, str, Vec<u8>, Vec<char> in Rust · GitHub fn main() { // 文字列"stressed"の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ. let s = "stressed"; let mut s = s.chars().collect::<Vec<_>>(); s.reverse(); print!("{}", s.iter().collect::<String>()); } collectの使い方とか、pythonみたいに容易に行かない感じがする。 Q01 さっきよりかはスムーズにできた。 でもイテレータの使い方とかちょっとググった。 fn main() { // 「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ. let s = "パタトクカシーー"; for (i, c) in s.chars().enumerate() { if !([1,3,5,7].contains(&i)) { continue; } print!("{}", c); } println!(); } Q02 基本的に先程の2問と解き方は一緒だった。 fn main() { // 「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ. let s1 = "パトカー"; let s2 = "タクシー"; let mut s1_vec = s1.chars().collect::<Vec<_>>(); let mut s2_vec = s2.chars().collect::<Vec<_>>(); s1_vec.reverse(); s2_vec.reverse(); let mut result: Vec<char> = vec![]; while s1_vec.len() > 0 && s2_vec.len() > 0 { if s1_vec.len() > 0 { result.push(s1_vec.pop().unwrap()); } if s2_vec.len() > 0 { result.push(s2_vec.pop().unwrap()); } } println!("{}", result.iter().collect::<String>()); } Q03 前の問題に比べると少し楽になりました。 ...

8月 20, 2023 · にあえん

hugoのテーマを新しくしました

今のHugoのテーマから、記事の検索機能などもあるいい感じのテンプレートに乗り換えたいなーと思った際の備忘録です。 何個かのテーマをインストールして実際に起動して確認してます。 hugoplateを導入する デモを見る限り、リッチなUIや記事の検索機能などがあり結構いいなと思ったのがこのテーマです。 Hugoplate | Hugo Themes git submoduleを使用してテーマを追加します。 hugoプロジェクトのthemesディレクトリで以下のコマンドを実行します。 git submodule add https://github.com/zeon-studio/hugoplate.git config.tomlを変更します。 theme = "hugoplate" この状態で一旦ローカルから起動してみます。 hugo serve -D しかしエラーが出てしまいました。。 render of "page" failed: execute of template failed: template: _default/single.html:8:7: executing "_default/single.html" at <partial "essentials/head.html" .>: error calling partial: "/home/username/Project/personal/hugo-blog/themes/hugoplate/layouts/partials/essentials/head.html:13:3": execute of template failed: template: partials/essentials/head.html:13:3: executing "partials/essentials/head.html" at <partialCached "favicon" .>: error calling partialCached: partial "favicon" not found render of "page" failed: execute of template failed: template: _default/single.html:8:7: executing "_default/single.html" at <partial "essentials/head.html" .>: error calling partial: "/home/username/Project/personal/hugo-blog/themes/hugoplate/layouts/partials/essentials/head.html:13:3": execute of template failed: template: partials/essentials/head.html:13:3: executing "partials/essentials/head.html" at <partialCached "favicon" .>: error calling partialCached: partial "favicon" not found render of "page" failed: execute of template failed: template: _default/single.html:8:7: executing "_default/single.html" at <partial "essentials/head.html" .>: error calling partial: "/home/username/Project/personal/hugo-blog/themes/hugoplate/layouts/partials/essentials/head.html:13:3": execute of template failed: template: partials/essentials/head.html:13:3: executing "partials/essentials/head.html" at <partialCached "favicon" .>: error calling partialCached: partial "favicon" not found render of "page" failed: execute of template failed: template: _default/single.html:8:7: executing "_default/single.html" at <partial "essentials/head.html" .>: error calling partial: "/home/username/Project/personal/hugo-blog/themes/hugoplate/layouts/partials/essentials/head.html:13:3": execute of template failed: template: partials/essentials/head.html:13:3: executing "partials/essentials/head.html" at <partialCached "favicon" .>: error calling partialCached: partial "favicon" not found Rebuild failed: Failed to render pages: render of "page" failed: execute of template failed: template: _default/single.html:8:7: executing "_default/single.html" at <partial "essentials/head.html" .>: error calling partial: "/home/username/Project/personal/hugo-blog/themes/hugoplate/layouts/partials/essentials/head.html:13:3": execute of template failed: template: partials/essentials/head.html:13:3: executing "partials/essentials/head.html" at <partialCached "favicon" .>: error calling partialCached: partial "favicon" not found hugo v0.92.2+extended linux/amd64 BuildDate=2023-01-31T11:11:57Z VendorInfo=ubuntu:0.92.2-1ubuntu0.1 Reload Page なんかファビコンが足りないっぽい? ...

8月 18, 2023 · にあえん

wasmに入門してみる【8】

今回で最後になります。 wasmに入門してみる【1】 wasmに入門してみる【2】 wasmに入門してみる【3】 wasmに入門してみる【4】 wasmに入門してみる【5】 wasmに入門してみる【6】 wasmに入門してみる【7】 wasmのサイズを小さくする いくつかの設定を追記することで、wasmのサイズを小さくすることができます。 Shrinking .wasm Size - Rust and WebAssembly Rustのリリースビルドみたいなものですね。 まず必要なパッケージをインストールします。 cargo install wasm-opt Cargo.tomlに設定を追記します。 [profile.release] lto = true opt-level = "z" 再ビルドする前に、一度どのくらいの大きさなのか見ておきましょう。 % wc -c pkg/wasm_game_of_life_bg.wasm 25136 pkg/wasm_game_of_life_bg.wasm 大体25KBくらいでした。 では先程インストールしたwasm-optで最適化していきます。 wasm-opt -Oz -o output.wasm pkg/wasm_game_of_life_bg.wasm 最適化できました。 % wc -c output.wasm 24955 output.wasm あんまり変わっていないですね。。 wasm-packでもビルドしてみて、wasmファイルに変化があるか確認してみます。 %wasm-pack build [INFO]: 🎯 Checking for the Wasm target... [INFO]: 🌀 Compiling to Wasm... Compiling wasm-game-of-life v0.1.0 (/home/username/Project/personal/wasm-game-of-life) warning: unused macro definition: `log` --> src/lib.rs:25:14 | 25 | macro_rules! log { | ^^^ | = note: `#[warn(unused_macros)]` on by default warning: `wasm-game-of-life` (lib) generated 1 warning Finished release [optimized] target(s) in 0.41s [INFO]: ⬇️ Installing wasm-bindgen... [INFO]: found wasm-opt at "/home/username/.cargo/bin/wasm-opt" [INFO]: Optimizing wasm binaries with `wasm-opt`... [INFO]: Optional fields missing from Cargo.toml: 'description', 'repository', and 'license'. These are not necessary, but recommended [INFO]: ✨ Done in 0.86s [INFO]: 📦 Your wasm pkg is ready to publish at /home/username/Project/personal/wasm-game-of-life/pkg. ビルドできたので確認します。 ...

8月 18, 2023 · にあえん

wasmに入門してみる【7】

前回からの続きです。 wasmに入門してみる【1】 wasmに入門してみる【2】 wasmに入門してみる【3】 wasmに入門してみる【4】 wasmに入門してみる【5】 wasmに入門してみる【6】 今回はタイムプロファイリングの章です。 Time Profiling - Rust and WebAssembly タイムプロファイリングする ライフゲームのパフォーマンス向上の指針として、FPS(Frames Per Second)タイマーの導入を行います。 window.performance.nowという関数を利用して、 www/index.jsにfpsオブジェクトを実装します。 const fps = new class { constructor() { this.fps = document.getElementById("fps"); this.frames = []; this.lastFrameTimeStamp = performance.now(); } render() { // 最後のフレームレンダリングからの差分時間を1秒あたりのフレーム数に変換する。 const now = performance.now(); const delta = now - this.lastFrameTimeStamp; this.lastFrameTimeStamp = now; const fps = 1 / delta * 1000; // 最新の100個のタイミングだけを保存する。 this.frames.push(fps); if (this.frames.length > 100) { this.frames.shift(); } // 最新の100個のタイムの最大値、最小値、平均値を求めます。 let min = Infinity; let max = -Infinity; let sum = 0; for (let i = 0; i < this.frames.length; i++) { sum += this.frames[i]; min = Math.min(this.frames[i], min); max = Math.max(this.frames[i], max); } let mean = sum / this.frames.length; // fpsに描画する this.fps.textContent = ` Frames per Second: latest = ${Math.round(fps)} avg of last 100 = ${Math.round(mean)} min of last 100 = ${Math.round(min)} max of last 100 = ${Math.round(max)} `.trim(); } }; //...中略 const renderLoop = () => { fps.render(); // 追記 universe.tick(); drawGrid(); drawCells(); animationId = requestAnimationFrame(renderLoop); }; www/index.htmlにも要素を追加します。 ...

8月 17, 2023 · にあえん

prisma client pythonが実行しているNodeはどこにあるのか

前回、prisma-client-pythonに入門しました。 しかし、どうやってNodeが動いているのかちょっとわからなかったので調べてみました。 Nodeの実態は? 現状、グローバルにprismaが使える状態ではないため、普通にprismaコマンドを実行しても実行できません。 % prisma zsh: command not found: prisma しかし、前回作ったパッケージ上であればprismaコマンドは実行できます。 % poetry run prisma This command is only intended to be invoked internally. Please run the following instead: prisma <command> e.g. prisma generate 説明を見るかぎり、ここで実行されているprismaは本家のCLIのラッパーとして実装されているようです。 Prisma Client Python exposes a CLI interface which wraps the Prisma CLI. This works by downloading a Node binary, if you don’t already have Node installed on your machine, installing the CLI with npm and running the CLI using Node. ...

8月 15, 2023 · にあえん

prisma-client-pythonでpythonからORMを楽にやる

今、自分の中でORMツールとしてアツいのがprismaです。 Prisma | Simplify working and interacting with databases モデル定義もマイグレーションも、ドキュメント読んだり実装してみたりすればするほどかなり使える書き方ができるので、すごく可能性を感じています。 そんなprismaですが、python用のクライアントがあるということで、勉強がてら触ってみたいと思います。 Prisma Client Python pythonプロジェクトの初期化 まずはpoetryでプロジェクトを初期化します。 poetry new prisma-client-python-playground 作成されたプロジェクトに依存性を追加します。 poetry add -D prisma さて、これでいつものprisma CLIが使えるようになりました。 早速Prismaの初期化をしていきましょう。 今回もsqliteを使用していきます。 % poetry run prisma init --datasource-provider sqlite ✔ Your Prisma schema was created at prisma/schema.prisma You can now open it in your favorite editor. Next steps: 1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started 2. Run prisma db pull to turn your database schema into a Prisma schema. 3. Run prisma generate to generate the Prisma Client. You can then start querying your database. More information in our documentation: https://pris.ly/d/getting-started 初期化できました。 ...

8月 13, 2023 · にあえん

wasmに入門してみる【6】

前回からの続きです。 wasmに入門してみる【1】 wasmに入門してみる【2】 wasmに入門してみる【3】 wasmに入門してみる【4】 wasmに入門してみる【5】 ゲームの一時停止と再生機能 まずはゲームの一時停止と再生ができるようにコードを修正します。 実装はJS内のみで完結できます。 www/index.htmlに新しくボタンを追加します。 <body> <noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript> <!-- ボタンを追加 --> <button id="play-pause"></button> <canvas id="game-of-life-canvas"></canvas> <script src="./bootstrap.js"></script> </body> 次にこのボタンに対するハンドラの実装を行います。 // requestAnimationFrameが発行する返り値を格納する変数 // https://developer.mozilla.org/ja/docs/Web/API/window/requestAnimationFrame let animationId = null; // 再生/停止を行うボタンを取得 const playPauseButton = document.getElementById("play-pause"); // 再生時のハンドラを実装 const play = () => { playPauseButton.textContent = "⏸"; renderLoop(); }; // 停止時のハンドラを実装 const pause = () => { playPauseButton.textContent = "▶"; cancelAnimationFrame(animationId); animationId = null; }; // 停止しているか判定する関数 const isPaused = () => { return animationId === null; }; // 再生/停止ボタンにイベントリスナーを追加 playPauseButton.addEventListener("click", (event) => { if (isPaused()) { play(); } else { pause(); } }); const renderLoop = () => { universe.tick(); drawGrid(); drawCells(); animationId = requestAnimationFrame(renderLoop); // requestAnimationFrameの返り値を設定 }; drawGrid(); drawCells(); play(); // requestAnimationFrame(renderLoop);をplay関数に置き換え これで再生/停止ボタンが使えるようになります! ...

8月 12, 2023 · にあえん

wasmに入門してみる【5】

シリーズ化しているwasm入門です。 (wasmのチュートリアルをやったという実績残しと備忘録を兼ねてやっています。真新しいことはないので悪しからず。。) wasmに入門してみる【1】 wasmに入門してみる【2】 wasmに入門してみる【3】 wasmに入門してみる【4】 テストの実装 これまでで実装してきたライフゲームのテストを実装します。 Testing Life - Rust and WebAssembly まずはUniverseの幅と高さのセッターを実装します。 #[wasm_bindgen] impl Universe { // ... /// Universeの幅を設定します。 /// /// すべてのセルの状態を死んだ状態にします。 pub fn set_width(&mut self, width: u32) { self.width = width; self.cells = (0..width * self.height).map(|_i| Cell::Dead).collect(); } /// Universeの高さを設定します。 /// /// すべてのセルの状態を死んだ状態にします。 pub fn set_height(&mut self, height: u32) { self.height = height; self.cells = (0..self.width * height).map(|_i| Cell::Dead).collect(); } // ... } 次に、セルのゲッターとセッターを実装します。 ここで、セルのゲッターを#[wasm_bindgen]マクロのあるUniverseに実装するとエラーになります。 #[wasm_bindgen] impl Universe { // ... /// Get the dead and alive values of the entire universe. pub fn get_cells(&self) -> &[Cell] { &self.cells } // ... } この状態でビルドします。 ...

8月 11, 2023 · にあえん

wasmに入門してみる【4】

前回の続きです。 wasmに入門してみる【1】 wasmに入門してみる【2】 wasmに入門してみる【3】 キャンバスタグを使って描画する 前回はpreタグを使って文字列で描画していました。 今回はキャンバスタグで描画するようにします。 前回preタグで宣言していた部分をそのままcanvasにします。 <canvas id="game-of-life-canvas"></canvas> Universeに高さ、幅、セルを返却するゲッターを実装します。 これはJSに公開されるように、#[wasm_bindgen]マクロを使用する必要があります。 #[wasm_bindgen] impl Universe { // ... pub fn width(&self) -> u32 { self.width } pub fn height(&self) -> u32 { self.height } pub fn cells(&self) -> *const Cell { self.cells.as_ptr() } // ... } 再ビルドもしておきましょう。 wasm-pack build 次にJSを修正します。 以前までの実装を削除し、新たに以下の実装を追加します。 セルのサイズや、盤上の色を定義します。 import { Universe, Cell } from "wasm-game-of-life"; const CELL_SIZE = 5; // px const GRID_COLOR = "#CCCCCC"; const DEAD_COLOR = "#FFFFFF"; const ALIVE_COLOR = "#000000"; 次に、マスを成形するためのグリッドを描画する関数を実装します。 // グリッド(マスを形成するための線)を描画します const drawGrid = () => { ctx.beginPath(); ctx.strokeStyle = GRID_COLOR; // Vertical lines. for (let i = 0; i <= width; i++) { ctx.moveTo(i * (CELL_SIZE + 1) + 1, 0); ctx.lineTo(i * (CELL_SIZE + 1) + 1, (CELL_SIZE + 1) * height + 1); } // Horizontal lines. for (let j = 0; j <= height; j++) { ctx.moveTo(0, j * (CELL_SIZE + 1) + 1); ctx.lineTo((CELL_SIZE + 1) * width + 1, j * (CELL_SIZE + 1) + 1); } ctx.stroke(); }; 次の実装はかなり興味深いです。 ...

8月 10, 2023 · にあえん