-
Notifications
You must be signed in to change notification settings - Fork 1
/
build-riscv32-linux-musl-elf.sh
executable file
·237 lines (198 loc) · 5.54 KB
/
build-riscv32-linux-musl-elf.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# build-riscv32-linux-musl-elf.sh -- build really simple linux for RISC-V
#
# (C) Copyright 2022-2024, Greg Ungerer ([email protected])
#
# This script carries out a simple build of a RISC-V based (32-bit) user
# space and linux for use with the standard qemu emulated machine.
#
# This is designed to be as absolutely simple and minimal as possible.
# Only the first stage gcc is built (that is all we really need) and
# only the busybox package to provide a very basic user space.
#
# The build starts by building binutils and a first pass minimal gcc,
# then builds musl, busybox and finally a kernel. The resulting kernel
# can be run using qemu:
#
# qemu-system-riscv32 \
# -nographic \
# -machine virt \
# -bios opensbi/build/platform/generic/firmware/fw_jump.elf \
# -kernel linux-6.11/arch/riscv/boot/Image
#
CPU=riscv
TARGET=riscv32-linux
FLAVOR=riscv32-elf
BOARD=qemu
BINUTILS_VERSION=2.43
GCC_VERSION=14.2.0
MUSL_VERSION=1.2.5
BUSYBOX_VERSION=1.36.1
LINUX_VERSION=6.11
BINUTILS_URL=https://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.xz
GCC_URL=https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/gcc-${GCC_VERSION}.tar.xz
MUSL_URL=https://musl.libc.org/releases/musl-${MUSL_VERSION}.tar.gz
LINUX_URL=https://www.kernel.org/pub/linux/kernel/v6.x/linux-${LINUX_VERSION}.tar.xz
BUSYBOX_URL=https://busybox.net/downloads/busybox-${BUSYBOX_VERSION}.tar.bz2
OPENSBI_URL=https:/riscv-software-src/opensbi.git
ROOTDIR=$(pwd)
TOOLCHAIN=${ROOTDIR}/toolchain
ROOTFS=${ROOTDIR}/rootfs
NCPU=$(grep -c processor /proc/cpuinfo 2> /dev/null)
[ -z "$NCPU" ] && NCPU=1
PATH=${TOOLCHAIN}/bin:${PATH}
fetch_file()
{
URL=$1
PACKAGE=$(basename ${URL})
mkdir -p downloads
if [ ! -f downloads/${PACKAGE} ]
then
echo "BUILD: fetching ${PACKAGE}"
cd downloads
wget ${URL}
cd ../
fi
}
build_binutils()
{
echo "BUILD: building binutils-${BINUTILS_VERSION}"
fetch_file ${BINUTILS_URL}
tar xvJf downloads/binutils-${BINUTILS_VERSION}.tar.xz
cd binutils-${BINUTILS_VERSION}
./configure --target=${TARGET} --prefix=${TOOLCHAIN}
make -j${NCPU} || exit 1
make install || exit 1
cd ../
}
build_gcc()
{
echo "BUILD: building gcc-${GCC_VERSION}"
fetch_file ${GCC_URL}
tar xvJf downloads/gcc-${GCC_VERSION}.tar.xz
cd gcc-${GCC_VERSION}
contrib/download_prerequisites
mkdir ${TARGET}
cd ${TARGET}
../configure --target=${TARGET} \
--prefix=${TOOLCHAIN} \
--enable-multilib \
--disable-shared \
--disable-libssp \
--disable-threads \
--disable-libmudflap \
--disable-libgomp \
--disable-libatomic \
--disable-libsanitizer \
--disable-libquadmath \
--disable-libmpx \
--without-headers \
--with-system-zlib \
--enable-languages=c
make -j${NCPU} || exit 1
make install || exit 1
cd ../..
}
build_linux_headers()
{
echo "BUILD: building linux-${LINUX_VERSION} headers"
fetch_file ${LINUX_URL}
tar xvJf downloads/linux-${LINUX_VERSION}.tar.xz
cd linux-${LINUX_VERSION}
make ARCH=${CPU} rv32_defconfig
make ARCH=${CPU} headers_install || exit 1
cp -a usr/include ${TOOLCHAIN}/${TARGET}/
cd ../
}
build_musl()
{
echo "BUILD: building musl-${MUSL_VERSION}"
fetch_file ${MUSL_URL}
tar xvzf downloads/musl-${MUSL_VERSION}.tar.gz
cd musl-${MUSL_VERSION}
./configure ARCH=${ARCH} CROSS_COMPILE=${TARGET}- --prefix=${TOOLCHAIN}/${TARGET}
make -j${NCPU} || exit 1
make install || exit 1
cd ../
}
build_busybox()
{
echo "BUILD: building busybox-${BUSYBOX_VERSION}"
fetch_file ${BUSYBOX_URL}
tar xvjf downloads/busybox-${BUSYBOX_VERSION}.tar.bz2
cp configs/busybox-${BUSYBOX_VERSION}.config busybox-${BUSYBOX_VERSION}/.config
cd busybox-${BUSYBOX_VERSION}
make oldconfig
make -j${NCPU} CROSS_COMPILE=${TARGET}- CONFIG_PREFIX=${ROOTFS} install
cd ../
}
build_finalize_rootfs()
{
echo "BUILD: finalizing rootfs"
mkdir -p ${ROOTFS}/etc
mkdir -p ${ROOTFS}/lib
mkdir -p ${ROOTFS}/proc
mkdir -p ${ROOTFS}/sys
cp musl-${MUSL_VERSION}/lib/libc.so ${ROOTFS}/lib/
ln -sf /lib/libc.so ${ROOTFS}/lib/ld-linux-riscv32-ilp32d.so.1
echo "::sysinit:/etc/rc" > ${ROOTFS}/etc/inittab
echo "::respawn:-/bin/sh" >> ${ROOTFS}/etc/inittab
echo "#!/bin/sh" > ${ROOTFS}/etc/rc
echo "mount -t proc proc /proc" >> ${ROOTFS}/etc/rc
echo "mount -t sysfs sys /sys" >> ${ROOTFS}/etc/rc
echo "echo -e \"\\nSimple Linux\\n\\n\"" >> ${ROOTFS}/etc/rc
chmod 755 ${ROOTFS}/etc/rc
ln -sf /sbin/init ${ROOTFS}/init
}
build_opensbi()
{
echo "BUILD: building opensbi firmware"
git clone -b v1.4 ${OPENSBI_URL}
cd opensbi
make -j${NCPU} PLATFORM=generic CROSS_COMPILE=${TARGET}- || exit 1
cd ../
}
build_linux()
{
echo "BUILD: building linux-${LINUX_VERSION}"
cd linux-${LINUX_VERSION}
make ARCH=${CPU} CROSS_COMPILE=${TARGET}- rv32_defconfig
sed -i "s/# CONFIG_BLK_DEV_INITRD is not set/CONFIG_BLK_DEV_INITRD=y/" .config
sed -i "/CONFIG_INITRAMFS_SOURCE=/d" .config
echo "CONFIG_INITRAMFS_SOURCE=\"${ROOTFS} ${ROOTDIR}/configs/rootfs.dev\"" >> .config
echo "CONFIG_INITRAMFS_COMPRESSION_GZIP=y" >> .config
make ARCH=${CPU} CROSS_COMPILE=${TARGET}- olddefconfig < /dev/null
make -j${NCPU} ARCH=${CPU} CROSS_COMPILE=${TARGET}- || exit 1
cd ../
}
#
# Do the real work.
#
if [ "$1" = "clean" ]
then
rm -rf binutils-${BINUTILS_VERSION}
rm -rf gcc-${GCC_VERSION}
rm -rf linux-${LINUX_VERSION}
rm -rf musl-${MUSL_VERSION}
rm -rf busybox-${BUSYBOX_VERSION}
rm -rf opensbi
rm -rf ${TOOLCHAIN}
rm -rf ${ROOTFS}
exit 0
fi
if [ "$#" != 0 ]
then
echo "usage: build-riscv32-linux-musl-elf.sh [clean]"
exit 1
fi
build_binutils
build_gcc
build_linux_headers
build_musl
build_busybox
build_finalize_rootfs
build_opensbi
build_linux
exit 0