{"id":45444,"date":"2024-01-10T01:23:34","date_gmt":"2023-01-21T01:45:35","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/"},"modified":"2024-05-04T17:36:19","modified_gmt":"2024-05-04T09:36:19","slug":"45444-2","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/","title":{"rendered":""},"content":{"rendered":"<h1>kernel-roulette<\/h1>\n<p>Rust\u3067Linux kernel module\u304c\u66f8\u3051\u308b\u2026\u3002\u5642\u306e\u771f\u76f8\u3092\u7a81\u304d\u6b62\u3081\u308b\u305f\u3081\u3001GitHub\u3078\u3068\u5411\u304b\u3063\u305f\u3002<br \/>\n\u30cd\u30bf\u3070\u308c\u3002\u5642\u306f\u672c\u5f53\u3060\u3063\u305f\u3002<\/p>\n<hr \/>\n<p>\u307e\u305a\u6700\u521d\u306b\u898b\u3064\u304b\u3063\u305f\u306e\u304c\u3001rust.ko\u3067\u3059\u3002<br \/>\n\u5185\u5bb9\u306f\u3001kernel module\u3092\u30ed\u30fc\u30c9\u3059\u308b\u3068\u3001&#8221;Hello from Rust!++&#8221;\u3092printk\u3067\u51fa\u529b\u3059\u308b\u3001\u3068\u3044\u3046\u3082\u306e\u3067\u3059\u3002<br \/>\n\u305f\u3060\u30013\u5e74\u524d\u304b\u3089\u30e1\u30f3\u30c6\u30ca\u30f3\u30b9\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u65e9\u3005\u306b\u898b\u5207\u308a\u3092\u3064\u3051\u3066\u6b21\u3092\u63a2\u3057\u307e\u3057\u305f\u3002<\/p>\n<p>\u6b21\u306b\u767a\u898b\u3057\u305f\u306e\u304c\u3001kernel-roulette\u3067\u3057\u305f\u3002<br \/>\ncharacter device driver\u3092\u5b9f\u88c5\u3057\u3066\u304a\u308a\u3001\u30c7\u30d0\u30a4\u30b9\u30d5\u30a1\u30a4\u30eb\u3092read\u3059\u308b\u3068\u3001\u4e00\u5b9a\u78ba\u7387\u3067kernel panic\u3092\u8d77\u3053\u3059\u3001\u3068\u3044\u3046driver\u3067\u3057\u305f\u3002<br \/>\n\u306a\u3093\u3066\u8ff7\u60d1\u306adriver\u3067\u3057\u3087\u3046\u304b<br \/>\n\u3053\u3046\u3044\u3046\u9ad8\u5ea6\u306a\u6280\u8853\u3092\u4f7f\u3063\u3066\u3001\u7121\u99c4\u306a\u3053\u3068\u3059\u308b\u306e\u3001\u597d\u304d\u3067\u3059\u3002<br \/>\n\u6700\u7d42\u66f4\u65b0\u65e5\u304c7\u30f6\u6708\u524d\u306a\u306e\u3067\u3001\u30c8\u30e9\u30d6\u30eb\u304c\u3042\u3063\u3066\u3082\u3001\u3053\u308c\u304b\u3089\u306a\u3093\u3068\u304b\u306a\u308a\u305d\u3046\u3067\u3059\u3002<\/p>\n<p>\u3068\u3044\u3046\u308f\u3051\u3067\u3001\u5c11\u3005\u30c8\u30e9\u30d6\u30eb\u306f\u3042\u3063\u305f\u306e\u3067\u3059\u304c\u3001\u30d3\u30eb\u30c9\u3057\u3066\u52d5\u304b\u3057\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u3057\u305f\u3002<\/p>\n<p>\u611f\u60f3\u304b\u3089\u8a00\u3046\u3068\u3001Rust\u3067Linux kernel module\u304c\u66f8\u3051\u308b\u3001\u3068\u3044\u3046\u3088\u308a\u3001Linux kernel module\u304b\u3089Rust\u3092\u547c\u3073\u51fa\u305b\u308b\u3001\u3068\u3044\u3046\u611f\u3058\u3067\u3057\u305f\u3002<br \/>\nRust\u3067Linux driver\u3092\u66f8\u3051\u308b\u304b\u3089Happy\uff01\u3068\u3044\u3046\u4e16\u754c\u3067\u306f\u306a\u3044\u3067\u3059\u3002\uff08\u304a\u305d\u3089\u304f\u305d\u3046\u3044\u3046\u4e16\u754c\u306f\u305a\u3063\u3068\u6765\u306a\u3044\u3068\u601d\u3044\u307e\u3059\uff09<\/p>\n<p>\u305f\u3060\u3001\u7d30\u304b\u3044\u3053\u3068\u306f\u7f6e\u3044\u3066\u304a\u3044\u3066\u3001\u9762\u767d\u3044\u306e\u3067\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n<p>\u307e\u305a\u3001\u4f55\u306f\u3068\u3082\u3042\u308c\u3001\u52d5\u304b\u3059\u3068\u3069\u3046\u306a\u308b\u304b\u3001\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<br \/>\n\u305d\u306e\u5f8c\u3001\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3092\u89e3\u6790\u3057\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n<p>Linux kernel driver\u3084Rust\u306e\u57fa\u790e\u4e8b\u9805\u306b\u3064\u3044\u3066\u306f\u89e3\u8aac\u3057\u307e\u305b\u3093\u3002\u5225\u9014\u53c2\u7167\u3092\u304a\u9858\u3044\u3057\u307e\u3059\u3002<\/p>\n<h1>\u30d3\u30eb\u30c9\uff06\u52d5\u4f5c\u78ba\u8a8d\u74b0\u5883<\/h1>\n<div>\n<div class=\"post-table\">\u9805\u76eeVersion\u306a\u3069Linux kernel4.4.0-137-genericdistributionUbuntu 16.04 (Virtual Box)rustc1.31.0-nightly (77af31408 2018-10-11)<\/div>\n<\/div>\n<h1>\u52d5\u304b\u3057\u3066\u307f\u3088\u3046<\/h1>\n<h2>\u524d\u6e96\u5099<\/h2>\n<p>kernel-roulette README\u306eDependencies\u306b\u3042\u308b\u901a\u308a\u3001\u4e0b\u8a18\u306e\u524d\u6e96\u5099\u304c\u5fc5\u8981\u3067\u3059\u3002<\/p>\n<blockquote><p>Linux kernel headers and build-essential (gcc, make, etc.)<br \/>\nNightly Rust (install from https:\/\/rustup.rs)<br \/>\nXargo and rust-src<br \/>\nDownload the Rust library source with rustup component add rust-src<br \/>\nInstall xargo with cargo install xargo<\/p><\/blockquote>\n<h2>\u30d3\u30eb\u30c9<\/h2>\n<p>\u30ec\u30dd\u30b8\u30c8\u30ea\u3092clone\u3057\u3066\u3001patch\u3092\u5f53\u3066\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code>$ git clone https:\/\/github.com\/souvik1997\/kernel-roulette.git\r\n$ cd kernel-roulette\r\n$ wget https:\/\/raw.githubusercontent.com\/tomoyuki-nakabayashi\/blogs\/master\/Rust\/kernel-roulette\/0001-fix-build-error-in-the-latest-nightly-rust.patch\r\n$ patch -p1 &lt; 0001-fix-build-error-in-the-latest-nightly-rust.patch\r\n<\/code><\/pre>\n<p>README\u306eBuilding\u306b\u5f93\u3063\u3066\u624b\u9806\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002<br \/>\n\u4ee5\u4e0b\u3001\u5c11\u3057\u5197\u9577\u306b\u66f8\u304d\u307e\u3059\u306e\u3067\u3001\u624b\u3063\u53d6\u308a\u65e9\u304f\u52d5\u304b\u3057\u305f\u3044\u65b9\u306f\u3001README\u306e\u65b9\u3092\u3054\u89a7\u4e0b\u3055\u3044\u3002<\/p>\n<p>kernel module\u3092\u30d3\u30eb\u30c9\u3057\u307e\u3059\u3002build\/roullete.ko\u304c\u751f\u6210\u3055\u308c\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code>$ make\r\n$ ls build\/\r\n...  roulette.ko  ...\r\n<\/code><\/pre>\n<p>\u3044\u3088\u3044\u3088\u3001\u7dca\u5f35\u306e\u77ac\u9593\u3067\u3059\u3002kernel module\u3092\u30ed\u30fc\u30c9\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<pre class=\"post-pre\"><code>$ sudo insmod build\/roullete.ko\r\n<\/code><\/pre>\n<p>\u30ed\u30fc\u30c9\u3067\u304d\u3061\u3083\u3044\u307e\u3059\uff01<br \/>\n\u3061\u3083\u3093\u3068\u30ed\u30fc\u30c9\u3055\u308c\u3066\u3044\u308b\u304b\u3001\u78ba\u8a8d\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<pre class=\"post-pre\"><code>$ lsmod\r\nModule                  Size  Used by\r\nroulette              106496  0\r\n<\/code><\/pre>\n<p>\u304a\u308b\u3084\u3093\uff01<br \/>\ndmesg\u306broulette driver\u304c\u30ed\u30b0\u3092\u51fa\u529b\u3059\u308b\u306e\u3067\u3001\u78ba\u8a8d\u3057\u307e\u3059\u3002Panic\u3059\u308b\u78ba\u7387\u306f1\/100\u306e\u3088\u3046\u3067\u3059\uff01\u307b\u3068\u3093\u3069\u6b7b\u306a\u306a\u3044\u3067\u3059\u306d\uff01<\/p>\n<pre class=\"post-pre\"><code>$ dmesg | tail -n 10\r\n...\r\n[16837.958611] Registered kernel-roulette with major device number 246\r\n[16837.958613] Run \/bin\/mknod \/dev\/kernel-roulette c 246 0\r\n[16838.468004] Panic probability: 1\/100\r\n<\/code><\/pre>\n<p>roulette driver\u306e\u6307\u793a\u901a\u308a\u3001\u30ad\u30e3\u30e9\u30af\u30bf\u30c7\u30d0\u30a4\u30b9\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code>$ sudo \/bin\/mknod \/dev\/kernel-roulette c 246 0\r\n<\/code><\/pre>\n<p>\u4f5c\u6210\u3057\u305f\u30c7\u30d0\u30a4\u30b9\u30d5\u30a1\u30a4\u30eb\u3092read\u3059\u308b\u3068\u30011\/100\u306e\u78ba\u7387\u3067\u6b7b\u306b\u307e\u3059\uff01<br \/>\ncat\u3057\u3066\u3001\u305d\u306e\u6642\u304c\u6765\u308b\u306e\u3092\u5f85\u3061\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code>$ cat \/dev\/kernel-roulette\r\nSurvived... sampled value is 79, which is &gt;= 1\r\n$ cat \/dev\/kernel-roulette\r\nSurvived... sampled value is 1, which is &gt;= 1\r\n<\/code><\/pre>\n<p>\u6b7b\u306d\u306a\u3044\uff01<br \/>\n\u6b7b\u306c\u78ba\u7387\u306f\u3001driver\u30ed\u30fc\u30c9\u6642\u306b\u30e9\u30f3\u30c0\u30e0\u3067\u6c7a\u5b9a\u3055\u308c\u308b\u306e\u3067\u3001\u9762\u5012\u306a\u306e\u3067\u30ed\u30fc\u30c9\u3057\u76f4\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code>$ sudo rmmod build\/roulette.ko\r\n$ sudo insmod build\/roulette.ko\r\n<\/code><\/pre>\n<p>\u3055\u3066\u3002<\/p>\n<pre class=\"post-pre\"><code>$ dmseg | tail -n 10\r\n...\r\n[17574.935478] Registered kernel-roulette with major device number 246\r\n[17574.935481] Run \/bin\/mknod \/dev\/kernel-roulette c 246 0\r\n[17575.447283] Panic probability: 49\/100\r\n<\/code><\/pre>\n<p>\u4eca\u5ea6\u306f\u3059\u3050\u6b7b\u306d\u305d\u3046\u3067\u3059\u306d\u3002<\/p>\n<pre class=\"post-pre\"><code>$ cat \/dev\/kernel-roulette\r\nSurvived... sampled value is 86, which is &gt;= 49\r\n$ cat \/dev\/kernel-roulette\r\nSegmentation fault\r\n<\/code><\/pre>\n<p>\u304a\u30012\u56de\u76ee\u3067\u30bb\u30b0\u30e1\u30f3\u30c6\u30fc\u30b7\u30e7\u30f3\u30d5\u30a9\u30fc\u30eb\u30c8\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u4f55\u304c\u8d77\u3053\u3063\u3066\u3044\u308b\u304b\u3001dmesg\u3067\u78ba\u8a8d\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<pre class=\"post-pre\"><code>$ dmesg | tail -n 100\r\n[17633.158768] Rust panic @ src\/roulette.rs:33\r\n[17633.158774] Boom!\r\n[17633.158793] ------------[ cut here ]------------\r\n[17633.158807] Kernel BUG at ffffffffc04bb24e [verbose debug info unavailable]\r\n[17633.158822] invalid opcode: 0000 [#1] SMP \r\n# \u30c8\u30ec\u30fc\u30b9\u7701\u7565\r\n[17633.172695] fbcon_switch: detected unhandled fb_set_par error, error code -16\r\n[17633.173673] fbcon_switch: detected unhandled fb_set_par error, error code -16\r\n[17633.174673] ---[ end trace ff2742f73b763c6d ]---\r\n<\/code><\/pre>\n<p>\u307e\u305aRust\u3067panic\u304c\u767a\u751f\u3057\u3066\u3044\u3066\u3001\u305d\u306e\u5f8c\u306f\u3001\u304a\u306a\u3058\u307f\u306eLinux kernel\u306e\u30c8\u30ec\u30fc\u30b9\u60c5\u5831\u3067\u3059\u3002<br \/>\nKernel\u306eBUG()\u304c\u547c\u3073\u51fa\u3055\u308c\u3066\u3001invalid opcode\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u306d\u3002<\/p>\n<p>kernel-roullete\u4f5c\u8005\u306e\u6069\u60c5\u3067\u3001panic()\u3067\u306f\u306a\u304f\u3001BUG()\u3092\u547c\u3076\u3088\u3046\u306b\u3057\u3066\u304f\u308c\u3066\u3044\u308b\u305f\u3081\u3001Kernel\u304cpanic\u3057\u3066\u30b7\u30b9\u30c6\u30e0\u304c\u6b62\u307e\u308b\u3088\u3046\u306a\u4e8b\u614b\u306f\u767a\u751f\u3057\u307e\u305b\u3093\u3002<\/p>\n<p>\u3061\u306a\u307f\u306b\u3001\u3053\u306e\u5f8c\u3001roullete driver\u3092rmmod\u3067\u304d\u306a\u304f\u306a\u308a\u307e\u3059\u3002<br \/>\n\u539f\u56e0\u306f\u89e3\u660e\u3067\u304d\u3066\u3044\u306a\u3044\u3067\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code>$ sudo rmmod roulette\r\nrmmod: ERROR: Module roulette is in use\r\n<\/code><\/pre>\n<h1>\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u89e3\u6790<\/h1>\n<p>\u3055\u3066\u3001Linux kernel driver\u306e\u4e00\u90e8\u3068\u3057\u3066\u3001Rust\u3092\u4f7f\u3046\u306b\u306f\u3069\u306e\u3088\u3046\u306a\u30c8\u30ea\u30c3\u30af\u304c\u5fc5\u8981\u306a\u306e\u3067\u3057\u3087\u3046\u304b\uff1f<br \/>\n\u3053\u3053\u307e\u3067\u3067\u52d5\u4f5c\u3092\u78ba\u8a8d\u3057\u305fkernel-roulette\u306e\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3092\u89e3\u6790\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<br \/>\n\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u3084Makefile\u306b\u4e01\u5be7\u306b\u30b3\u30e1\u30f3\u30c8\u304c\u6dfb\u3048\u3089\u308c\u3066\u3044\u308b\u305f\u3081\u3001\u975e\u5e38\u306b\u89e3\u6790\u3057\u3084\u3059\u3044\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3067\u3057\u305f\u3002\u4f5c\u8005\u306e\u6280\u8853\u30ec\u30d9\u30eb\u306e\u9ad8\u3055\u304c\u4f3a\u3048\u307e\u3059\u3002<br \/>\n\u7d39\u4ecb\u3059\u308b\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u306f\u30011.31.0-nightly\u3067\u30d3\u30eb\u30c9\u3067\u304d\u308b\u3088\u3046\u306b\u4fee\u6b63\u3092\u52a0\u3048\u305f\u3082\u306e\u3067\u3059\u3002<\/p>\n<h2>\u69cb\u6210<\/h2>\n<p>\u307e\u305a\u306f\u3001\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u69cb\u6210\u304b\u3089\u5168\u4f53\u50cf\u3092\u628a\u63e1\u3057\u3066\u3044\u304d\u307e\u3059\u3002shim.c\u3068kbuild.mk\u304c\u3042\u308b\u4ee5\u5916\u306f\u3001\u666e\u901a\u306eRust\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3001\u3068\u3044\u3046\u611f\u3058\u3067\u3057\u3087\u3046\u304b\u3002<\/p>\n<pre class=\"post-pre\"><code>$ tree .\r\n.\r\n\u251c\u2500\u2500 Cargo.lock\r\n\u251c\u2500\u2500 Cargo.toml\r\n\u251c\u2500\u2500 kbuild.mk\r\n\u251c\u2500\u2500 LICENSE.txt\r\n\u251c\u2500\u2500 Makefile\r\n\u251c\u2500\u2500 README.md\r\n\u251c\u2500\u2500 src\r\n\u2502   \u251c\u2500\u2500 io\r\n\u2502   \u2502   \u2514\u2500\u2500 mod.rs\r\n\u2502   \u251c\u2500\u2500 lang.rs\r\n\u2502   \u251c\u2500\u2500 lib.rs\r\n\u2502   \u251c\u2500\u2500 mem\r\n\u2502   \u2502   \u2514\u2500\u2500 mod.rs\r\n\u2502   \u251c\u2500\u2500 roulette.rs\r\n\u2502   \u2514\u2500\u2500 shim.c\r\n\u251c\u2500\u2500 x86_64-unknown-none-gnu.json\r\n\u2514\u2500\u2500 Xargo.toml\r\n\r\n3 directories, 14 files\r\n<\/code><\/pre>\n<p>Cargo.toml\u3092\u898b\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nn\">[package]<\/span>\r\n<span class=\"py\">name<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"kernel-roulette\"<\/span>\r\n<span class=\"py\">version<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"0.1.0\"<\/span>\r\n<span class=\"py\">authors<\/span> <span class=\"p\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"Souvik Banerjee &lt;souvik@souvik.me&gt;\"<\/span><span class=\"p\">]<\/span>\r\n\r\n<span class=\"nn\">[lib]<\/span>\r\n<span class=\"py\">name<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"roulette\"<\/span>\r\n<span class=\"py\">crate-type<\/span> <span class=\"p\">=<\/span> <span class=\"nn\">[\"staticlib\"]<\/span>\r\n\r\n<span class=\"nn\">[dependencies]<\/span>\r\n<span class=\"nn\">lazy_static<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span> <span class=\"py\">version<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"1.0.0\"<\/span><span class=\"p\">,<\/span> <span class=\"py\">features<\/span> <span class=\"p\">=<\/span> <span class=\"nn\">[\"spin_no_std\"]<\/span> <span class=\"p\">}<\/span>\r\n<span class=\"py\">spin<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"0.4.9\"<\/span>\r\n<span class=\"nn\">rand<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span> <span class=\"py\">version<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"0.4.2\"<\/span><span class=\"p\">,<\/span> <span class=\"py\">default-features<\/span> <span class=\"p\">=<\/span> <span class=\"kc\">false<\/span> <span class=\"p\">}<\/span>\r\n<span class=\"py\">rlibc<\/span> <span class=\"p\">=<\/span> <span class=\"s\">\"1.0\"<\/span>\r\n<\/code><\/pre>\n<p>crate-type\u304cstaticlib\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u306fRust\u306e\u30a2\u30fc\u30ab\u30a4\u30d6\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u3063\u3066\u3001C\u8a00\u8a9e\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30d5\u30a1\u30a4\u30eb\u3068\u30ea\u30f3\u30af\u3059\u308b\u30a2\u30ec\u3067\u3059\u306d\u3001\u304d\u3063\u3068\u3002<br \/>\n\u691c\u8a0e\u304c\u3064\u3044\u305f\u3068\u3053\u308d\u3067\u3001Makefile\u3092\u898b\u307e\u3057\u3087\u3046\u3002kernel module\u540d\u306froulette\u3067\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\"># Configuration that will be passed to sub-make\r\n<\/span>\r\n<span class=\"c\"># Name of the kernel module\r\n<\/span><span class=\"k\">export <\/span><span class=\"nv\">KERNEL_MODULE<\/span> <span class=\"o\">:=<\/span> roulette\r\n\r\n<span class=\"c\"># Path to Linux kernel headers\r\n<\/span><span class=\"k\">export <\/span><span class=\"nv\">KERNEL_BUILD_PATH<\/span> <span class=\"o\">:=<\/span> \/lib\/modules\/<span class=\"nf\">$(<\/span><span class=\"nb\">shell<\/span> <span class=\"nb\">uname<\/span> <span class=\"nt\">-r<\/span><span class=\"nf\">)<\/span>\/build\r\n\r\n<span class=\"c\"># Find all C and Rust source files\r\n<\/span><span class=\"k\">export <\/span><span class=\"nv\">C_FILES<\/span> <span class=\"o\">:=<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">shell<\/span> find src\/ <span class=\"nt\">-type<\/span> f <span class=\"nt\">-name<\/span> <span class=\"s2\">\"*.c\"<\/span><span class=\"nf\">)<\/span>\r\n<span class=\"k\">export <\/span><span class=\"nv\">RUST_FILES<\/span> <span class=\"o\">:=<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">shell<\/span> find src\/ <span class=\"nt\">-type<\/span> f <span class=\"nt\">-name<\/span> <span class=\"s2\">\"*.rs\"<\/span><span class=\"nf\">)<\/span> Cargo.toml Cargo.lock\r\n\r\n<span class=\"c\"># Define the architecture; this will be used for the LLVM target specification\r\n<\/span><span class=\"k\">export <\/span><span class=\"nv\">UTS_MACHINE<\/span> <span class=\"o\">=<\/span> x86_64\r\n\r\n<span class=\"c\"># The Rust compiler and cross-compiler\r\n<\/span><span class=\"k\">export <\/span><span class=\"nv\">CARGO<\/span><span class=\"o\">=<\/span>cargo\r\n<span class=\"k\">export <\/span><span class=\"nv\">XARGO<\/span><span class=\"o\">=<\/span>xargo\r\n\r\n<span class=\"c\"># A JSON file specifying an LLVM target\r\n<\/span><span class=\"k\">export <\/span><span class=\"nv\">LLVM_TARGET_SPEC<\/span><span class=\"o\">=<\/span><span class=\"nv\">$(UTS_MACHINE)<\/span><span class=\"nt\">-unknown-none-gnu<\/span>.json\r\n\r\n<span class=\"c\"># Top-level project directory\r\n<\/span><span class=\"k\">export <\/span><span class=\"nv\">BASE_DIR<\/span> <span class=\"o\">:=<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">patsubst<\/span> %\/,%,<span class=\"nf\">$(<\/span><span class=\"nb\">dir<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">abspath<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">lastword<\/span> <span class=\"nv\">$(MAKEFILE_LIST)<\/span><span class=\"nf\">))))<\/span>\r\n\r\n<span class=\"c\"># The build directory\r\n<\/span><span class=\"k\">export <\/span><span class=\"nv\">BUILD_DIR<\/span> <span class=\"o\">:=<\/span> build\r\n\r\n<span class=\"c\"># The Makefile that is copied to $(BUILD_DIR)\r\n<\/span><span class=\"k\">export <\/span><span class=\"nv\">KBUILD<\/span> <span class=\"o\">:=<\/span> kbuild.mk\r\n\r\n<span class=\"nl\">all<\/span><span class=\"o\">:<\/span> <span class=\"nf\">$(BUILD_DIR)\/Makefile Makefile<\/span>\r\n<span class=\"c\"># The kbuild makefile has been copied to $(BUILD_DIR), so now we can invoke kbuild from\r\n# the kernel headers.\r\n<\/span>    <span class=\"err\">$(MAKE)<\/span> <span class=\"err\">-C<\/span> <span class=\"s2\">\"$(KERNEL_BUILD_PATH)\"<\/span> <span class=\"nv\">M<\/span><span class=\"o\">=<\/span><span class=\"s2\">\"<\/span><span class=\"nv\">$(BASE_DIR)<\/span><span class=\"s2\">\/<\/span><span class=\"nv\">$(BUILD_DIR)<\/span><span class=\"s2\">\"<\/span> modules\r\n\r\n<span class=\"nl\">$(BUILD_DIR)\/Makefile <\/span><span class=\"o\">:<\/span> <span class=\"nf\">$(KBUILD)<\/span>\r\n    <span class=\"err\">@mkdir<\/span> <span class=\"err\">-p<\/span> <span class=\"s2\">\"${BUILD_DIR}\/src\"<\/span>\r\n    <span class=\"err\">cp<\/span> <span class=\"s2\">\"$(KBUILD)\"<\/span> <span class=\"s2\">\"$(BUILD_DIR)\/Makefile\"<\/span>\r\n\r\n<span class=\"nl\">clean<\/span><span class=\"o\">:<\/span>\r\n<span class=\"c\"># cleanup is really simple, we just blow away the $(BUILD_DIR) and call `xargo clean`\r\n<\/span>    <span class=\"err\">rm<\/span> <span class=\"err\">-rf<\/span> <span class=\"s2\">\"$(BUILD_DIR)\"<\/span>\r\n    <span class=\"err\">xargo<\/span> <span class=\"err\">clean<\/span>\r\n<\/code><\/pre>\n<p>kbuild.mk\u3092Makefile\u306b\u30ea\u30cd\u30fc\u30e0\u3057\u305f\u4e0a\u3067\u3001build\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306b\u79fb\u52d5\u3057\u3066\u3001kbuild.mk\u3092make\u30b3\u30de\u30f3\u30c9\u3067\u53e9\u3044\u3066\u3044\u307e\u3059\u3002<br \/>\nkbuild\u3067\u5f15\u304d\u7d99\u3050\u74b0\u5883\u5909\u6570\u3082\u591a\u6570\u5b9a\u7fa9\u3057\u3066\u3044\u307e\u3059\u306d\u3002<br \/>\nkbuild.mk\u3092\u898b\u3066\u307f\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\"># Define the Rust target. Xargo will create an ar archive file with the\r\n# following name in the target folder\r\n<\/span><span class=\"nv\">RUST_TARGET<\/span> <span class=\"o\">:=<\/span> lib<span class=\"nv\">$(KERNEL_MODULE)<\/span>.a\r\n\r\n<span class=\"c\"># Enumerate the object files that the C files will compile to\r\n<\/span><span class=\"nv\">C_OBJECTS<\/span> <span class=\"o\">:=<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">patsubst<\/span> %.c,%.o,<span class=\"nv\">$(C_FILES)<\/span><span class=\"nf\">)<\/span>\r\n\r\n<span class=\"c\"># Tell kbuild which files to build\r\n<\/span><span class=\"nv\">obj-m<\/span> <span class=\"o\">:=<\/span> <span class=\"nv\">$(KERNEL_MODULE)<\/span>.o\r\n\r\n<span class=\"c\"># Tell kbuild where the source files are\r\n<\/span><span class=\"nv\">src<\/span> <span class=\"o\">:=<\/span> <span class=\"nv\">$(BASE_DIR)<\/span>\r\n\r\n<span class=\"c\"># The kernel module will be linked from the C object files and the Rust archive\r\n# The order is important: C objects must come first\r\n<\/span><span class=\"nv\">$(KERNEL_MODULE)-objs<\/span> <span class=\"o\">:=<\/span> <span class=\"nv\">$(C_OBJECTS)<\/span> <span class=\"nv\">$(RUST_TARGET)<\/span>\r\n\r\n<span class=\"c\"># Strip unused symbols from the input object file\r\n<\/span><span class=\"nv\">EXTRA_LDFLAGS<\/span> <span class=\"o\">+=<\/span> <span class=\"nt\">--gc-sections<\/span> <span class=\"nt\">--entry<\/span><span class=\"o\">=<\/span>init_module <span class=\"nt\">--undefined<\/span><span class=\"o\">=<\/span>cleanup_module\r\n<span class=\"nv\">EXTRA_LDFLAGS<\/span> <span class=\"o\">+=<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">if<\/span> <span class=\"nv\">$(RELEASE)<\/span>,--strip-all<span class=\"nf\">)<\/span>\r\n\r\n<span class=\"c\"># Fix file paths (since this script will be run from the kbuild's working directory)\r\n<\/span><span class=\"nv\">C_FILES<\/span>    <span class=\"o\">:=<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">foreach<\/span> filepath,<span class=\"nv\">$(C_FILES)<\/span>   ,<span class=\"nv\">$(BASE_DIR)<\/span>\/<span class=\"nv\">$(filepath)<\/span><span class=\"nf\">)<\/span>\r\n<span class=\"nv\">RUST_FILES<\/span> <span class=\"o\">:=<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">foreach<\/span> filepath,<span class=\"nv\">$(RUST_FILES)<\/span>,<span class=\"nv\">$(BASE_DIR)<\/span>\/<span class=\"nv\">$(filepath)<\/span><span class=\"nf\">)<\/span>\r\n<span class=\"nv\">LLVM_TARGET_SPEC<\/span> <span class=\"o\">:=<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">foreach<\/span> filepath,<span class=\"nv\">$(LLVM_TARGET_SPEC)<\/span>,<span class=\"nv\">$(BASE_DIR)<\/span>\/<span class=\"nv\">$(filepath)<\/span><span class=\"nf\">)<\/span>\r\n\r\n<span class=\"c\"># Determine target directory of cargo's module build\r\n<\/span><span class=\"nv\">CARGO_BUILD_DIR<\/span> <span class=\"o\">:=<\/span> <span class=\"nv\">$(BASE_DIR)<\/span>\/target\/<span class=\"nv\">$(UTS_MACHINE)<\/span><span class=\"nt\">-unknown-none-gnu<\/span>\/<span class=\"nf\">$(<\/span><span class=\"nb\">if<\/span> <span class=\"nv\">$(RELEASE)<\/span>,release,debug<span class=\"nf\">)<\/span>\r\n\r\n<span class=\"nl\">$(obj)\/$(RUST_TARGET)<\/span><span class=\"o\">:<\/span> <span class=\"nf\">$(RUST_FILES) $(LLVM_TARGET_SPEC) $(BASE_DIR)\/$(KBUILD)<\/span>\r\n<span class=\"c\"># We set RUST_TARGET_PATH because of a bug in cargo\/xargo\/rustc: the --target flag is relative to the current working\r\n# directory but subsequent invokations of cargo\/xargo\/rustc might change their working directory. Setting\r\n# RUST_TARGET_PATH ensures that the compiler can find the LLVM target specification.\r\n# We also have to `cd` into $(BASE_DIR) since we are currently in the kernel headers directory.\r\n<\/span>    <span class=\"err\">(cd<\/span> <span class=\"err\">$(BASE_DIR);<\/span> <span class=\"err\">env<\/span> <span class=\"nv\">RUST_TARGET_PATH<\/span><span class=\"o\">=<\/span><span class=\"nv\">$(BASE_DIR)<\/span> <span class=\"nv\">$(XARGO)<\/span> rustc <span class=\"nf\">$(<\/span><span class=\"nb\">if<\/span> <span class=\"nv\">$(RELEASE)<\/span>,--release<span class=\"nf\">)<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">if<\/span> <span class=\"nv\">$(VERBOSE)<\/span>,--verbose<span class=\"nf\">)<\/span> <span class=\"nt\">--target<\/span> <span class=\"nv\">$(UTS_MACHINE)<\/span><span class=\"nt\">-unknown-none-gnu<\/span> <span class=\"nt\">--<\/span> <span class=\"nt\">-C<\/span> code-model<span class=\"o\">=<\/span>kernel <span class=\"nt\">-C<\/span> relocation-model<span class=\"o\">=<\/span>static <span class=\"nt\">-C<\/span> <span class=\"nv\">panic<\/span><span class=\"o\">=<\/span>abort<span class=\"o\">)<\/span>\r\n<span class=\"c\"># After the archive is compiled, copy it to the build directory\r\n<\/span>    <span class=\"err\">cp<\/span> <span class=\"s2\">\"$(CARGO_BUILD_DIR)\/$(RUST_TARGET)\"<\/span> <span class=\"err\">$(obj)<\/span>\r\n\r\n<span class=\"nl\">$(obj)\/%.c <\/span><span class=\"o\">:<\/span> <span class=\"nf\">$(BASE_DIR)\/%.c $(BASE_DIR)\/$(KBUILD)<\/span>\r\n<span class=\"c\"># KBUILD_CFLAGS is automatically generated by kbuild\r\n<\/span>    <span class=\"err\">$(CC)<\/span> <span class=\"err\">$(KBUILD_CFLAGS)<\/span> <span class=\"err\">-c<\/span> <span class=\"err\">$(BASE_DIR)\/$*.c<\/span> <span class=\"err\">-o<\/span> <span class=\"err\">$*.o<\/span>\r\n<\/code><\/pre>\n<p>\u305d\u3053\u305d\u3053\u30dc\u30ea\u30e5\u30fc\u30e0\u304c\u3042\u308b\u306e\u3067\u3059\u304c\u3001\u4e0b\u3092\u898b\u308b\u3068\u3001\u5148\u307b\u3069\u306e\u4e88\u6e2c\u304c\u7684\u4e2d\u3057\u3066\u3044\u308b\u3053\u3068\u304c\u5206\u304b\u308a\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\"># The kernel module will be linked from the C object files and the Rust archive\r\n# The order is important: C objects must come first\r\n<\/span><span class=\"nv\">$(KERNEL_MODULE)-objs<\/span> <span class=\"o\">:=<\/span> <span class=\"nv\">$(C_OBJECTS)<\/span> <span class=\"nv\">$(RUST_TARGET)<\/span>\r\n<\/code><\/pre>\n<p>kernel module\u3092\u4f5c\u308b\u305f\u3081\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30d5\u30a1\u30a4\u30eb\u306f\u3001C\u8a00\u8a9e\u3068Rust\u3001\u305d\u308c\u305e\u308c\u500b\u5225\u3067\u4f5c\u3089\u308c\u3066\u3044\u307e\u3059\u3002<br \/>\nC\u8a00\u8a9e\u3001\u666e\u901a\u306bkernel module\u306e\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u30d5\u30a1\u30a4\u30eb\u4f5c\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nl\">$(obj)\/%.c <\/span><span class=\"o\">:<\/span> <span class=\"nf\">$(BASE_DIR)\/%.c $(BASE_DIR)\/$(KBUILD)<\/span>\r\n<span class=\"c\"># KBUILD_CFLAGS is automatically generated by kbuild\r\n<\/span>    <span class=\"err\">$(CC)<\/span> <span class=\"err\">$(KBUILD_CFLAGS)<\/span> <span class=\"err\">-c<\/span> <span class=\"err\">$(BASE_DIR)\/$*.c<\/span> <span class=\"err\">-o<\/span> <span class=\"err\">$*.o<\/span>\r\n<\/code><\/pre>\n<p>Rust\u3001relocation-model\u3092static\u306b\u3059\u308b\u3001panic\u3092abort\u306b\u3059\u308b\u3001\u4ee5\u5916\u306f\u666e\u901a\u306e\u30af\u30ed\u30b9\u30d3\u30eb\u30c9\u3067\u3057\u3087\u3046\u304b\u3002<\/p>\n<pre class=\"post-pre\"><code>    <span class=\"err\">(cd<\/span> <span class=\"err\">$(BASE_DIR);<\/span> <span class=\"err\">env<\/span> <span class=\"nv\">RUST_TARGET_PATH<\/span><span class=\"o\">=<\/span><span class=\"nv\">$(BASE_DIR)<\/span> <span class=\"nv\">$(XARGO)<\/span> rustc <span class=\"nf\">$(<\/span><span class=\"nb\">if<\/span> <span class=\"nv\">$(RELEASE)<\/span>,--release<span class=\"nf\">)<\/span> <span class=\"nf\">$(<\/span><span class=\"nb\">if<\/span> <span class=\"nv\">$(VERBOSE)<\/span>,--verbose<span class=\"nf\">)<\/span> <span class=\"nt\">--target<\/span> <span class=\"nv\">$(UTS_MACHINE)<\/span><span class=\"nt\">-unknown-none-gnu<\/span> <span class=\"nt\">--<\/span> <span class=\"nt\">-C<\/span> code-model<span class=\"o\">=<\/span>kernel <span class=\"nt\">-C<\/span> relocation-model<span class=\"o\">=<\/span>static <span class=\"nt\">-C<\/span> <span class=\"nv\">panic<\/span><span class=\"o\">=<\/span>abort<span class=\"o\">)<\/span>\r\n<\/code><\/pre>\n<p>Rust\u3068C\u8a00\u8a9e\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306e\u69cb\u6210\u3092\u3056\u3063\u3068\u898b\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<pre class=\"post-pre\"><code>\u251c\u2500\u2500 src\r\n\u2502   \u251c\u2500\u2500 io\r\n\u2502   \u2502   \u2514\u2500\u2500 mod.rs\r\n\u2502   \u251c\u2500\u2500 lang.rs\r\n\u2502   \u251c\u2500\u2500 lib.rs\r\n\u2502   \u251c\u2500\u2500 mem\r\n\u2502   \u2502   \u2514\u2500\u2500 mod.rs\r\n\u2502   \u251c\u2500\u2500 roulette.rs\r\n\u2502   \u2514\u2500\u2500 shim.c\r\n<\/code><\/pre>\n<div>\n<div class=\"post-table\">\u30d5\u30a1\u30a4\u30eb\u8aac\u660eshim.cLinux kernel driver\u3002init()\u3084open()\u3067Rust\u95a2\u6570\u3092\u547c\u3073\u51fa\u3059io\/mod.rsprintk\u306e\u30e9\u30c3\u30d1\u30fc\u3067print!\u30de\u30af\u30ed\u3092\u5b9a\u7fa9mem\/mod.rskmalloc\u306e\u30e9\u30c3\u30d1\u30fc\u3067\u30d2\u30fc\u30d7\u30a2\u30ed\u30b1\u30fc\u30bf\u3092\u5b9f\u88c5lang.rspanic_handler\u304a\u3088\u3073alloc_error_handler\u3092\u5b9a\u7fa9lib.rsinit(), exit()\u3067\u547c\u3070\u308c\u308b\u95a2\u6570\u3092\u5b9a\u7fa9roulette.rs\u4e00\u5b9a\u78ba\u7387\u3067panic\u3059\u308b\u51e6\u7406\u3092\u5b9a\u7fa9<\/div>\n<\/div>\n<h2>\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9<\/h2>\n<p>\u3067\u306f\u3001\u30b3\u30fc\u30c9\u3092\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n<h3>\u521d\u671f\u5316\/\u7d42\u4e86\u51e6\u7406<\/h3>\n<h4>driver\u30ed\u30fc\u30c9<\/h4>\n<p>\u307e\u305a\u306f\u3001\u521d\u671f\u5316\u3092\u8ffd\u3063\u3066\u3044\u304d\u307e\u3059\u3002<br \/>\nkernel driver\u306e\u30a8\u30f3\u30c8\u30ea\u30dd\u30a4\u30f3\u30c8\u306a\u306e\u3067\u3001C\u8a00\u8a9e\u304b\u3089\u3067\u3059\u3002<br \/>\n\u6700\u5f8c\u306e\u4e00\u884c\u4ee5\u5916\u306f\u3001\u666e\u901a\u306ekernel driver\u3067\u3059\u3002<br \/>\n\u30ad\u30e3\u30e9\u30af\u30bf\u30c7\u30d0\u30a4\u30b9\u3092\u767b\u9332\u3057\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u306f\u5f8c\u307b\u3069\u6539\u3081\u3066\u89e3\u8aac\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"cm\">\/*\r\n * The entry points in C\r\n *\/<\/span>\r\n<span class=\"k\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">_mod_init<\/span><span class=\"p\">(<\/span><span class=\"kt\">void<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n\r\n  <span class=\"c1\">\/\/ Register a character device<\/span>\r\n  <span class=\"n\">rl_dev_major_num<\/span> <span class=\"o\">=<\/span> <span class=\"n\">register_chrdev<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span> <span class=\"cm\">\/* allocate a major number *\/<\/span><span class=\"p\">,<\/span> <span class=\"n\">rl_device_name<\/span><span class=\"p\">,<\/span> <span class=\"o\">&amp;<\/span><span class=\"n\">rl_driver_fops<\/span><span class=\"p\">);<\/span>\r\n\r\n  <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">rl_dev_major_num<\/span> <span class=\"o\">&lt;<\/span> <span class=\"mi\">0<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">printk<\/span><span class=\"p\">(<\/span><span class=\"n\">KERN_ALERT<\/span> <span class=\"s\">\"failed to register character device: got major number %d<\/span><span class=\"se\">\\n<\/span><span class=\"s\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">rl_dev_major_num<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">rl_dev_major_num<\/span><span class=\"p\">;<\/span>\r\n  <span class=\"p\">}<\/span>\r\n\r\n  <span class=\"n\">printk<\/span><span class=\"p\">(<\/span><span class=\"n\">KERN_INFO<\/span> <span class=\"s\">\"Registered %s with major device number %d<\/span><span class=\"se\">\\n<\/span><span class=\"s\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">rl_device_name<\/span><span class=\"p\">,<\/span> <span class=\"n\">rl_dev_major_num<\/span><span class=\"p\">);<\/span>\r\n  <span class=\"n\">printk<\/span><span class=\"p\">(<\/span><span class=\"n\">KERN_INFO<\/span> <span class=\"s\">\"Run \/bin\/mknod \/dev\/%s c %d 0<\/span><span class=\"se\">\\n<\/span><span class=\"s\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">rl_device_name<\/span><span class=\"p\">,<\/span> <span class=\"n\">rl_dev_major_num<\/span><span class=\"p\">);<\/span>\r\n\r\n  <span class=\"k\">return<\/span> <span class=\"n\">rust_mod_init<\/span><span class=\"p\">();<\/span>\r\n<span class=\"p\">}<\/span>\r\n<span class=\"n\">init<\/span><span class=\"p\">(<\/span><span class=\"n\">_mod_init<\/span><span class=\"p\">);<\/span>\r\n<\/code><\/pre>\n<p>rust_mod_init()\u306f\u3001Rust\u306e\u95a2\u6570\u547c\u3073\u51fa\u3057\u3067\u3059\u3002shim.c\u5185\u3067extern\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"cm\">\/*\r\n * The entry points for the kernel module in Rust. We define\r\n * entry points in C for the module_init and module_exit macros.\r\n *\/<\/span>\r\n<span class=\"k\">extern<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">rust_mod_init<\/span><span class=\"p\">(<\/span><span class=\"kt\">void<\/span><span class=\"p\">);<\/span>\r\n<\/code><\/pre>\n<p>Rust\u5074\u306e\u5b9f\u88c5\u3092\u898b\u3066\u307f\u307e\u3057\u3087\u3046\u3002<br \/>\nno_mangle\u3067\u30de\u30f3\u30b0\u30eb\u3055\u308c\u306a\u3044\u3088\u3046\u306b\u3057\u3066\u3044\u308b\u4ee5\u5916\u306f\u3001\u666e\u901a\u306eRust\u306b\u898b\u3048\u307e\u3059\u306d\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\">\/\/ Entry points<\/span>\r\n<span class=\"nd\">#[no_mangle]<\/span>\r\n<span class=\"k\">pub<\/span> <span class=\"k\">extern<\/span> <span class=\"s\">\"C\"<\/span> <span class=\"k\">fn<\/span> <span class=\"nf\">rust_mod_init<\/span><span class=\"p\">()<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"nb\">i32<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"nd\">print!<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Panic probability: {}\/{}<\/span><span class=\"se\">\\n<\/span><span class=\"s\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">CONFIG<\/span><span class=\"nf\">.lock<\/span><span class=\"p\">()<\/span><span class=\"py\">.chance<\/span><span class=\"p\">,<\/span> <span class=\"n\">MAX_RAND<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"mi\">0<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u305f\u3060\u3001\u88cf\u3067\u306f\u8272\u3005\u3068\u52d5\u3044\u3066\u3044\u307e\u3059\u3002<br \/>\n\u9806\u756a\u306b\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<br \/>\nprint!\u30de\u30af\u30ed\u3001\u30d2\u30fc\u30d7\u30a2\u30ed\u30b1\u30fc\u30bf\u3001CONFIG\u3001\u306e\u9806\u756a\u306b\u898b\u3066\u3044\u304d\u307e\u3059\u3002<\/p>\n<h4>print!\u30de\u30af\u30ed<\/h4>\n<p>\u307e\u305a\u306f\u3001print!\u30de\u30af\u30ed\u3067\u3059\u3002<br \/>\n\u6a19\u6e96\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u4f7f\u3063\u3066\u3044\u306a\u3044\u305f\u3081\u3001printk()\u3092\u30e9\u30c3\u30d7\u3059\u308b\u4ed5\u7d44\u307f\u3092\u81ea\u4f5c\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\">\/\/\/ Like the `print!` macro in the standard library, but calls printk<\/span>\r\n<span class=\"nd\">#[allow(unused_macros)]<\/span>\r\n<span class=\"nd\">macro_rules!<\/span> <span class=\"n\">print<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"p\">(<\/span><span class=\"nv\">$<\/span><span class=\"p\">(<\/span><span class=\"nv\">$arg:tt<\/span><span class=\"p\">)<\/span><span class=\"o\">*<\/span><span class=\"p\">)<\/span> <span class=\"k\">=&gt;<\/span> <span class=\"p\">(<\/span><span class=\"nv\">$crate<\/span><span class=\"p\">::<\/span><span class=\"nn\">io<\/span><span class=\"p\">::<\/span><span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"nd\">format_args!<\/span><span class=\"p\">(<\/span><span class=\"nv\">$<\/span><span class=\"p\">(<\/span><span class=\"nv\">$arg<\/span><span class=\"p\">)<\/span><span class=\"o\">*<\/span><span class=\"p\">)));<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u3053\u306ecrate\u306eio\u30e2\u30b8\u30e5\u30fc\u30eb\u306eprint()\u3092\u8aad\u3093\u3067\u3044\u307e\u3059\u306d\u3002<br \/>\n\u3064\u307e\u308a\u3001\u540cio.rs\u5185\u306eprint()\u95a2\u6570\u3067\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">pub<\/span> <span class=\"k\">fn<\/span> <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">args<\/span><span class=\"p\">:<\/span> <span class=\"nn\">fmt<\/span><span class=\"p\">::<\/span><span class=\"n\">Arguments<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">use<\/span> <span class=\"nn\">core<\/span><span class=\"p\">::<\/span><span class=\"nn\">fmt<\/span><span class=\"p\">::<\/span><span class=\"n\">Write<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"k\">let<\/span> <span class=\"k\">mut<\/span> <span class=\"n\">writer<\/span> <span class=\"o\">=<\/span> <span class=\"n\">PRINTK_WRITER<\/span><span class=\"nf\">.lock<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"n\">writer<\/span><span class=\"nf\">.write_fmt<\/span><span class=\"p\">(<\/span><span class=\"n\">args<\/span><span class=\"p\">)<\/span><span class=\"nf\">.unwrap<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"n\">writer<\/span><span class=\"nf\">.flush<\/span><span class=\"p\">();<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>PRINTK_WRITER\u306e\u30ed\u30c3\u30af\u3092\u53d6\u5f97\u3057\u3001writer\u304c\u5b9f\u88c5\u3057\u3066\u3044\u308bWrite trait\u306ewrite_fmt()\u3092\u547c\u3073\u51fa\u3057\u3066\u3044\u307e\u3059\u3002<br \/>\n\u3053\u306ePRINTK_WRITER\u306f\u3001Mutex\u4ed8\u304d\u306eKernelDebugWriter\u3067\u3059\u3002<br \/>\nlazy_static!\u30de\u30af\u30ed\u3092\u5229\u7528\u3057\u3066\u3044\u308b\u306e\u3067\u3001\u6700\u521d\u306b\u4f7f\u308f\u308c\u308b\u3068\u304d\u306b\u521d\u671f\u5316\u3055\u308c\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">lazy_static!<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"c\">\/\/\/ Used by the `print!` and `println!` macros.<\/span>\r\n    <span class=\"k\">pub<\/span> <span class=\"k\">static<\/span> <span class=\"k\">ref<\/span> <span class=\"n\">PRINTK_WRITER<\/span><span class=\"p\">:<\/span> <span class=\"n\">Mutex<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">KernelDebugWriter<\/span><span class=\"o\">&gt;<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Mutex<\/span><span class=\"p\">::<\/span><span class=\"nf\">new<\/span><span class=\"p\">(<\/span><span class=\"nn\">KernelDebugWriter<\/span><span class=\"p\">::<\/span><span class=\"nf\">default<\/span><span class=\"p\">());<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>KernelDebugWriter\u306f\u3001\u6700\u7d42\u7684\u306b\u3001C\u8a00\u8a9e\u306eprintk()\u95a2\u6570\u3092\u547c\u3073\u51fa\u3057\u307e\u3059\u3002<br \/>\nprintk()\u95a2\u6570\u306b\u6e21\u3059\u6587\u5b57\u5217\u306f\u3001Vec\u3067\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">#[derive(Default)]<\/span>\r\n<span class=\"k\">pub<\/span> <span class=\"k\">struct<\/span> <span class=\"n\">KernelDebugWriter<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"n\">buffer<\/span><span class=\"p\">:<\/span> <span class=\"nb\">Vec<\/span><span class=\"o\">&lt;<\/span><span class=\"nb\">u8<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">,<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">extern<\/span> <span class=\"s\">\"C\"<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"c\">\/\/ printk()\u306e\u30e9\u30c3\u30d1\u30fc<\/span>\r\n    <span class=\"k\">fn<\/span> <span class=\"nf\">puts_c<\/span><span class=\"p\">(<\/span><span class=\"n\">len<\/span><span class=\"p\">:<\/span> <span class=\"nb\">u64<\/span><span class=\"p\">,<\/span> <span class=\"n\">c<\/span><span class=\"p\">:<\/span> <span class=\"o\">*<\/span><span class=\"k\">const<\/span> <span class=\"nb\">u8<\/span><span class=\"p\">);<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"c\">\/\/ `buffer`\u3092\u62e1\u5f35\u3057\u3066\u3001`buffer`\u306b\u6587\u5b57\u5217\u3092\u8ffd\u52a0\u3059\u308b\u3002<\/span>\r\n<span class=\"k\">impl<\/span> <span class=\"nn\">fmt<\/span><span class=\"p\">::<\/span><span class=\"n\">Write<\/span> <span class=\"k\">for<\/span> <span class=\"n\">KernelDebugWriter<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">fn<\/span> <span class=\"nf\">write_str<\/span><span class=\"p\">(<\/span><span class=\"o\">&amp;<\/span><span class=\"k\">mut<\/span> <span class=\"k\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">s<\/span><span class=\"p\">:<\/span> <span class=\"o\">&amp;<\/span><span class=\"nb\">str<\/span><span class=\"p\">)<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"nn\">fmt<\/span><span class=\"p\">::<\/span><span class=\"n\">Result<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"c\">\/\/ Add the bytes from `s` to the buffer<\/span>\r\n        <span class=\"k\">self<\/span><span class=\"py\">.buffer<\/span><span class=\"nf\">.extend<\/span><span class=\"p\">(<\/span><span class=\"n\">s<\/span><span class=\"nf\">.bytes<\/span><span class=\"p\">());<\/span>\r\n        <span class=\"nf\">Ok<\/span><span class=\"p\">(())<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">impl<\/span> <span class=\"n\">KernelDebugWriter<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"c\">\/\/ \u5b9f\u969b\u306b\u6587\u5b57\u3092\u51fa\u529b\u3059\u308b\u3002\u51fa\u529b\u304c\u7d42\u308f\u308b\u3068\u3001`buffer`\u3092\u30af\u30ea\u30a2\u3059\u308b\u3002<\/span>\r\n    <span class=\"k\">fn<\/span> <span class=\"nf\">flush<\/span><span class=\"p\">(<\/span><span class=\"o\">&amp;<\/span><span class=\"k\">mut<\/span> <span class=\"k\">self<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"c\">\/\/ Call c_puts with the string length and a pointer to its contents<\/span>\r\n        <span class=\"k\">unsafe<\/span> <span class=\"p\">{<\/span> <span class=\"nf\">puts_c<\/span><span class=\"p\">(<\/span><span class=\"k\">self<\/span><span class=\"py\">.buffer<\/span><span class=\"nf\">.len<\/span><span class=\"p\">()<\/span> <span class=\"k\">as<\/span> <span class=\"nb\">u64<\/span><span class=\"p\">,<\/span> <span class=\"k\">self<\/span><span class=\"py\">.buffer<\/span><span class=\"nf\">.as_ptr<\/span><span class=\"p\">()<\/span> <span class=\"k\">as<\/span> <span class=\"o\">*<\/span><span class=\"k\">const<\/span> <span class=\"nb\">u8<\/span><span class=\"p\">)<\/span> <span class=\"p\">};<\/span>\r\n        <span class=\"k\">self<\/span><span class=\"py\">.buffer<\/span><span class=\"nf\">.clear<\/span><span class=\"p\">();<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>Vec\u3092\u4f7f\u3063\u3066\u3044\u308b\u306e\u3067\u3001\u30d2\u30fc\u30d7\u30a2\u30ed\u30b1\u30fc\u30bf\u304c\u5fc5\u8981\u3067\u3059\u3002\u3053\u308c\u306f\u5f8c\u3067\u8aac\u660e\u3057\u307e\u3059\u3002<br \/>\nwrite_str()\u3067buffer\u306b\u6587\u5b57\u5217\u306e\u30c7\u30fc\u30bf\u3092\u8ffd\u52a0\u3057\u3001flush()\u3067C\u8a00\u8a9e\u306eput_c()\u3092\u547c\u3073\u51fa\u3057\u307e\u3059\u3002<\/p>\n<p>C\u8a00\u8a9e\u306e\u4e16\u754c\u306b\u623b\u308a\u307e\u3059\u3002put_c()\u306fprintk()\u306e\u30e9\u30c3\u30d1\u30fc\u3067\u3059\u306d\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"cm\">\/*\r\n * A utility function to print a string.\r\n * NOTE: `str` is not necessarily NULL-terminated.\r\n *\/<\/span>\r\n<span class=\"kt\">void<\/span> <span class=\"nf\">puts_c<\/span><span class=\"p\">(<\/span><span class=\"n\">u64<\/span> <span class=\"n\">length<\/span><span class=\"p\">,<\/span> <span class=\"kt\">char<\/span><span class=\"o\">*<\/span> <span class=\"n\">str<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"n\">printk<\/span><span class=\"p\">(<\/span><span class=\"n\">KERN_DEBUG<\/span> <span class=\"s\">\"%.*s\"<\/span><span class=\"p\">,<\/span> <span class=\"p\">(<\/span><span class=\"kt\">int<\/span><span class=\"p\">)<\/span><span class=\"n\">length<\/span><span class=\"p\">,<\/span> <span class=\"n\">str<\/span><span class=\"p\">);<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u3053\u308c\u3067\u3001Rust\u304b\u3089kernel\u30ed\u30b0\u3092\u51fa\u529b\u3067\u304d\u308b\u4ed5\u7d44\u307f\u304c\u308f\u304b\u308a\u307e\u3057\u305f\u3002<\/p>\n<h4>\u30d2\u30fc\u30d7\u30a2\u30ed\u30b1\u30fc\u30bf<\/h4>\n<p>kmalloc()\u3092\u30e9\u30c3\u30d7\u3057\u3066\u3001Vec\u306e\u5229\u7528\u3092\u89e3\u7981\u3057\u307e\u3059\u3002<\/p>\n<p>Rust\u306e\u30d9\u30a2\u30e1\u30bf\u30eb\u30d2\u30fc\u30d7\u30a2\u30ed\u30b1\u30fc\u30bf\u306b\u3064\u3044\u3066\u306f\u3001\u3053\u3061\u3089\u306e\u8a18\u4e8b\u3067\u66f8\u304d\u307e\u3057\u305f\u3002\u8a73\u7d30\u306b\u8208\u5473\u304c\u3042\u308c\u3070\u3054\u89a7\u4e0b\u3055\u3044\u3002<br \/>\nRedox Slab Allocator\u3067\u5b66\u3076Rust\u30d9\u30a2\u30e1\u30bf\u30eb\u74b0\u5883\u306e\u30d2\u30fc\u30d7\u30a2\u30ed\u30b1\u30fc\u30bf<\/p>\n<p>print!\u30de\u30af\u30ed\u3067\u306f\u3001\u6587\u5b57\u5217\u3092Vec\u306ebuffer\u3067\u30d0\u30c3\u30d5\u30a1\u30ea\u30f3\u30b0\u3057\u3066\u3001printk()\u306b\u51fa\u529b\u3092\u59d4\u8b72\u3057\u3066\u3044\u307e\u3057\u305f\u3002<br \/>\nVec\u3092\u4f7f\u3046\u305f\u3081\u306b\u306f\u3001\u30d2\u30fc\u30d7\u9818\u57df\u3092\u78ba\u4fdd\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u30d2\u30fc\u30d7\u9818\u57df\u3092\u4f7f\u3046\u305f\u3081\u306b\u306f\u3001GlobalAlloc trait\u3092\u5b9f\u88c5\u3057\u305f\u30a2\u30ed\u30b1\u30fc\u30bf\u3092#[global_allocator]\u30a2\u30c8\u30ea\u30d3\u30e5\u30fc\u30c8\u3092\u4ed8\u3051\u3066\u5b9a\u7fa9\u3057\u307e\u3059\u3002<br \/>\n\u30a2\u30ed\u30b1\u30fc\u30bf\u306f\u6b21\u306e\u3088\u3046\u306b\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\">\/\/ Set up the global allocator<\/span>\r\n<span class=\"nd\">#[global_allocator]<\/span>\r\n<span class=\"k\">static<\/span> <span class=\"n\">ALLOCATOR<\/span><span class=\"p\">:<\/span> <span class=\"nn\">mem<\/span><span class=\"p\">::<\/span><span class=\"n\">KernelAllocator<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">mem<\/span><span class=\"p\">::<\/span><span class=\"nn\">KernelAllocator<\/span><span class=\"p\">::<\/span><span class=\"nf\">new<\/span><span class=\"p\">();<\/span>\r\n<\/code><\/pre>\n<p>KernelAllocator\u306e\u5185\u90e8\u3092\u8ffd\u3063\u3066\u3044\u304d\u307e\u3059\u3002\u91cd\u8981\u306a\u306e\u306fGlobalAlloc trait\u306e\u5b9f\u88c5\u3067\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">#[derive(Default)]<\/span>\r\n<span class=\"k\">pub<\/span> <span class=\"k\">struct<\/span> <span class=\"n\">KernelAllocator<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"k\">impl<\/span> <span class=\"n\">KernelAllocator<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">pub<\/span> <span class=\"k\">const<\/span> <span class=\"k\">fn<\/span> <span class=\"nf\">new<\/span><span class=\"p\">()<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"n\">Self<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"n\">Self<\/span> <span class=\"p\">{}<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"c\">\/\/ Use shim functions to avoid hardcoding the GFP_KERNEL constant<\/span>\r\n<span class=\"nd\">#[allow(dead_code)]<\/span>\r\n<span class=\"k\">extern<\/span> <span class=\"s\">\"C\"<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">fn<\/span> <span class=\"nf\">kmalloc_c<\/span><span class=\"p\">(<\/span><span class=\"n\">size<\/span><span class=\"p\">:<\/span> <span class=\"nb\">usize<\/span><span class=\"p\">)<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"o\">*<\/span><span class=\"k\">mut<\/span> <span class=\"nb\">u8<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"k\">fn<\/span> <span class=\"nf\">kfree_c<\/span><span class=\"p\">(<\/span><span class=\"n\">ptr<\/span><span class=\"p\">:<\/span> <span class=\"o\">*<\/span><span class=\"k\">mut<\/span> <span class=\"nb\">u8<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"k\">fn<\/span> <span class=\"nf\">krealloc_c<\/span><span class=\"p\">(<\/span><span class=\"n\">ptr<\/span><span class=\"p\">:<\/span> <span class=\"o\">*<\/span><span class=\"k\">mut<\/span> <span class=\"nb\">u8<\/span><span class=\"p\">,<\/span> <span class=\"n\">size<\/span><span class=\"p\">:<\/span> <span class=\"nb\">usize<\/span><span class=\"p\">)<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"o\">*<\/span><span class=\"k\">mut<\/span> <span class=\"nb\">u8<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">unsafe<\/span> <span class=\"k\">impl<\/span> <span class=\"n\">GlobalAlloc<\/span> <span class=\"k\">for<\/span> <span class=\"n\">KernelAllocator<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">unsafe<\/span> <span class=\"k\">fn<\/span> <span class=\"nf\">alloc<\/span><span class=\"p\">(<\/span><span class=\"o\">&amp;<\/span><span class=\"k\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">layout<\/span><span class=\"p\">:<\/span> <span class=\"n\">Layout<\/span><span class=\"p\">)<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"o\">*<\/span><span class=\"k\">mut<\/span> <span class=\"nb\">u8<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"c\">\/\/ A side effect of the buddy allocator is that allocations are aligned to<\/span>\r\n        <span class=\"c\">\/\/ the power-of-two that is larger than the allocation size. So if the<\/span>\r\n        <span class=\"c\">\/\/ request needs to be aligned to something larger than the allocation size,<\/span>\r\n        <span class=\"c\">\/\/ we can just pass max(size, align) to kmalloc to get something reasonable<\/span>\r\n        <span class=\"c\">\/\/ at the cost of a few extra wasted bytes.<\/span>\r\n        <span class=\"k\">use<\/span> <span class=\"nn\">core<\/span><span class=\"p\">::<\/span><span class=\"nn\">cmp<\/span><span class=\"p\">::<\/span><span class=\"n\">max<\/span><span class=\"p\">;<\/span>\r\n        <span class=\"k\">let<\/span> <span class=\"n\">p<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">kmalloc_c<\/span><span class=\"p\">(<\/span><span class=\"nf\">max<\/span><span class=\"p\">(<\/span><span class=\"n\">layout<\/span><span class=\"nf\">.size<\/span><span class=\"p\">(),<\/span> <span class=\"n\">layout<\/span><span class=\"nf\">.align<\/span><span class=\"p\">()));<\/span>\r\n        <span class=\"k\">if<\/span> <span class=\"n\">p<\/span><span class=\"nf\">.is_null<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"mi\">0<\/span> <span class=\"k\">as<\/span> <span class=\"o\">*<\/span><span class=\"k\">mut<\/span> <span class=\"nb\">u8<\/span>            \r\n        <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"n\">p<\/span>\r\n        <span class=\"p\">}<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"k\">unsafe<\/span> <span class=\"k\">fn<\/span> <span class=\"nf\">dealloc<\/span><span class=\"p\">(<\/span><span class=\"o\">&amp;<\/span><span class=\"k\">self<\/span><span class=\"p\">,<\/span> <span class=\"n\">ptr<\/span><span class=\"p\">:<\/span> <span class=\"o\">*<\/span><span class=\"k\">mut<\/span> <span class=\"nb\">u8<\/span><span class=\"p\">,<\/span> <span class=\"mi\">_<\/span><span class=\"n\">layout<\/span><span class=\"p\">:<\/span> <span class=\"n\">Layout<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"nf\">kfree_c<\/span><span class=\"p\">(<\/span><span class=\"n\">ptr<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>alloc()\u3067\u306f\u3001kmalloc_c()\u3092\u547c\u3073\u51fa\u3057\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u306fC\u8a00\u8a9e\u306ekmalloc\u306e\u30e9\u30c3\u30d1\u30fc\u3067\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"cm\">\/*\r\n * Re-exported memory management functions\r\n *\/<\/span>\r\n<span class=\"kt\">void<\/span><span class=\"o\">*<\/span> <span class=\"nf\">kmalloc_c<\/span><span class=\"p\">(<\/span><span class=\"kt\">size_t<\/span> <span class=\"n\">size<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"k\">return<\/span> <span class=\"n\">kmalloc<\/span><span class=\"p\">(<\/span><span class=\"n\">size<\/span><span class=\"p\">,<\/span> <span class=\"n\">GFP_KERNEL<\/span><span class=\"p\">);<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u3053\u306e\u8584\u3044\u30e9\u30c3\u30d1\u30fc1\u679a\u3092\u4f5c\u308b\u3060\u3051\u3067\u3001Vec\u3084Box\u306a\u3069\u306e\u4fbf\u5229\u6a5f\u80fd\u304c\u89e3\u7981\u3068\u306a\u308b\u308f\u3051\u3067\u3059\u3002\u3053\u308c\u306f\u6717\u5831\u3067\u3059\u306d\uff01<\/p>\n<h4>CONFIG<\/h4>\n<p>Rust\u5074\u306e\u521d\u671f\u5316\u51e6\u7406\u3092\u518d\u63b2\u8f09\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\">\/\/ Entry points<\/span>\r\n<span class=\"nd\">#[no_mangle]<\/span>\r\n<span class=\"k\">pub<\/span> <span class=\"k\">extern<\/span> <span class=\"s\">\"C\"<\/span> <span class=\"k\">fn<\/span> <span class=\"nf\">rust_mod_init<\/span><span class=\"p\">()<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"nb\">i32<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"nd\">print!<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Panic probability: {}\/{}<\/span><span class=\"se\">\\n<\/span><span class=\"s\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">CONFIG<\/span><span class=\"nf\">.lock<\/span><span class=\"p\">()<\/span><span class=\"py\">.chance<\/span><span class=\"p\">,<\/span> <span class=\"n\">MAX_RAND<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"mi\">0<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>CONFIG.lock().chance\u306fkernel panic\u304c\u767a\u751f\u3059\u308b\u78ba\u7387\u3067\u3059\u3002\u3069\u306e\u3088\u3046\u306b\u521d\u671f\u5316\u3055\u308c\u3066\u3044\u308b\u304b\u898b\u3066\u3044\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">lazy_static!<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"c\">\/\/ CONFIG\u306fRouletteConfig\u3092Mutex\u3067\u5305\u3093\u3067\u3044\u307e\u3059<\/span>\r\n    <span class=\"k\">pub<\/span> <span class=\"k\">static<\/span> <span class=\"k\">ref<\/span> <span class=\"n\">CONFIG<\/span><span class=\"p\">:<\/span> <span class=\"n\">Mutex<\/span><span class=\"o\">&lt;<\/span><span class=\"n\">RouletteConfig<\/span><span class=\"o\">&gt;<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Mutex<\/span><span class=\"p\">::<\/span><span class=\"nf\">new<\/span><span class=\"p\">(<\/span><span class=\"nn\">RouletteConfig<\/span><span class=\"p\">::<\/span><span class=\"nf\">new<\/span><span class=\"p\">());<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"nd\">#[derive(Default)]<\/span>\r\n<span class=\"k\">pub<\/span> <span class=\"k\">struct<\/span> <span class=\"n\">RouletteConfig<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">pub<\/span> <span class=\"n\">chance<\/span><span class=\"p\">:<\/span> <span class=\"nb\">u8<\/span><span class=\"p\">,<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">impl<\/span> <span class=\"n\">RouletteConfig<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">pub<\/span> <span class=\"k\">fn<\/span> <span class=\"nf\">new<\/span><span class=\"p\">()<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"n\">Self<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"c\">\/\/ MIN_RAND(0)\u304b\u3089MAX_RAND(100)\u306e\u7bc4\u56f2\u3067\u4e71\u6570\u3092\u751f\u6210\u3057\u307e\u3059<\/span>\r\n        <span class=\"k\">let<\/span> <span class=\"n\">chance<\/span> <span class=\"o\">=<\/span> <span class=\"n\">RNG<\/span><span class=\"nf\">.lock<\/span><span class=\"p\">()<\/span><span class=\"nf\">.gen_range<\/span><span class=\"p\">(<\/span><span class=\"n\">MIN_RAND<\/span><span class=\"p\">,<\/span> <span class=\"n\">MAX_RAND<\/span><span class=\"p\">);<\/span>\r\n        <span class=\"n\">RouletteConfig<\/span> <span class=\"p\">{<\/span> <span class=\"n\">chance<\/span><span class=\"p\">:<\/span> <span class=\"n\">chance<\/span> <span class=\"p\">}<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u6b63\u78ba\u306b\u306f\u30010\uff5e99\u306e\u7bc4\u56f2\u3067\u4e71\u6570\u3092\u751f\u6210\u3057\u307e\u3059\u3002API\u306e\u89e3\u8aac\u306f\u6b21\u306e\u901a\u308a\u3067\u3059\u3002<\/p>\n<blockquote><p>Generate a random value in the range [low, high), i.e. inclusive of low and exclusive of high.<\/p><\/blockquote>\n<p>RNG\u306f\u6b21\u306e\u3088\u3046\u306b\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u307e\u3059\u3002JitterRng\u3068\u3044\u3046\u4e71\u6570\u751f\u6210\u5668\u3092Mutex\u3067\u5305\u3093\u3067\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">lazy_static!<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">static<\/span> <span class=\"k\">ref<\/span> <span class=\"n\">RNG<\/span><span class=\"p\">:<\/span> <span class=\"n\">Mutex<\/span><span class=\"o\">&lt;<\/span><span class=\"nn\">rand<\/span><span class=\"p\">::<\/span><span class=\"n\">JitterRng<\/span><span class=\"o\">&gt;<\/span> <span class=\"o\">=<\/span> <span class=\"nn\">Mutex<\/span><span class=\"p\">::<\/span><span class=\"nf\">new<\/span><span class=\"p\">(<\/span><span class=\"nn\">rand<\/span><span class=\"p\">::<\/span><span class=\"nn\">JitterRng<\/span><span class=\"p\">::<\/span><span class=\"nf\">new_with_timer<\/span><span class=\"p\">(||<\/span> <span class=\"k\">unsafe<\/span> <span class=\"p\">{<\/span> <span class=\"nf\">nanosecond_timer_c<\/span><span class=\"p\">()<\/span> <span class=\"p\">}));<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>JitterRng\u306fCPU\u5b9f\u884c\u6642\u9593\u306e\u30b8\u30c3\u30bf\u3068\u30e1\u30e2\u30ea\u30a2\u30af\u30bb\u30b9\u306e\u30b8\u30c3\u30bf\u3068\u3092\u4f7f\u3063\u305f\u3001\u4e71\u6570\u30b8\u30a7\u30cd\u30ec\u30fc\u30bf\u3001\u3068\u306e\u3053\u3068\u3067\u3059\u3002<br \/>\nnew_with_timer()\u3067\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u751f\u6210\u3057\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u306f\u3001no_std\u74b0\u5883\u3067JitterRng\u3092\u4f7f\u3046\u5834\u5408\u306eAPI\u3067\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">pub<\/span> <span class=\"k\">fn<\/span> <span class=\"nf\">new_with_timer<\/span><span class=\"p\">(<\/span><span class=\"n\">timer<\/span><span class=\"p\">:<\/span> <span class=\"k\">fn<\/span><span class=\"p\">()<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"nb\">u64<\/span><span class=\"p\">)<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"n\">JitterRng<\/span>\r\n<\/code><\/pre>\n<blockquote><p>Create a new JitterRng. A custom timer can be supplied, making it possible to use JitterRng in no_std environments.<\/p><\/blockquote>\n<p>new_with_timer()\u3067\u6e21\u3057\u3066\u3044\u308b\u30af\u30ed\u30fc\u30b8\u30e3\u3067\u306f\u3001C\u8a00\u8a9e\u306enanosecond_timer_c()\u3092\u547c\u3093\u3067\u3044\u307e\u3059\u3002<br \/>\n\u3053\u306e\u4e2d\u3067\u306fjiffies\u3092\u53d6\u5f97\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"cm\">\/*\r\n * This isn't really a nanosecond timer but its close enough.\r\n *\/<\/span>\r\n<span class=\"n\">u64<\/span> <span class=\"nf\">nanosecond_timer_c<\/span><span class=\"p\">(<\/span><span class=\"kt\">void<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"k\">return<\/span> <span class=\"n\">get_jiffies_64<\/span><span class=\"p\">();<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u5c11\u3057\u6574\u7406\u3059\u308b\u3068\u3001RNG\u306fMutex\u3067\u5305\u307e\u308c\u305f\u4e71\u6570\u30b8\u30a7\u30cd\u30ec\u30fc\u30bf\u3067\u3059\u3002<br \/>\nRNG.gen_range(MIN_RAND, MAX_RAND)\u3092\u547c\u3073\u51fa\u3059\u3068\u3001\u30af\u30ed\u30fc\u30b8\u30e3\u3067jiffies\u3092\u53d6\u5f97\u3057\u30010\u304b\u308999\u306e\u7bc4\u56f2\u3067\u4e71\u6570\u3092\u751f\u6210\u3057\u307e\u3059\u3002<br \/>\nCONFIG\u306f\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u751f\u6210\u6642\u306b\u3001RNG.get_range()\u3092\u547c\u3073\u51fa\u3057\u3001panic\u78ba\u7387\u3067\u3042\u308bchance\u3092\u521d\u671f\u5316\u3057\u307e\u3059\u3002<\/p>\n<p>\u7d42\u4e86\u51e6\u7406\u306f\u7279\u306b\u96e3\u3057\u3044\u3053\u3068\u3092\u3057\u3066\u3044\u306a\u3044\u306e\u3067\u3001\u7701\u7565\u3057\u307e\u3059\u3002<\/p>\n<h3>\u30ed\u30b7\u30a2\u30f3\u30eb\u30fc\u30ec\u30c3\u30c8\u5b9f\u884c<\/h3>\n<p>\u305d\u308c\u3067\u306f\u3001\u809d\u5fc3\u306e\u30ed\u30b7\u30a2\u30f3\u30eb\u30fc\u30ec\u30c3\u30c8\u5b9f\u884c\u90e8\u5206\u3092\u898b\u3066\u3044\u304d\u307e\u3059\u3002<br \/>\n\u8a18\u4e8b\u306e\u6700\u521d\u306e\u65b9\u3067\u3084\u3063\u305f\u901a\u308a\u3001\/dev\/kernel-roulette\u3092cat\u3057\u305f\u3068\u304d(\u3088\u308a\u6b63\u78ba\u306b\u306fopen()\u547c\u3073\u51fa\u3057\u6642)\u306b\u4e71\u6570\u3092\u751f\u6210\u3057\u3001chance\u3088\u308a\u5c0f\u3055\u306a\u5024\u304c\u51fa\u308b\u3068panic\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code>$ cat \/dev\/kernel-roulette\r\nSurvived... sampled value is 86, which is &gt;= 49\r\n$ cat \/dev\/kernel-roulette\r\nSegmentation fault\r\n<\/code><\/pre>\n<p>\u6b8b\u5ff5\u306a\u3053\u3068\u306b\u3001\u30c7\u30d0\u30a4\u30b9\u30d5\u30a1\u30a4\u30eb\u306e\u64cd\u4f5c\u306f\u307b\u3068\u3093\u3069C\u8a00\u8a9e\u3067\u51e6\u7406\u3057\u3066\u3044\u307e\u3059\u3002<br \/>\n\u307e\u305a\u3001\u30ad\u30e3\u30e9\u30af\u30bf\u30c7\u30d0\u30a4\u30b9\u3067\u3059\u304c\u3001_mod_init()\u3067\u767b\u9332\u3057\u3066\u3044\u307e\u3057\u305f\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">_mod_init<\/span><span class=\"p\">(<\/span><span class=\"kt\">void<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n\r\n  <span class=\"c1\">\/\/ Register a character device<\/span>\r\n  <span class=\"n\">rl_dev_major_num<\/span> <span class=\"o\">=<\/span> <span class=\"n\">register_chrdev<\/span><span class=\"p\">(<\/span><span class=\"mi\">0<\/span> <span class=\"cm\">\/* allocate a major number *\/<\/span><span class=\"p\">,<\/span> <span class=\"n\">rl_device_name<\/span><span class=\"p\">,<\/span> <span class=\"o\">&amp;<\/span><span class=\"n\">rl_driver_fops<\/span><span class=\"p\">);<\/span>\r\n<span class=\"p\">...<\/span>\r\n<\/code><\/pre>\n<p>\u30ad\u30e3\u30e9\u30af\u30bf\u30c7\u30d0\u30a4\u30b9\u30c9\u30e9\u30a4\u30d0\u306b\u306f\u3001open(), release(), read()\u304c\u5b9f\u88c5\u3055\u308c\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">rl_device_open<\/span><span class=\"p\">(<\/span><span class=\"k\">struct<\/span> <span class=\"n\">inode<\/span><span class=\"o\">*<\/span> <span class=\"n\">inode<\/span><span class=\"p\">,<\/span> <span class=\"k\">struct<\/span> <span class=\"n\">file<\/span><span class=\"o\">*<\/span> <span class=\"n\">filp<\/span><span class=\"p\">);<\/span>\r\n<span class=\"k\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">rl_device_release<\/span><span class=\"p\">(<\/span><span class=\"k\">struct<\/span> <span class=\"n\">inode<\/span><span class=\"o\">*<\/span> <span class=\"n\">inode<\/span><span class=\"p\">,<\/span> <span class=\"k\">struct<\/span> <span class=\"n\">file<\/span><span class=\"o\">*<\/span> <span class=\"n\">filp<\/span><span class=\"p\">);<\/span>\r\n<span class=\"k\">static<\/span> <span class=\"kt\">ssize_t<\/span> <span class=\"nf\">rl_device_read<\/span><span class=\"p\">(<\/span><span class=\"k\">struct<\/span> <span class=\"n\">file<\/span><span class=\"o\">*<\/span> <span class=\"n\">filp<\/span><span class=\"p\">,<\/span>    <span class=\"cm\">\/* see include\/linux\/fs.h   *\/<\/span>\r\n                              <span class=\"kt\">char<\/span> <span class=\"n\">__user<\/span><span class=\"o\">*<\/span> <span class=\"n\">buffer<\/span><span class=\"p\">,<\/span>  <span class=\"cm\">\/* buffer to fill with data *\/<\/span>\r\n                              <span class=\"kt\">size_t<\/span> <span class=\"n\">length<\/span><span class=\"p\">,<\/span>    <span class=\"cm\">\/* length of the buffer  *\/<\/span>\r\n                              <span class=\"n\">loff_t<\/span><span class=\"o\">*<\/span> <span class=\"n\">offset<\/span> <span class=\"cm\">\/* the file offset *\/<\/span><span class=\"p\">);<\/span>\r\n<span class=\"k\">static<\/span> <span class=\"k\">struct<\/span> <span class=\"n\">file_operations<\/span> <span class=\"n\">rl_driver_fops<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"p\">.<\/span><span class=\"n\">read<\/span> <span class=\"o\">=<\/span> <span class=\"n\">rl_device_read<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"p\">.<\/span><span class=\"n\">open<\/span> <span class=\"o\">=<\/span> <span class=\"n\">rl_device_open<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"p\">.<\/span><span class=\"n\">release<\/span> <span class=\"o\">=<\/span> <span class=\"n\">rl_device_release<\/span><span class=\"p\">,<\/span>\r\n<span class=\"p\">};<\/span>\r\n<span class=\"k\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">rl_dev_major_num<\/span> <span class=\"o\">=<\/span> <span class=\"mi\">0<\/span><span class=\"p\">;<\/span>\r\n<span class=\"k\">static<\/span> <span class=\"k\">const<\/span> <span class=\"kt\">char<\/span> <span class=\"n\">rl_device_name<\/span><span class=\"p\">[]<\/span> <span class=\"o\">=<\/span> <span class=\"s\">\"kernel-roulette\"<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<p>release()\u3068read()\u304b\u3089\u306fRust\u3092\u547c\u3093\u3067\u3044\u306a\u3044\u305f\u3081\u3001open()\u3060\u3051\u89e3\u8aac\u3057\u307e\u3059\u3002<br \/>\nRust\u3092\u547c\u3093\u3067\u3044\u308b\u306e\u306f\u3001sample()\u306e\u90e8\u5206\u3067\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">static<\/span> <span class=\"kt\">int<\/span> <span class=\"nf\">rl_device_open<\/span><span class=\"p\">(<\/span><span class=\"k\">struct<\/span> <span class=\"n\">inode<\/span><span class=\"o\">*<\/span> <span class=\"n\">inode<\/span><span class=\"p\">,<\/span> <span class=\"k\">struct<\/span> <span class=\"n\">file<\/span><span class=\"o\">*<\/span> <span class=\"n\">filp<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"n\">u8<\/span> <span class=\"n\">sampled<\/span><span class=\"p\">;<\/span>\r\n  <span class=\"k\">struct<\/span> <span class=\"n\">rl_state<\/span><span class=\"o\">*<\/span> <span class=\"n\">state<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">...<\/span>\r\n  <span class=\"c1\">\/\/ Get a sample from Rust<\/span>\r\n  <span class=\"n\">sampled<\/span> <span class=\"o\">=<\/span> <span class=\"n\">sample<\/span><span class=\"p\">();<\/span> <span class=\"c1\">\/\/ may panic!<\/span>\r\n<span class=\"p\">...<\/span>\r\n  <span class=\"c1\">\/\/ read()\u3067\u8aad\u307f\u3060\u3059\u30c7\u30fc\u30bf\u3092\u3053\u3053\u3067\u4f5c\u6210\u3057\u307e\u3059<\/span>\r\n  <span class=\"c1\">\/\/ Format data and store in string<\/span>\r\n  <span class=\"n\">snprintf<\/span><span class=\"p\">(<\/span><span class=\"n\">state<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">data<\/span><span class=\"p\">,<\/span> <span class=\"n\">MAX_BUFFER_SIZE<\/span><span class=\"p\">,<\/span> <span class=\"s\">\"Survived... sampled value is %d, which is &gt;= %d<\/span><span class=\"se\">\\n<\/span><span class=\"s\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">sampled<\/span><span class=\"p\">,<\/span> <span class=\"n\">get_chance<\/span><span class=\"p\">());<\/span>\r\n<span class=\"p\">...<\/span>\r\n  <span class=\"c1\">\/\/ Set private_data to the state we allocated<\/span>\r\n  <span class=\"n\">filp<\/span><span class=\"o\">-&gt;<\/span><span class=\"n\">private_data<\/span> <span class=\"o\">=<\/span> <span class=\"n\">state<\/span><span class=\"p\">;<\/span>\r\n  <span class=\"k\">return<\/span> <span class=\"n\">SUCCESS<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>Rust\u306esample()\u306f\u6b21\u306e\u901a\u308a\u3067\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">#[no_mangle]<\/span>\r\n<span class=\"k\">pub<\/span> <span class=\"k\">extern<\/span> <span class=\"s\">\"C\"<\/span> <span class=\"k\">fn<\/span> <span class=\"nf\">sample<\/span><span class=\"p\">()<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"nb\">u8<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"k\">let<\/span> <span class=\"n\">sampled<\/span> <span class=\"o\">=<\/span> <span class=\"n\">RNG<\/span><span class=\"nf\">.lock<\/span><span class=\"p\">()<\/span><span class=\"nf\">.gen_range<\/span><span class=\"p\">(<\/span><span class=\"n\">MIN_RAND<\/span><span class=\"p\">,<\/span> <span class=\"n\">MAX_RAND<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"n\">sampled<\/span> <span class=\"o\">&lt;<\/span> <span class=\"n\">CONFIG<\/span><span class=\"nf\">.lock<\/span><span class=\"p\">()<\/span><span class=\"py\">.chance<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"nd\">panic!<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Boom!\"<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"n\">sampled<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u65b0\u305f\u306b\u751f\u6210\u3057\u305f\u4e71\u6570\u304c\u3001chance\u3088\u308a\u5c0f\u3055\u3051\u308c\u3070\u3001&#8221;Boom&#8221;\u3092\u51fa\u529b\u3057\u3066\u3001panic\u3057\u307e\u3059\u3002<br \/>\npanic_handler\u306f\u6b21\u306e\u3088\u3046\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"nd\">#[panic_handler]<\/span>\r\n<span class=\"nd\">#[no_mangle]<\/span>\r\n<span class=\"k\">pub<\/span> <span class=\"k\">fn<\/span> <span class=\"nf\">rust_begin_panic<\/span><span class=\"p\">(<\/span><span class=\"n\">info<\/span><span class=\"p\">:<\/span> <span class=\"o\">&amp;<\/span><span class=\"n\">PanicInfo<\/span><span class=\"p\">)<\/span> <span class=\"k\">-&gt;<\/span> <span class=\"o\">!<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"c\">\/\/ Print the file and line number<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"k\">let<\/span> <span class=\"nf\">Some<\/span><span class=\"p\">(<\/span><span class=\"n\">location<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> <span class=\"n\">info<\/span><span class=\"nf\">.location<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"nd\">println!<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Rust panic @ {}:{}\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"n\">location<\/span><span class=\"nf\">.file<\/span><span class=\"p\">(),<\/span> <span class=\"n\">location<\/span><span class=\"nf\">.line<\/span><span class=\"p\">());<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"c\">\/\/ Print the message and a newline<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"k\">let<\/span> <span class=\"nf\">Some<\/span><span class=\"p\">(<\/span><span class=\"n\">message<\/span><span class=\"p\">)<\/span> <span class=\"o\">=<\/span> <span class=\"n\">info<\/span><span class=\"nf\">.message<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"nd\">println!<\/span><span class=\"p\">(<\/span><span class=\"s\">\"{}\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">message<\/span><span class=\"p\">);<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"k\">unsafe<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"c\">\/\/ In a real kernel module, we should use abort() instead of panic()<\/span>\r\n        <span class=\"nf\">abort<\/span><span class=\"p\">()<\/span> <span class=\"c\">\/\/ replace with panic_c() if you want<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u6700\u7d42\u7684\u306bC\u8a00\u8a9e\u306eabort()\u3092\u547c\u3093\u3067\u3044\u307e\u3059\u3002abort()\u306fBUG()\u3092\u547c\u3073\u51fa\u3057\u307e\u3059\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"cm\">\/*\r\n * Define the abort() function. We use the BUG() macro, which generates a ud2 instruction.\r\n *\/<\/span>\r\n<span class=\"kt\">void<\/span> <span class=\"nf\">abort<\/span><span class=\"p\">(<\/span><span class=\"kt\">void<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"n\">BUG<\/span><span class=\"p\">();<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u3061\u306a\u307f\u306b\u3001abort()\u306e\u4ee3\u308f\u308a\u306b\u3001panic_c()\u3092\u547c\u3073\u51fa\u3059\u3068\u2026<\/p>\n<pre class=\"post-pre\"><code><span class=\"kt\">void<\/span> <span class=\"nf\">panic_c<\/span><span class=\"p\">(<\/span><span class=\"kt\">void<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"n\">panic<\/span><span class=\"p\">(<\/span><span class=\"s\">\"Panic!\"<\/span><span class=\"p\">);<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u672c\u5f53\u306b\u30d5\u30ea\u30fc\u30ba\u3057\u307e\u3059\u3002<\/p>\n<p>\u4ee5\u4e0a\u3067\u4e3b\u8981\u306a\u51e6\u7406\u306e\u89e3\u6790\u306f\u5b8c\u4e86\u3067\u3059\u3002<br \/>\n\u3044\u304b\u304c\u3067\u3057\u305f\u3067\u3057\u3087\u3046\u304b\u3002<\/p>\n<h1>\u307e\u3068\u3081<\/h1>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">Linux kernel module\u304b\u3089Rust\u3092\u547c\u3079\u307e\u3059\u3002Rust\u3092\u30e9\u30a4\u30d6\u30e9\u30ea\u3067\u30d3\u30eb\u30c9\u3057\u3066\u304a\u304d\u3001C\u8a00\u8a9e\u306ekernel module object\u3068\u30ea\u30f3\u30af\u3059\u308b\u3060\u3051\u3067\u3059\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">kmalloc()\u306e\u30e9\u30c3\u30d1\u30fc\u3092\u7528\u610f\u3059\u308b\u3053\u3068\u3067\u3001Vec\u306a\u3069\u3001\u30d2\u30fc\u30d7\u9818\u57df\u3092\u4f7f\u3046\u6a5f\u80fd\u304c\u4f7f\u3048\u307e\u3059\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\n<li style=\"list-style-type: none;\">\n<ul class=\"post-ul\">printk()\u306e\u30e9\u30c3\u30d1\u30fc\u3092\u7528\u610f\u3059\u308b\u3053\u3068\u3067\u3001print!\u30de\u30af\u30ed\u3092\u4f5c\u3063\u3066\u3001\u6a19\u6e96\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u3088\u3046\u306b\u4f7f\u3048\u307e\u3059\u3002<\/ul>\n<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<ul class=\"post-ul\">\u6b8b\u5ff5\u306a\u304c\u3089\u30c7\u30d0\u30a4\u30b9\u30d5\u30a1\u30a4\u30eb\u306e\u64cd\u4f5c\u306f\u307b\u3068\u3093\u3069C\u8a00\u8a9e\u3067\u3057\u305f\u3002<\/ul>\n<h1>\u53c2\u8003<\/h1>\n<p>kernel-roulette<\/p>\n","protected":false},"excerpt":{"rendered":"<p>kernel-roulette Rust\u3067Linux kernel module\u304c\u66f8\u3051\u308b\u2026\u3002\u5642\u306e\u771f\u76f8\u3092\u7a81\u304d\u6b62\u3081 [&hellip;]<\/p>\n","protected":false},"author":7,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-45444","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>- Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:description\" content=\"kernel-roulette Rust\u3067Linux kernel module\u304c\u66f8\u3051\u308b\u2026\u3002\u5642\u306e\u771f\u76f8\u3092\u7a81\u304d\u6b62\u3081 [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-01-21T01:45:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-04T09:36:19+00:00\" \/>\n<meta name=\"author\" content=\"\u79d1, \u9896\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u79d1, \u9896\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/\",\"name\":\"- Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-01-21T01:45:35+00:00\",\"dateModified\":\"2024-05-04T09:36:19+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/\"]}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e\",\"name\":\"\u79d1, \u9896\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g\",\"caption\":\"\u79d1, \u9896\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/keying\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"- Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/","og_locale":"zh_CN","og_type":"article","og_description":"kernel-roulette Rust\u3067Linux kernel module\u304c\u66f8\u3051\u308b\u2026\u3002\u5642\u306e\u771f\u76f8\u3092\u7a81\u304d\u6b62\u3081 [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-01-21T01:45:35+00:00","article_modified_time":"2024-05-04T09:36:19+00:00","author":"\u79d1, \u9896","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u79d1, \u9896","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"11 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/","name":"- Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-01-21T01:45:35+00:00","dateModified":"2024-05-04T09:36:19+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/"]}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/8ca01ba7f7362ad4edb7da206a12f29e","name":"\u79d1, \u9896","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8a6fb3cc7ba2f69d2189ba532aec4633ea7ed75ac0af162ec367cb3abc0fb2af?s=96&d=mm&r=g","caption":"\u79d1, \u9896"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/keying\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/45444-2\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/45444","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=45444"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/45444\/revisions"}],"predecessor-version":[{"id":99725,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/45444\/revisions\/99725"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=45444"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=45444"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=45444"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}