
すべての初心者プログラマーは、正しいエラー報告の重要性について常に知らされています。彼らはいつも、プログラムが何かをすることができなかった場合、それがなぜ起こったのかを明確かつ明確に伝えるべきだと言っています。彼らは、呼び出された関数の戻り値を制御することの重要性について話します。さらに、特定の関数によって返される値が無視された場合、コンパイラーでさえ警告を発行することを学びました。現代のプログラマーによるエラー処理の重要性は受け入れられていると言わなければなりません。 KDPV(ここで撮影)のように、これが面白い事件につながることもあります)。実生活では、私はそのような奇妙な診断メッセージに何度か対処しなければなりませんでした。後者の場合とそのような診断を克服する方法についてお話ししたいと思います。興味のある方は猫の下で大歓迎です。経験豊富なプログラマーは確かに自分自身にとって新しいことを発見することはありませんが、ソフトウェア開発について哲学を学ぶことは間違いありません。
一般的に、私は悲しいニュースがあります。これ以上の写真はありません。Linuxシステムコンソールレベルに移動して、そこに住んでいます。この場合、私たちは喜ぶでしょう。作業するプロジェクトには、かなりよく知られているU-Bootローダーがあります。DENXソフトウェアエンジニアリングがサポートするオープンソースプロジェクト..。したがって、コンソールがあり、システム環境があり、一般的に生活が本格化していることを嬉しく思います。このプロジェクトで作業する場合、原則として、このようなものはありません。連続したメモリ領域、ある場所から別の場所へのバイトの転送、および周辺機器の準備が整うのを待ちます。しかし、ちなみに、この部分はすでに完了しており、ハードウェアの一部に対してかなり機能するブートローダーがあります。アプリケーションプログラマがシステムの起動プロセスに何らかの影響を与えることができる装飾を始めるときが来ました。問題の前兆はありません。この問題はずっと前に解決され、OpenWRTや他の多くの人気のあるプロジェクトで積極的に使用されていますが、あまり知られていません。
. U-Boot . . fw_printenv fw_setenv Linux. . . « ». ? . «fw_printenv», - .
localhost ~ # fw_printenv Cannot open /dev/mtd1: No such file or directory localhost ~ # fw_printenv --help Usage: fw_printenv [OPTIONS]... [VARIABLE]... Print variables from U-Boot environment -h, --help print this help. -v, --version display version -c, --config configuration file, default:/etc/fw_env.config -n, --noheader do not repeat variable name in output -l, --lock lock node, default:/var/lock
. . . « » , . /etc/fw_env.config. . , ( ) U-Boot , . uboot.env , vfat ( FAT-32). . U-Boot , . . Linux. c uboot.env, , , /boot. 11 12 (/dev/mtd1 /dev/mdt2 ) 30 (/boot/uboot.env) .
# VFAT example /boot/uboot.env 0x0000 0x4000
. . .
localhost ~ # fw_printenv Read error on /boot/uboot.env: Success
, . , Linux’ — . , « » — root’. . , ( ) ? ? U-Boot’ «saveenv»? …
localhost ~ # ls -l /boot/uboot.env -rwxr-xr-x 1 root root 8192 Dec 2 13:22 /boot/uboot.env
, . (, ). , ?
localhost ~ # mv /boot/uboot.env /boot/uboot.env.bak localhost ~ # fw_printenv Cannot open /boot/uboot.env: No such file or directory localhost ~ # mv /boot/uboot.env.bak /boot/uboot.env
. . , … , . . , . ? 950 tools/env/fw_env.c:
lseek(fd, blockstart + block_seek, SEEK_SET);
rc = read(fd, buf + processed, readlen);
if (rc == -1) {
fprintf(stderr, "Read error on %s: %s\n",
DEVNAME(dev), strerror(errno));
return -1;
}
if (rc != readlen) {
fprintf(stderr,
"Read error on %s: Attempted to read %zd bytes but got %d\n",
DEVNAME(dev), readlen, rc);
return -1;
}
. read(). . , , read() -1, errno . . ? , … …
, read? , … read- -. read() . . ? , — .
localhost ~ # strace fw_printenv execve("/usr/bin/fw_printenv", ["fw_printenv"], 0x7ebf2400 /* 28 vars */) = 0 brk(NULL) = 0x2118000 uname({sysname="Linux", nodename="localhost", ...}) = 0 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=42265, ...}) = 0 mmap2(NULL, 42265, PROT_READ, MAP_PRIVATE, 3, 0) = 0x76f14000 close(3) = 0 openat(AT_FDCWD, "/lib/libc.so.6", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3 read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\f~\1\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1286448, ...}) = 0 mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x76f12000 mmap2(NULL, 1356160, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x76da1000 mprotect(0x76ed7000, 65536, PROT_NONE) = 0 mmap2(0x76ee7000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x136000) = 0x76ee7000 mmap2(0x76eea000, 8576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x76eea000 close(3) = 0 set_tls(0x76f12ca0) = 0 mprotect(0x76ee7000, 8192, PROT_READ) = 0 mprotect(0x4a9000, 4096, PROT_READ) = 0 mprotect(0x76f1f000, 4096, PROT_READ) = 0 munmap(0x76f14000, 42265) = 0 openat(AT_FDCWD, "/var/lock/fw_printenv.lock", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 flock(3, LOCK_EX) = 0 brk(NULL) = 0x2118000 brk(0x2139000) = 0x2139000 openat(AT_FDCWD, "/etc/fw_env.config", O_RDONLY) = 4 fstat64(4, {st_mode=S_IFREG|0644, st_size=1342, ...}) = 0 read(4, "# Configuration file for fw_(pri"..., 4096) = 1342 read(4, "", 4096) = 0 close(4) = 0 openat(AT_FDCWD, "/boot/uboot.env", O_RDONLY) = 4 fstat64(4, {st_mode=S_IFREG|0755, st_size=8192, ...}) = 0 close(4) = 0 openat(AT_FDCWD, "/boot/uboot.env", O_RDONLY) = 4 _llseek(4, 0, [0], SEEK_SET) = 0 read(4, "n.'\202__INF0__=Ravion-V2 I.MX6 CPU"..., 16384) = 8192 write(2, "Read error on /boot/uboot.env: S"..., 39Read error on /boot/uboot.env: Success ) = 39 close(4) = 0 flock(3, LOCK_UN) = 0 close(3) = 0 exit_group(1) = ? +++ exited with 1 +++ localhost ~ #
Linux. . . , — . -. :
openat(AT_FDCWD, "/boot/uboot.env", O_RDONLY) = 4 _llseek(4, 0, [0], SEEK_SET) = 0 read(4, "n.'\202__INF0__=Ravion-V2 I.MX6 CPU"..., 16384) = 8192 write(2, "Read error on /boot/uboot.env: S"..., 39Read error on /boot/uboot.env: Success ) = 39
16384 (16K), 8192 (8K). . . . , 8192 . . 0, 0x4000 16384. 0x2000
# VFAT example /boot/uboot.env 0x0000 0x2000
, . U-Boot’ . . . . () . — - . , . , . . .
— U-Boot. . , — . ? ( )? — 16 8. — ? , — .
localhost ~ # fw_printenv __INF0__=Ravion-V2 I.MX6 CPU Module BSP package __INF1__=Created: Alex A. Mihaylov AKA MinimumLaw, MinimumLaw@Rambler.Ru […] boot_os=1 localhost ~ #
. fw_setenv .
localhost ~ # fw_setenv boot_os 0; fw_printenv boot_os boot_os=0
? . , . , ?
. , U-Boot, , . . , strace read 8192. ? 8192 -1.
. , — , Das U-Boot . . , . . , . . . .
localhost ~ # fw_printenv --version Compiled with U-Boot 2019.10 localhost ~ #
lseek(fd, blockstart + block_seek, SEEK_SET);
rc = read(fd, buf + processed, readlen);
if (rc != readlen) {
fprintf(stderr, "Read error on %s: %s\n",
DEVNAME(dev), strerror(errno));
return -1;
}
. . . . . , . .
. «uboot.env»
localhost ~ # hexdump -C /boot/uboot.env 00000000 0a 43 62 eb 5f 5f 49 4e 46 30 5f 5f 3d 52 61 76 |.Cb.__INF0__=Rav| 00000010 69 6f 6e 2d 56 32 20 49 2e 4d 58 36 20 43 50 55 |ion-V2 I.MX6 CPU| 00000020 20 4d 6f 64 75 6c 65 20 42 53 50 20 70 61 63 6b | Module BSP pack| 00000030 61 67 65 00 5f 5f 49 4e 46 31 5f 5f 3d 43 72 65 |age.__INF1__=Cre| [...] 00000720 3d 71 70 00 76 65 6e 64 6f 72 3d 72 61 76 69 6f |=qp.vendor=ravio| 00000730 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |n...............| 00000740 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00002000 localhost ~ #
— , , . 1837 (0x7031 – 4) . 4 CRC32, =. . . . ( !) . ?
. . U-Boot . vfat . . OpenWRT . SPI-flash. . . . . , dataflash raw-NAND . .. , . .
. … . . . . , . . , . .
. , … , . : « , . .» , .
P.S.
CodeRushHabrへの招待を再度ありがとう。そして、はい、私は常に何か深刻なことについて書きたいと思っています-コンパイラについて、ハードウェア上で直接安全にプログラミングすることについて。そして、その強さは金曜日の軽い読書にのみ十分です。さて、開始が行われたと仮定しましょう。大きな旅は常に小さな一歩から始まります。