diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml
index a18d9628..43210022 100644
--- a/.github/workflows/image.yml
+++ b/.github/workflows/image.yml
@@ -8,6 +8,7 @@ env:
   SIGMASTAR: ssc30kd ssc30kq ssc325 ssc333 ssc335 ssc335de ssc337 ssc337de ssc338q ssc377 ssc377d ssc377de ssc378de
   INGENIC: t10 t10l t20 t20l t20x t21n t30a t30a1 t30l t30n t30x t31a t31al t31l t31lc t31n t31x
   ALLWINNER: v851s
+  TAG_NAME: image
 
 jobs:
   toolchain:
@@ -20,9 +21,9 @@ jobs:
             create() {
               uboot=u-boot-$1-nor.bin
               firmware=openipc.$2-nor-$3.tgz
-              release=images/openipc-$1-nor-$3.bin
+              release=image/openipc-$1-nor-$3.bin
 
-              mkdir -p images output
+              mkdir -p image output
               if ! wget -nv $link/$uboot -O output/$1.bin; then
                 echo -e "Download failed: $link/$uboot\n"
                 return 0
@@ -56,6 +57,6 @@ jobs:
       - name: Upload
         uses: softprops/action-gh-release@v2
         with:
-          tag_name: images
+          tag_name: ${{env.TAG_NAME}}
           make_latest: false
-          files: images/*.bin
+          files: image/*.bin
diff --git a/.github/workflows/toolchain.yml b/.github/workflows/toolchain.yml
index 3a952242..155312b8 100644
--- a/.github/workflows/toolchain.yml
+++ b/.github/workflows/toolchain.yml
@@ -3,7 +3,7 @@ on:
   workflow_dispatch:
 
 env:
-  TAG_NAME: latest
+  TAG_NAME: toolchain
 
 jobs:
   toolchain:
@@ -26,9 +26,6 @@ jobs:
           # Ingenic [T31]
           - {"platform": "t31"}
 
-          # Ingenic [T31] with GLIBC
-          - {"platform": "t31glibc"}
-
           # Ingenic [T40]
           - {"platform": "t40"}
 
@@ -84,11 +81,9 @@ jobs:
           URL=https://github.com/${GITHUB_REPOSITORY}/releases/download/${TAG_NAME}/${GCC}
           echo ${URL}
           if ! wget -q --spider ${URL}; then
-            sed -i "/BR2_TOOLCHAIN_EXTERNAL.*/d" ${CONFIG}
             echo BR2_PACKAGE_HOST_GDB=y >> ${CONFIG}
             echo BR2_PACKAGE_AWS_WEBRTC=y >> ${CONFIG}
-            make BOARD=${CONFIG} br-source
-            make BOARD=${CONFIG} br-sdk
+            make BOARD=${CONFIG} toolchain
             SDK=$(find output/images -name *_sdk-buildroot.tar.gz)
             mv ${SDK} ${GCC}
             echo GCC=${GCC} >> ${GITHUB_ENV}
@@ -98,4 +93,5 @@ jobs:
         uses: softprops/action-gh-release@v2
         with:
           tag_name: ${{env.TAG_NAME}}
+          make_latest: false
           files: ${{env.GCC}}
diff --git a/Makefile b/Makefile
index 556776b0..f6919b95 100644
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,7 @@ BR_VER = 2024.02.6
 BR_MAKE = $(MAKE) -C $(TARGET)/buildroot-$(BR_VER) BR2_EXTERNAL=$(PWD)/general O=$(TARGET)
 BR_LINK = https://github.com/buildroot/buildroot/archive
 BR_FILE = /tmp/buildroot-$(BR_VER).tar.gz
+BR_CONF = $(TARGET)/openipc_defconfig
 TARGET ?= $(PWD)/output
 
 CONFIG = $(error variable BOARD not defined)
@@ -29,8 +30,8 @@ br-%: defconfig
 
 defconfig: prepare
 	@echo --- $(or $(CONFIG),$(error variable BOARD not found))
-	@cat $(CONFIG) $(PWD)/general/openipc.fragment > $(TARGET)/openipc_defconfig
-	@$(BR_MAKE) BR2_DEFCONFIG=$(TARGET)/openipc_defconfig defconfig
+	@cat $(CONFIG) $(PWD)/general/openipc.fragment > $(BR_CONF)
+	@$(BR_MAKE) BR2_DEFCONFIG=$(BR_CONF) defconfig
 
 prepare:
 	@if test ! -e $(TARGET)/buildroot-$(BR_VER); then \
@@ -53,7 +54,7 @@ package:
 	@find $(PWD)/general/package/* -maxdepth 0 -type d -printf "br-%f\n" | grep -v patch
 
 toolname:
-	@$(PWD)/general/scripts/show_toolchains.sh $(CONFIG)
+	@echo br-sdk-$(BR2_OPENIPC_SOC_VENDOR)-$(BR2_OPENIPC_SOC_FAMILY)
 
 clean:
 	@rm -rf $(TARGET)/build $(TARGET)/images $(TARGET)/per-package $(TARGET)/target
@@ -68,6 +69,13 @@ deps:
 timer:
 	@echo - Build time: $(shell date -d @$(shell expr $(shell date +%s) - $(TIMER)) -u +%M:%S)
 
+toolchain: defconfig
+ifeq ($(BR2_TOOLCHAIN_EXTERNAL),y)
+	@$(MAKE) -f $(PWD)/general/toolchain.mk BR_CONF=$(BR_CONF) CONFIG=$(PWD)/$(CONFIG)
+	@$(BR_MAKE) BR2_DEFCONFIG=$(BR_CONF) defconfig
+endif
+	@$(BR_MAKE) sdk
+
 repack:
 ifeq ($(BR2_TARGET_ROOTFS_SQUASHFS),y)
 ifeq ($(BR2_OPENIPC_FLASH_SIZE),"8")
diff --git a/br-ext-chip-grainmedia/configs/gm8135_lite_defconfig b/br-ext-chip-grainmedia/configs/gm8135_lite_defconfig
index 39026749..05baf642 100644
--- a/br-ext-chip-grainmedia/configs/gm8135_lite_defconfig
+++ b/br-ext-chip-grainmedia/configs/gm8135_lite_defconfig
@@ -5,7 +5,6 @@ BR2_arm=y
 BR2_TOOLCHAIN_EXTERNAL=y
 BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
 BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
-BR2_TOOLCHAIN_EXTERNAL_UCLIBC=y
 BR2_TOOLCHAIN_EXTERNAL_URL="https://github.com/openipc/firmware/releases/download/$(OPENIPC_TOOLCHAIN).tgz"
 BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="arm-openipc-linux-uclibcgnueabi"
 BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_3=y
diff --git a/br-ext-chip-grainmedia/configs/gm8136_lite_defconfig b/br-ext-chip-grainmedia/configs/gm8136_lite_defconfig
index 03e12163..4752a8fa 100644
--- a/br-ext-chip-grainmedia/configs/gm8136_lite_defconfig
+++ b/br-ext-chip-grainmedia/configs/gm8136_lite_defconfig
@@ -5,7 +5,6 @@ BR2_arm=y
 BR2_TOOLCHAIN_EXTERNAL=y
 BR2_TOOLCHAIN_EXTERNAL_CUSTOM=y
 BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
-BR2_TOOLCHAIN_EXTERNAL_UCLIBC=y
 BR2_TOOLCHAIN_EXTERNAL_URL="https://github.com/openipc/firmware/releases/download/$(OPENIPC_TOOLCHAIN).tgz"
 BR2_TOOLCHAIN_EXTERNAL_CUSTOM_PREFIX="arm-openipc-linux-uclibcgnueabi"
 BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_3=y
diff --git a/general/external.mk b/general/external.mk
index dc9f00fd..0168c560 100644
--- a/general/external.mk
+++ b/general/external.mk
@@ -7,7 +7,7 @@ export OPENIPC_MAJESTIC := $(call qstrip,$(BR2_OPENIPC_MAJESTIC))
 export WGET := wget --show-progress --passive-ftp -nd -t5 -T10
 
 EXTERNAL_VENDOR := $(BR2_EXTERNAL)/../br-ext-chip-$(OPENIPC_SOC_VENDOR)
-OPENIPC_TOOLCHAIN := latest/$(shell $(BR2_EXTERNAL)/scripts/show_toolchains.sh $(BR2_DEFCONFIG))
 OPENIPC_KERNEL := $(OPENIPC_SOC_VENDOR)-$(OPENIPC_SOC_FAMILY)
+OPENIPC_TOOLCHAIN := toolchain/br-sdk-$(OPENIPC_KERNEL)
 
 include $(sort $(wildcard $(BR2_EXTERNAL)/package/*/*.mk))
diff --git a/general/scripts/show_toolchains.sh b/general/scripts/show_toolchains.sh
deleted file mode 100755
index aa23949c..00000000
--- a/general/scripts/show_toolchains.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-if [ -z "$1" ]; then
-	echo "Configuration file missing"
-	exit 0
-fi
-
-LIST="arm11.+=y|cortex.+=y|mips_xburst=y"
-SOC=$(grep -E "${LIST}" "$1" | sed -rn "s/BR2_(.*)=y/\1/p")
-THUMB=$(grep -q "THUMB2=y" "$1" && echo _thumb2)
-FLOAT=$(grep -qE "VFPV3=y|VFPV4=y" "$1" && ! grep -q "ARM_EABI=y" "$1" && echo _hf)
-LINUX=$(grep -oP "HEADERS.+\K\d+.\d+" "$1")
-
-if grep -q "MUSL=y" "$1"; then
-	LIB=musl
-elif grep -q "UCLIBC=y" "$1"; then
-	LIB=uclibc
-fi
-
-echo "${SOC:-arm926t}${THUMB}${FLOAT}-gcc13-${LIB:-glibc}-${LINUX}"
diff --git a/general/toolchain.mk b/general/toolchain.mk
new file mode 100644
index 00000000..ffdbd776
--- /dev/null
+++ b/general/toolchain.mk
@@ -0,0 +1,36 @@
+include $(CONFIG)
+
+all:
+	@echo -e "\n# SDK" >> $(BR_CONF)
+	@echo "BR2_TOOLCHAIN_BUILDROOT=y" >> $(BR_CONF)
+	@echo "BR2_TOOLCHAIN_BUILDROOT_VENDOR=\"openipc\"" >> $(BR_CONF)
+ifeq ($(BR2_TOOLCHAIN_EXTERNAL_CUSTOM_MUSL),y)
+	@echo "BR2_TOOLCHAIN_BUILDROOT_MUSL=y" >> $(BR_CONF)
+else ifeq ($(BR2_TOOLCHAIN_EXTERNAL_CUSTOM_GLIBC),y)
+	@echo "BR2_TOOLCHAIN_BUILDROOT_GLIBC=y" >> $(BR_CONF)
+else
+	@echo "BR2_TOOLCHAIN_BUILDROOT_UCLIBC=y" >> $(BR_CONF)
+endif
+ifeq ($(BR2_TOOLCHAIN_EXTERNAL_CXX),y)
+	@echo "BR2_TOOLCHAIN_BUILDROOT_CXX=y" >> $(BR_CONF)
+endif
+ifeq ($(BR2_TOOLCHAIN_EXTERNAL_HEADERS_5_10),y)
+	@echo "BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_5_10=y" >> $(BR_CONF)
+else ifeq ($(BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_19),y)
+	@echo "BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_19=y" >> $(BR_CONF)
+else ifeq ($(BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_9),y)
+	@echo "BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_9=y" >> $(BR_CONF)
+else ifeq ($(BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_4),y)
+	@echo "BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_4=y" >> $(BR_CONF)
+else ifeq ($(BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_18),y)
+	@echo "BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_18=y" >> $(BR_CONF)
+else ifeq ($(BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_10),y)
+	@echo "BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_10=y" >> $(BR_CONF)
+else ifeq ($(BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_4),y)
+	@echo "BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_4=y" >> $(BR_CONF)
+else ifeq ($(BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_3),y)
+	@echo "BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_3=y" >> $(BR_CONF)
+else ifeq ($(BR2_TOOLCHAIN_EXTERNAL_HEADERS_3_0),y)
+	@echo "BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_3_0=y" >> $(BR_CONF)
+endif
+	@echo "BR2_GCC_VERSION_13_X=y" >> $(BR_CONF)