<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zhou Jiang</title>
    <description>The latest articles on DEV Community by Zhou Jiang (@zhou_jiang_841481454f6b8c).</description>
    <link>https://dev.to/zhou_jiang_841481454f6b8c</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3837351%2Feff26baa-4c24-407b-abea-cb7733a111bb.png</url>
      <title>DEV Community: Zhou Jiang</title>
      <link>https://dev.to/zhou_jiang_841481454f6b8c</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zhou_jiang_841481454f6b8c"/>
    <language>en</language>
    <item>
      <title>i.MX6ULL Porting Log 04: I Did Not Touch eMMC First — I Loaded My Own U-Boot into RAM</title>
      <dc:creator>Zhou Jiang</dc:creator>
      <pubDate>Sun, 22 Mar 2026 07:45:11 +0000</pubDate>
      <link>https://dev.to/zhou_jiang_841481454f6b8c/imx6ull-porting-log-04-i-did-not-touch-emmc-first-i-loaded-my-own-u-boot-into-ram-19jc</link>
      <guid>https://dev.to/zhou_jiang_841481454f6b8c/imx6ull-porting-log-04-i-did-not-touch-emmc-first-i-loaded-my-own-u-boot-into-ram-19jc</guid>
      <description>&lt;p&gt;Subtitle&lt;/p&gt;

&lt;p&gt;Before changing permanent storage, I first used USB RecoveryMode and RAM Boot to prove that my own bootloader could take control.&lt;/p&gt;

&lt;p&gt;Goal&lt;/p&gt;

&lt;p&gt;In this level, my goal was not to flash eMMC.&lt;/p&gt;

&lt;p&gt;My goal was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build my own u-boot.imx&lt;/li&gt;
&lt;li&gt;enter USB RecoveryMode&lt;/li&gt;
&lt;li&gt;send U-Boot into RAM with uuu&lt;/li&gt;
&lt;li&gt;confirm from the serial console that my U-Boot had taken control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is safer than modifying permanent storage too early.&lt;/p&gt;

&lt;p&gt;Real Starting Point&lt;/p&gt;

&lt;p&gt;The board already had an older boot path from previous work.&lt;/p&gt;

&lt;p&gt;So I did not want to trust the stored boot chain first.&lt;br&gt;
I wanted temporary control before permanent flashing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: I made a small but real mistake first
&lt;/h2&gt;

&lt;p&gt;I first ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;make &lt;span class="nv"&gt;ARCH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arm &lt;span class="nv"&gt;CROSS_COMPILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;arm-linux-gnueabihf- distclean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and got:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make: *** 没有规则可制作目标“distclean”。 停止。
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was not a compiler problem.&lt;br&gt;
I was simply in the wrong directory.&lt;/p&gt;

&lt;p&gt;Then I moved into the real bootloader source tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/imx6ull-porting/bsp/bootloader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Configure and build U-Boot
&lt;/h2&gt;

&lt;p&gt;I applied the board configuration:&lt;/p&gt;

&lt;p&gt;make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig&lt;/p&gt;

&lt;p&gt;The important output was:&lt;/p&gt;

&lt;h1&gt;
  
  
  configuration written to .config
&lt;/h1&gt;

&lt;p&gt;Then I built the image:&lt;/p&gt;

&lt;p&gt;make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j$(nproc)&lt;/p&gt;

&lt;p&gt;The key build evidence was:&lt;/p&gt;

&lt;p&gt;MKIMAGE u-boot.imx&lt;/p&gt;

&lt;p&gt;That means u-boot.imx was really generated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: RecoveryMode was confirmed by USB enumeration
&lt;/h2&gt;

&lt;p&gt;Before the injection, I checked USB devices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsusb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key output was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Bus 001 Device 019: ID 15a2:0080 Freescale Semiconductor, Inc. i.MX 6ULL SystemOnChip in RecoveryMode
Bus 001 Device 020: ID 1a86:7523 QinHeng Electronics CH340 serial converter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This proved that:&lt;/p&gt;

&lt;p&gt;the SoC was in RecoveryMode&lt;br&gt;
the CH340 serial adapter was also present&lt;/p&gt;

&lt;p&gt;At one point I also saw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FATAL: cannot open /dev/ttyUSB0: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the serial node was not always ready immediately.&lt;br&gt;
That is why checking lsusb was important.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Inject U-Boot into RAM
&lt;/h2&gt;

&lt;p&gt;Then I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;uuu &lt;span class="nt"&gt;-b&lt;/span&gt; spl u-boot.imx

The important output was:

SDP: boot &lt;span class="nt"&gt;-f&lt;/span&gt; u-boot.imx
&lt;span class="o"&gt;[=================&lt;/span&gt;100%&lt;span class="o"&gt;=================]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This showed that the host was really sending u-boot.imx to the chip.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: The serial console gave the final proof
&lt;/h2&gt;

&lt;p&gt;After the RAM boot, I opened the serial console and saw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;U-Boot 2016.03 (Mar 22 2026 - 12:20:06 +0800)
Board: I.MX6U ALPHA|MINI
DRAM:  512 MiB
Boot from USB for mfgtools
Use default environment for mfgtools
Run bootcmd_mfg: run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr};
Bad Linux ARM zImage magic!
=&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the strongest evidence of the whole level.&lt;/p&gt;

&lt;p&gt;It proves that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;my U-Boot image is running&lt;/li&gt;
&lt;li&gt;the board is now following the USB mfgtools path&lt;/li&gt;
&lt;li&gt;the bootloader has already taken control&lt;/li&gt;
&lt;li&gt;the next failure point is the Linux image stage&lt;/li&gt;
&lt;li&gt;What Bad Linux ARM zImage magic! really means&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This message looks scary, but it does not mean this level failed.&lt;/p&gt;

&lt;p&gt;For this level, the main goal was to prove:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;my U-Boot can be built&lt;/li&gt;
&lt;li&gt;USB RecoveryMode works&lt;/li&gt;
&lt;li&gt;uuu can inject the image&lt;/li&gt;
&lt;li&gt;the serial console shows my bootloader running&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That already happened.&lt;/p&gt;

&lt;p&gt;So this error means the problem has moved forward to the Linux image stage.&lt;/p&gt;

</description>
      <category>ubuntu</category>
      <category>linux</category>
    </item>
    <item>
      <title>i.MX6ULL Porting Log 02: Project Layout, a Serial Port Trap, and the Current Board Baseline</title>
      <dc:creator>Zhou Jiang</dc:creator>
      <pubDate>Sun, 22 Mar 2026 02:42:50 +0000</pubDate>
      <link>https://dev.to/zhou_jiang_841481454f6b8c/imx6ull-porting-log-02-project-layout-a-serial-port-trap-and-the-current-board-baseline-31b8</link>
      <guid>https://dev.to/zhou_jiang_841481454f6b8c/imx6ull-porting-log-02-project-layout-a-serial-port-trap-and-the-current-board-baseline-31b8</guid>
      <description>&lt;p&gt;The Goal&lt;/p&gt;

&lt;p&gt;Build a clean project structure and capture the current board boot baseline through the serial console.&lt;/p&gt;

&lt;p&gt;The Problem&lt;/p&gt;

&lt;p&gt;At first, this level looked simple:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;create folders&lt;br&gt;
initialize Git&lt;br&gt;
connect the serial cable&lt;br&gt;
save the boot log&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But the real system was not that simple.&lt;/p&gt;

&lt;p&gt;This board is not in confirmed factory-default state.&lt;br&gt;
Its serial output already contains traces from a previous project.&lt;br&gt;
So I could not call this log a factory baseline.&lt;br&gt;
I had to treat it as a current board baseline.&lt;/p&gt;

&lt;p&gt;I also hit a second problem:&lt;br&gt;
my CH340 serial adapter was detected by Linux, but the serial port disappeared immediately.&lt;/p&gt;

&lt;p&gt;The Fix&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Build the project layout
&lt;/h2&gt;

&lt;p&gt;I created a clean working structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/imx6ull-porting/&lt;span class="o"&gt;{&lt;/span&gt;src,build,out,logs,docs&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/imx6ull-porting
git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps source code, build output, final output, logs, and documents separated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Record the board state first
&lt;/h2&gt;

&lt;p&gt;Before trusting the serial log, I wrote down the truth:&lt;/p&gt;

&lt;p&gt;the board is not in confirmed factory-default state&lt;br&gt;
the current boot output contains traces from an older project&lt;br&gt;
this log must be treated as a current board baseline&lt;/p&gt;

&lt;p&gt;This was important because future debugging must compare against the real current state, not an imagined clean state.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Find the serial trap
&lt;/h2&gt;

&lt;p&gt;I checked lsusb and confirmed the CH340 adapter was detected.&lt;/p&gt;

&lt;p&gt;But the kernel log showed the real problem:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ch341-uart converter now attached to ttyUSB0&lt;br&gt;
usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1&lt;br&gt;
ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So the problem was not the cable.&lt;br&gt;
It was brltty, a background accessibility service in Ubuntu.&lt;br&gt;
It hijacked the CH340 device and disconnected it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Remove the conflicting service
&lt;/h2&gt;

&lt;p&gt;I fixed it by removing brltty:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get remove &lt;span class="nt"&gt;--purge&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; brltty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, /dev/ttyUSB0 became stable.&lt;/p&gt;

&lt;p&gt;Step 5: Open the serial console and capture the baseline&lt;/p&gt;

&lt;p&gt;I used picocom and rebooted the board.&lt;/p&gt;

&lt;p&gt;The captured log showed important real facts:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;U-Boot 2016.03&lt;br&gt;
Board: I.MX6U ALPHA|MINI&lt;br&gt;
DRAM: 512 MiB&lt;br&gt;
Net: FEC1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It also showed that the current board still had an old network boot path:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;FEC1 Waiting for PHY auto negotiation to complete......... TIMEOUT !&lt;br&gt;
TFTP from server 169.254.82.125&lt;br&gt;
Filename 'zImage'&lt;br&gt;
ARP Retry count exceeded; starting again&lt;br&gt;
Filename 'imx6ull-alientek-emmc.dtb'&lt;br&gt;
Bad Linux ARM zImage magic!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That means the board is currently trying to boot by TFTP, but the path is not working correctly.&lt;/p&gt;

&lt;p&gt;The Test&lt;/p&gt;

&lt;p&gt;This level passes if:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;the project folders exist&lt;br&gt;
board_state.md exists&lt;br&gt;
current_board_boot_baseline.log exists&lt;br&gt;
the serial console works&lt;br&gt;
the current board state is clearly documented&lt;br&gt;
The Debug Log&lt;br&gt;
&lt;code&gt;Issue 1: The CH340 device was detected, but /dev/ttyUSB0 was unstable&lt;br&gt;
Fix: Found that brltty hijacked the device, then removed it&lt;br&gt;
Issue 2: Normal user access gave Permission denied&lt;br&gt;
Fix: Used sudo picocom first, then prepared to fix group permissions later&lt;br&gt;
Issue 3: The board was not in clean factory state&lt;br&gt;
Fix: Recorded that truth first, and saved the log as a current board baseline instead of a factory baseline&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;This level was not about code.&lt;br&gt;
It was about discipline.&lt;/p&gt;

&lt;p&gt;I learned two important things:&lt;/p&gt;

&lt;p&gt;Always record the real board state before trusting any boot log&lt;br&gt;
When serial devices behave strangely on Linux, check dmesg first&lt;/p&gt;

&lt;p&gt;In low-level work, the real system state is always more important than assumptions.&lt;/p&gt;

</description>
      <category>iot</category>
      <category>linux</category>
      <category>softwaredevelopment</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>i.MX6ULL Porting Log 01: How I Fixed a 404 Error and Set Up the ARM Cross-Compiler</title>
      <dc:creator>Zhou Jiang</dc:creator>
      <pubDate>Sat, 21 Mar 2026 16:46:38 +0000</pubDate>
      <link>https://dev.to/zhou_jiang_841481454f6b8c/imx6ull-porting-log-01-how-i-fixed-a-404-error-and-set-up-the-arm-cross-compiler-3bdn</link>
      <guid>https://dev.to/zhou_jiang_841481454f6b8c/imx6ull-porting-log-01-how-i-fixed-a-404-error-and-set-up-the-arm-cross-compiler-3bdn</guid>
      <description>&lt;p&gt;The Goal&lt;/p&gt;

&lt;p&gt;Set up the ARM cross-compiler for the i.MX6ULL bring-up project.&lt;/p&gt;

&lt;p&gt;This project will later test a more modern Ubuntu 22.04 userland on an old i.MX6ULL BSP flow.&lt;br&gt;
But before that, I first needed a working ARM compiler on my Ubuntu 22.04 host.&lt;/p&gt;

&lt;p&gt;The Problem&lt;/p&gt;

&lt;p&gt;My host machine is x86, but the target board is ARM.&lt;br&gt;
So I need a cross-compiler to build ARM binaries.&lt;/p&gt;

&lt;p&gt;At first, this looked simple.&lt;br&gt;
But the real work started with an old download link and a 404 error.&lt;/p&gt;

&lt;p&gt;The Fix&lt;br&gt;
Step 1: Install the basic packages&lt;/p&gt;

&lt;p&gt;I first installed the common build tools and libraries:&lt;/p&gt;

&lt;p&gt;sudo apt-get update&lt;br&gt;
sudo apt-get install -y make gcc g++ build-essential libncurses5-dev bison flex libssl-dev lzop git wget libusb-1.0-0-dev net-tools&lt;/p&gt;

&lt;p&gt;This step completed normally.&lt;/p&gt;

&lt;p&gt;Step 2: The old Linaro link was dead&lt;/p&gt;

&lt;p&gt;I tried this old toolchain link first:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo wget https://releases.linaro.org/components/toolchain/binaries/8.3-2019.03/arm-linux-gnueabihf/gcc-linaro-8.3.0-2019.03-x86_64_arm-linux-gnueabihf.tar.xz&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The result was:&lt;/p&gt;

&lt;p&gt;404 Not Found&lt;/p&gt;

&lt;p&gt;So the problem was not my command.&lt;br&gt;
The old resource was no longer available.&lt;/p&gt;

&lt;p&gt;Step 3: Download from the ARM official site&lt;/p&gt;

&lt;p&gt;Then I switched to the ARM official download URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;wget https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This worked.&lt;/p&gt;

&lt;p&gt;Step 4: I made a real naming mistake&lt;/p&gt;

&lt;p&gt;After the download, I still used the old gcc-linaro... name in my extract command.&lt;/p&gt;

&lt;p&gt;That failed because the real file name was already changed to gcc-arm....&lt;/p&gt;

&lt;p&gt;So I checked the directory with ls -l, then used the real file name:&lt;/p&gt;

&lt;p&gt;sudo xz -d gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz&lt;br&gt;
sudo tar -xvf gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar&lt;br&gt;
Step 5: The PATH was wrong at first&lt;/p&gt;

&lt;p&gt;I also wrote the wrong path in ~/.bashrc at first.&lt;br&gt;
I used the old gcc-linaro... folder name.&lt;/p&gt;

&lt;p&gt;Because of that, this command failed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;arm-linux-gnueabihf-gcc &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real reason was simple:&lt;/p&gt;

&lt;p&gt;the compiler was extracted&lt;br&gt;
but my PATH pointed to a folder that did not exist&lt;/p&gt;

&lt;p&gt;Then I fixed the PATH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/usr/local/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6: Remove one extra shell noise&lt;/p&gt;

&lt;p&gt;I also saw this message when running source ~/.bashrc:&lt;/p&gt;

&lt;p&gt;/home/zhou/.openclaw/completions/openclaw.bash: No such file or directory&lt;/p&gt;

&lt;p&gt;This was not the main compiler problem, but it added noise.&lt;br&gt;
So I commented it out first and kept the shell clean.&lt;/p&gt;

&lt;p&gt;The Test&lt;/p&gt;

&lt;p&gt;After fixing the PATH, I ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
arm-linux-gnueabihf-gcc &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result was:&lt;/p&gt;

&lt;p&gt;gcc version 8.3.0 (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36))&lt;/p&gt;

&lt;p&gt;That means the cross-compiler was ready.&lt;/p&gt;

&lt;p&gt;The Debug Log&lt;br&gt;
Issue 1: The old Linaro download link returned 404 Not Found&lt;br&gt;
Fix: Switched to the ARM official toolchain download URL&lt;br&gt;
Issue 2: I still used the old gcc-linaro... name in the extract command&lt;br&gt;
Fix: Checked the real file name with ls -l and used gcc-arm...&lt;br&gt;
Issue 3: The PATH in ~/.bashrc pointed to the wrong folder&lt;br&gt;
Fix: Updated the PATH to the real extracted directory&lt;br&gt;
Issue 4: One unrelated shell completion file was missing&lt;br&gt;
Fix: Commented it out to reduce shell noise&lt;br&gt;
What I Learned&lt;/p&gt;

&lt;p&gt;This level was not only about installing a compiler.&lt;/p&gt;

&lt;p&gt;It taught me one important lesson:&lt;/p&gt;

&lt;p&gt;In low-level work, a wrong path name can stop the whole chain.&lt;/p&gt;

&lt;p&gt;Sometimes the big problem is not the theory.&lt;br&gt;
It is just that one real thing in the system does not match the real state on the machine.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>linux</category>
      <category>tutorial</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
