임베디드

u-boot Ethernet 기능 활성화

FoxNux 2019. 12. 25. 14:37

u-boot에 Ethernet 기능이 꺼져 있어, TFTP를 이용한 원격 커널 부팅이 불가능했다.

뻔질나게 SD 카드를 옮기고 복사하면서 개발하는 것은 효율이 너무 낮아 네트웍 기능을 켜 보았다.

 

sun8i-s3-foxnux.dts를 아래와 같이 변경하였다. USB 관련 변경은 무시하자.

diff --git a/arch/arm/dts/sun8i-s3-foxnux.dts b/arch/arm/dts/sun8i-s3-foxnux.dts
index 758c3ffeaf..1f51e305a6 100644
--- a/arch/arm/dts/sun8i-s3-foxnux.dts
+++ b/arch/arm/dts/sun8i-s3-foxnux.dts
@@ -49,6 +49,7 @@
        compatible = "licheepi,licheepi-zero", "allwinner,sun8i-s3";
 
        aliases {
+               ethernet0 = &emac;
                serial0 = &uart0;
                spi0 = &spi0;
        };
@@ -83,6 +84,17 @@
 };
 
 &usbphy {
-       usb0_id_det-gpio = <&pio 5 6 GPIO_ACTIVE_HIGH>;
+       usb0_id_det-gpio = <&pio 2 10 GPIO_ACTIVE_HIGH>;
        status = "okay";
 };
+
+&emac {
+       phy = <&phy0>;
+       phy-mode = "mii";
+       allwinner,use-internal-phy;
+       allwinner,leds-active-low;
+       status = "okay";
+       phy0: ethernet-phy@0 {
+               reg = <1>;
+       };
+};

그리고 해당 dtsi에 칩셋 내부의 이더넷 관련 장치에 대한 설정값을 추가하였다.

diff --git a/arch/arm/dts/sun8i-v3s.dtsi b/arch/arm/dts/sun8i-v3s.dtsi
index 8ab30219d3..c58694d1be 100644
--- a/arch/arm/dts/sun8i-v3s.dtsi
+++ b/arch/arm/dts/sun8i-v3s.dtsi
@@ -96,6 +96,11 @@
                #size-cells = <1>;
                ranges;
 
+                syscon: syscon@01c00000 {
+                        compatible = "allwinner,sun8i-h3-syscon","syscon";
+                        reg = <0x01c00000 0x34>;
+                };
+
                mmc0: mmc@01c0f000 {
                        compatible = "allwinner,sun7i-a20-mmc";
                        reg = <0x01c0f000 0x1000>;
@@ -208,6 +213,17 @@
                        interrupt-controller;
                        #interrupt-cells = <3>;
 
+                        emac_rgmii_pins: emac0@0 {
+                                allwinner,pins = "PD0", "PD1", "PD2", "PD3",
+                                                 "PD4", "PD5", "PD7",
+                                                 "PD8", "PD9", "PD10",
+                                                 "PD12", "PD13", "PD15",
+                                                 "PD16", "PD17";
+                                allwinner,function = "emac";
+                                allwinner,drive = <SUN4I_PINCTRL_40_MA>;
+                                allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
+                        };
+
                        uart0_pins_a: uart0@0 {
                                pins = "PB8", "PB9";
                                function = "uart0";
@@ -289,6 +305,20 @@
                        #size-cells = <0>;
                };
 
+                emac: ethernet@1c30000 {
+                        compatible = "allwinner,sun8i-h3-emac";
+                        reg = <0x01c30000 0x104>, <0x01c00030 0x4>;
+                        reg-names = "emac", "syscon";
+                        interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                        resets = <&ccu RST_BUS_EMAC>, <&ccu RST_BUS_EPHY>;
+                        reset-names = "ahb", "ephy";
+                        clocks = <&ccu CLK_BUS_EMAC>, <&ccu CLK_BUS_EPHY>;
+                        clock-names = "ahb", "ephy";
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+                        status = "disabled";
+                };
+
                gic: interrupt-controller@01c81000 {
                        compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic";
                        reg = <0x01c81000 0x1000>,

 

그리고 "make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig"를 실행하여 u-boot 설정 화면이 나오게 한다.

Device-Drivers -> Network device support -> Allwinner Sun8i Ethernet MAC support를 선택하고 저장한다.

컴파일하고 보드에 설치하고 부팅하면 다음과 같이 네트웍 장치 관련 정보가 보인다.

U-Boot 2017.01-rc2-00079-g2453611c1a-dirty (Dec 25 2019 - 13:46:41 +0900) Allwinner Technology                                              
                                                                                                                                            
CPU:   Allwinner S3/V3s (SUN8I 1681)                                                                                                        
Model: FoxNux One                                                                                                                           
DRAM:  128 MiB                                                                                                                              
MMC:   SUNXI SD/MMC: 0                                                                                                                      
*** Warning - bad CRC, using default environment                                                                                            
                                                                                                                                            
Setting up a 1024x600 lcd console (overscan 0x0)                                                                                            
dotclock: 51000kHz = 51000kHz: (1 * 3MHz * 102) / 6                                                                                         
In:    serial@01c28000                                                                                                                      
Out:   serial@01c28000                                                                                                                      
Err:   serial@01c28000                                                                                                                      
Net:   phy interface0                                                                                                                       
eth0: ethernet@1c30000 

 

개발용 호스트 컴퓨터와의 연결상태를 보기위해 ping을 실행해 보았으나, ipaddr라는 환경 변수가 설정이 안되어 있다고 한다.

로컬 영역의 빈 IP 주소를 하나 임의로 지정하니 잘 된다. DHCP는 안되는것 같다.

정상 동작을 확인했으면 savenv 명령으로 ipaddr 변수를 저장하여 켤때마다 다시설정하는 수고를 없애자.

=> ping 192.168.1.2
*** ERROR: `ipaddr' not set
ping failed; host 192.168.1.2 is not alive

=> setenv ipaddr 192.168.1.200

=> ping 192.168.1.2
Using ethernet@1c30000 device
host 192.168.1.2 is alive

=> saveenv                                                                                                                                  
Saving Environment to MMC...                                                                                                                
Writing to MMC(0)... done

RJ-45잭의 LED는 동작은 하지만 리눅스 커널 드라이버와는 다르게 통신중에만 불이 켜진다. 커널은 통신중에 불이 꺼지는 형태이다.

 

여기까지 정리해서 Github에 commit 하였다. 추후에 TFTP를 이용한 편리한 개발환경 구축 과정에 대한 이야기 해보겠다.

https://github.com/foxnux/u-boot/commit/1a0dc3247c9bfcac8bd90ccd831190f5308e37b0

 

 

전원을 켤때 USB-UART IC에서 전기적 노이즈로 인해 생기는 임의 데이터 때문에 부트로더에서 멈추는 경우가 매우 빈번하다.

이 문제부터 잡아야겠다.

 

업데이트<1>: 하드웨어 문제를 소프트웨어 땜빵으로 해결하는데 충분한 개선이 이루어지지 않았다.

하드웨어 수정이나 좀 큰 변경이 필요한 것으로 판단된다. ㅠㅠ

 

업데이트<2>: 전기 노이즈 문제는 "SPACE" 키를 두번 눌러야 u-boot prompt 모드로 들어갈 수 있도록 변경하여 해결하였다.

비슷한 문제를 해결 할 수 있도록 다른 개발자들이 모두 고생을 해둔 덕에 비교적 쉽게 땜빵이 된것 같다.

diff --git a/configs/foxnux_S3_defconfig b/configs/foxnux_S3_defconfig
index 80765af4d8..f6412eecf9 100644
--- a/configs/foxnux_S3_defconfig
+++ b/configs/foxnux_S3_defconfig
@@ -350,7 +350,12 @@ CONFIG_SYS_PROMPT="=> "
 # Autoboot options
 #
 CONFIG_AUTOBOOT=y
-# CONFIG_AUTOBOOT_KEYED is not set
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_PROMPT="Press SPACE key two times to abort autoboot in %d seconds\n"
+# CONFIG_AUTOBOOT_ENCRYPTION is not set
+CONFIG_AUTOBOOT_DELAY_STR=""
+CONFIG_AUTOBOOT_STOP_STR="  "
+# CONFIG_AUTOBOOT_KEYED_CTRLC is not set

 

이더넷 기능을 활성화하기 위해 수정한 부분과 오토부트를 SPACE키 2번을 눌러야 멈추도록 수정한 부분이 모두 포함된 defconfig파일을 commit하였다.

https://github.com/foxnux/u-boot/commit/bd399a8b199787dd755b3aea26b398d2fd8e7863

 

u-boot 관련된 개발은 거의 다 끝나가는것 같다.

이제 커널과 관련된 개발을 시작해 보아야 겠다.