genact/modules/
kernel_compile.rs1use async_trait::async_trait;
3use rand::prelude::*;
4use regex::Regex;
5
6use crate::args::AppConfig;
7use crate::data::CFILES_LIST;
8use crate::io::{csleep, newline, print};
9use crate::modules::Module;
10
11fn gen_header(arch: &str, rng: &mut ThreadRng) -> String {
13 const RARE_CMDS: &[&str] = &["SYSTBL ", "SYSHDR "];
14
15 const CMDS: &[&str] = &["WRAP ", "CHK ", "UPD "];
16
17 let cmd = if rng.gen_bool(1.0 / 15.0) {
18 RARE_CMDS.choose(rng).unwrap_or(&"")
19 } else {
20 CMDS.choose(rng).unwrap_or(&"")
21 };
22
23 let cfile = &CFILES_LIST.choose(rng).unwrap_or(&"");
24 let mut file = format!("{}h", &cfile[..cfile.len() - 1]);
25
26 if file.starts_with("arch") {
27 let re = Regex::new(r"arch/([a-z0-9_])+/").unwrap();
28 file = re
29 .replace(&file, format!("arch/{arch}/").as_str())
30 .into_owned();
31 }
32
33 format!(" {cmd} {file}")
34}
35
36fn gen_object(arch: &str, rng: &mut ThreadRng) -> String {
38 const RARE_CMDS: &[&str] = &["HOSTCC ", "AS "];
39
40 let cmd = if rng.gen_bool(1.0 / 15.0) {
41 RARE_CMDS.choose(rng).unwrap_or(&"")
42 } else if rng.gen_bool(0.33) {
43 "AR "
44 } else {
45 "CC "
46 };
47
48 let cfile = &CFILES_LIST.choose(rng).unwrap_or(&"");
49 let mut file = format!("{}o", cfile[..cfile.len() - 1].to_owned());
50
51 if file.starts_with("arch") {
52 let re = Regex::new(r"arch/([a-z0-9_])+/").unwrap();
53 file = re
54 .replace(&file, format!("arch/{arch}/").as_str())
55 .into_owned();
56 }
57
58 format!(" {cmd} {file}")
59}
60
61fn gen_special(arch: &str, rng: &mut ThreadRng) -> String {
63 const SPECIALS: &[&str] = &[
64 "HOSTLD arch/ARCH/tools/relocs",
65 "HOSTLD scripts/mod/modpost",
66 "MKELF scripts/mod/elfconfig.h",
67 "LDS arch/ARCH/entry/vdso/vdso32/vdso32.lds",
68 "LDS arch/ARCH/kernel/vmlinux.lds",
69 "LDS arch/ARCH/realmode/rm/realmode.lds",
70 "LDS arch/ARCH/boot/compressed/vmlinux.lds",
71 "EXPORTS arch/ARCH/lib/lib-ksyms.o",
72 "EXPORTS lib/lib-ksyms.o",
73 "MODPOST vmlinux.o",
74 "SORTEX vmlinux",
75 "SYSMAP System.map",
76 "VOFFSET arch/ARCH/boot/compressed/../voffset.h",
77 "OBJCOPY arch/ARCH/entry/vdso/vdso32.so",
78 "OBJCOPY arch/ARCH/realmode/rm/realmode.bin",
79 "OBJCOPY arch/ARCH/boot/compressed/vmlinux.bin",
80 "OBJCOPY arch/ARCH/boot/vmlinux.bin",
81 "VDSO2C arch/ARCH/entry/vdso/vdso-image-32.c",
82 "VDSO arch/ARCH/entry/vdso/vdso32.so.dbg",
83 "RELOCS arch/ARCH/realmode/rm/realmode.relocs",
84 "PASYMS arch/ARCH/realmode/rm/pasyms.h",
85 "XZKERN arch/ARCH/boot/compressed/vmlinux.bin.xz",
86 "MKPIGGY arch/ARCH/boot/compressed/piggy.S",
87 "DATAREL arch/ARCH/boot/compressed/vmlinux",
88 "ZOFFSET arch/ARCH/boot/zoffset.h",
89 ];
90
91 let special = SPECIALS.choose(rng).unwrap_or(&"").to_string();
92 let special = special.replace("ARCH", arch);
93
94 format!(" {special}")
95}
96
97fn gen_line(arch: &str, rng: &mut ThreadRng) -> String {
99 if rng.gen_bool(1.0 / 50.0) {
100 gen_special(arch, rng)
101 } else if rng.gen_bool(0.1) {
102 gen_header(arch, rng)
103 } else {
104 gen_object(arch, rng)
105 }
106}
107
108pub struct KernelCompile;
109
110#[async_trait(?Send)]
111impl Module for KernelCompile {
112 fn name(&self) -> &'static str {
113 "kernel_compile"
114 }
115
116 fn signature(&self) -> String {
117 "sudo make install".to_string()
118 }
119
120 async fn run(&self, appconfig: &AppConfig) {
121 let mut rng = thread_rng();
122 let num_lines = rng.gen_range(50..500);
123
124 const ARCHES: &[&str] = &[
125 "alpha",
126 "arc",
127 "arm",
128 "arm64",
129 "blackfin",
130 "c6x",
131 "cris",
132 "frv",
133 "h8300",
134 "hexagon",
135 "ia64",
136 "m32r",
137 "m68k",
138 "metag",
139 "microblaze",
140 "mips",
141 "mn10300",
142 "nios2",
143 "openrisc",
144 "parisc",
145 "powerpc",
146 "s390",
147 "score",
148 "sh",
149 "sparc",
150 "tile",
151 "um",
152 "unicore32",
153 "x86",
154 "xtensa",
155 ];
156
157 let arch = ARCHES.choose(&mut rng).unwrap_or(&"x86");
158
159 for _ in 1..num_lines {
160 let line = gen_line(arch, &mut rng);
161 let sleep_length = rng.gen_range(10..1000);
162
163 print(line).await;
164 newline().await;
165 csleep(sleep_length).await;
166
167 if appconfig.should_exit() {
168 return;
169 }
170 }
171
172 print(format!("BUILD arch/{arch}/boot/bzImage")).await;
173 newline().await;
174
175 newline().await;
176
177 let bytes: u32 = rng.gen_range(9000..1_000_000);
178 let padded_bytes: u32 = rng.gen_range(bytes..1_100_000);
179
180 print(format!(
181 "Setup is {bytes} bytes (padded to {padded_bytes} bytes)."
182 ))
183 .await;
184 newline().await;
185
186 let system: u32 = rng.gen_range(300..3000);
187 print(format!("System is {system} kB")).await;
188 newline().await;
189
190 let crc: u32 = rng.gen_range(0x1000_0000..0xffff_ffff);
191
192 print(format!("CRC {crc:x}")).await;
193 newline().await;
194
195 print(format!("Kernel: arch/{arch}/boot/bzImage is ready (#1)")).await;
196 newline().await;
197
198 newline().await;
199 }
200}