凌云实验室推出的ARM Linux物联网网关开发板IGKBoard(IoT Gateway Kit Board)项目源码
guowenxue
2021-12-30 88700c0fc909f6051241232a0bd7277781619d53
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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
#!/bin/bash
 
PRJ_PATH=`pwd`
PRJ_NAME=`basename ${PRJ_PATH}`
 
# update by top build.sh
BOARD=igkboard
SYSTEM=buildroot
DISTRO=2021.02
SYSNAME=buildroot
 
ROOTFS_DIR=rootfs_${SYSNAME}
 
TAR_PATH=${PRJ_PATH}/../tarball
 
# rootfs configuration
DEBIAN_URL=http://ftp.cn.debian.org/debian/
ARCH=armhf
DEF_USER=lingyun
DEF_PASSWD=12345
DEF_HOSTNAME=${BOARD}
 
APPS_CONF=extra_apps.json
 
set -u
set -e
 
trap 'exit_handler' EXIT
function exit_handler()
{
    rm -f  ${ROOTFS_DIR}/usr/bin/qemu-arm-static
    umount ${ROOTFS_DIR}/{sys,proc,dev/pts,dev} 2>/dev/null || true
}
 
STAGE=0
function msg_banner()
{
    STAGE=`expr $STAGE + 1`
 
    echo ""
    echo "+---------------------------------------------+"
    printf " Stage $STAGE: $1\n"
    echo "+---------------------------------------------+"
    echo ""
}
 
function do_unpack()
{
    if [ -d ${ROOTFS_DIR} ] ; then
        printf "\n\n -- ${ROOTFS_DIR} fetched already, skip it -- \n\n"
        return;
    fi
 
    if [ -s ${TAR_PATH}/${ROOTFS_DIR}.tar.bz2 ]  ; then
        printf "\n\n -- decompress ${ROOTFS_DIR}.tar.bz2 -- \n\n"
        mkdir -p ${ROOTFS_DIR}
        tar -xjf ${TAR_PATH}/${ROOTFS_DIR}.tar.bz2 -C ${ROOTFS_DIR}
    fi
 
    return;
}
 
 
# decompress rootfs packet or debootstrap fetch debian rootfs
function do_fetch()
{
    msg_banner " ${ROOTFS_DIR} do fetch "
 
    # try to decompress packet first.
    do_unpack
 
    # Yocto and buildroot rootfs decompress only
    if [ -d ${ROOTFS_DIR} ] ; then
        return ;
    else
        if [ $SYSTEM != "debian" ] ; then
            echo " ERROR: miss ${SYSTEM}(${DISTRO}) rootfs, exit now. "
            echo ""
            exit;
        fi
    fi
 
    # debootstrap fetch debian rootfs
    export DEBIAN_FRONTEND=noninteractive
    export DEBCONF_NONINTERACTIVE_SEEN=true
    export LC_ALL=C
    export LANGUAGE=C
    export LANG=C
 
    printf "\n\n -- debootstrap fetch start --\n\n"
    echo "debootstrap --arch=${ARCH} --foreign ${DISTRO} ${ROOTFS_DIR} ${DEBIAN_URL}"
    debootstrap --arch=${ARCH} --foreign ${DISTRO} ${ROOTFS_DIR} ${DEBIAN_URL}
 
    chroot ${ROOTFS_DIR} debootstrap/debootstrap --second-stage
    printf "\n\n -- debootstrap config start --\n\n"
 
    chroot ${ROOTFS_DIR} dpkg --configure -a
    printf "\n\n -- debootstrap fetch done -- \n\n"
 
    # Clear the MD5 value to install extra apps
    sed -i -e "s|.*md5apt.*|\t\"md5apt\":\"MD5_Auto_Generate_Here\"|g" $APPS_CONF
 
    cd ${ROOTFS_DIR}
    tar -cjf ../${ROOTFS_DIR}.orig.tar.bz2 *
    cd -
}
 
 
# Install extra apps defined in extra_apps.conf
function do_extra_apt()
{
    if [ ! -f $APPS_CONF ] ; then
        return ;
    fi
 
    extra_apps=$(eval jq -r .extra_debian_apps[] $APPS_CONF )
    md5_file=$(eval jq -r .md5apt $APPS_CONF)
    md5_calc=$(eval echo $extra_apps | md5sum | awk '{print $1}')
 
    if [ $md5_file == $md5_calc ] ; then
        printf "\n\n -- debootstrap apt install already, skip it! --\n\n"
        return ;
    fi
 
    msg_banner " debootstrap apt install "
 
    export DEBIAN_FRONTEND=noninteractive
    export DEBCONF_NONINTERACTIVE_SEEN=true
    export LC_ALL=C
    export LANGUAGE=C
    export LANG=C
 
 
    cp -f /usr/bin/qemu-arm-static ${ROOTFS_DIR}/usr/bin/
    mount -o bind /proc ${ROOTFS_DIR}/proc
    mount -o bind /dev ${ROOTFS_DIR}/dev
    mount -o bind /dev/pts ${ROOTFS_DIR}/dev/pts
    mount -o bind /sys ${ROOTFS_DIR}/sys
 
    chroot ${ROOTFS_DIR} apt update
    chroot ${ROOTFS_DIR} apt install -y ${extra_apps}
    chroot ${ROOTFS_DIR} apt autoremove
 
    umount ${ROOTFS_DIR}/{sys,proc,dev/pts,dev}
 
 
    sed -i -e "s|.*md5apt.*|\t\"md5apt\":\"$md5_calc\"|g" $APPS_CONF
    printf "\n\n -- debootstrap apt install done --\n\n"
 
    # modify root password
    chroot ${ROOTFS_DIR} sh -c "echo root:${DEF_PASSWD} | chpasswd"
 
    # add default user account
    set +e
    grep "$DEF_USER" ${ROOTFS_DIR}/etc/passwd > /dev/null 2>&1
    if [ $? != 0 ] ; then
        printf "\n\n -- setup default user account --\n\n"
        chroot ${ROOTFS_DIR} sh -c "useradd -m -s /bin/bash ${DEF_USER}"
        chroot ${ROOTFS_DIR} sh -c "echo ${DEF_USER}:${DEF_PASSWD} | chpasswd"
        chroot ${ROOTFS_DIR} sh -c "usermod -aG video,audio,sudo ${DEF_USER}"
    fi
    set -e
}
 
function install_file()
{
    if [ $# != 1 ] ; then
        return ;
    fi
 
    # parser the source file and destination install path
    src=`echo $1 | cut -d: -f1`
    dst=${ROOTFS_DIR}/`echo $1 | cut -d: -f2`
 
    echo "install $src => $dst"
 
    mkdir -p ${dst}
 
    # parser to get .tar.gz .tar.bz2 .tar.xz
    fname=`basename ${src}`
    suffix=`echo "${fname#*.}"`
 
    case $suffix in
        tar.gz)
            tar -xzf ${src} -C ${dst}
            ;;
 
        tar.bz2)
            tar -xjf ${src} -C ${dst}
            ;;
 
        tar.xz)
            tar -xJf ${src} -C ${dst}
            ;;
 
        *)
            rm -rf ${dst}/${fname}
            cp -rf ${src} ${dst}
            ;;
 
        esac
}
 
function do_install()
{
    # apt install extra packet for debian rootfs
    if [ $SYSTEM == "debian" ] ; then
        do_extra_apt
    fi
 
    # install common files for all the system
    for row in $( jq -r '.extra_common_files | keys[] as $k | "\($k):\(.[$k])"' $APPS_CONF ) ; do
        install_file $row
    done
 
    # install extra files for custom system
    jq_args=".extra_${SYSTEM}_files | keys[] as \$k | \"\(\$k):\(.[\$k])\""
    for row in $( jq -r "${jq_args}" $APPS_CONF ) ; do
        install_file $row
    done
}
 
function do_modify()
{
    msg_banner " modify rootfs environment"
 
    set +e
 
    # update hostnmae and issue
    echo "Welcome to LingYun IoT Gateway Kit Board GNU/Linux ${SYSTEM}(${DISTRO}) system, default password '$DEF_PASSWD'." > ${ROOTFS_DIR}/etc/issue
    echo $DEF_HOSTNAME > ${ROOTFS_DIR}/etc/hostname
    grep "$BOARD" ${ROOTFS_DIR}/etc/hosts > /dev/null 2>&1
    if [ $? != 0 ] ; then
       echo "127.0.0.1       ${BOARD}" >> ${ROOTFS_DIR}/etc/hosts
    fi
 
    # update dns server
    echo "nameserver 114.114.114.114" > ${ROOTFS_DIR}/etc/resolv.conf
    echo "nameserver 223.5.5.5" >> ${ROOTFS_DIR}/etc/resolv.conf
 
    # update profile
    sed -i "s|PS1='# '|PS1='\\\u@\\\h:\\\w# '|g" ${ROOTFS_DIR}/etc/profile
    sed -i "s|PS1='$ '|PS1='\\\u@\\\h:\\\w$ '|g" ${ROOTFS_DIR}/etc/profile
    sed -i 's|PATH=.*|PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"|g' ${ROOTFS_DIR}/etc/profile
 
    # add ls alias for display with color
    grep "^alias ls=" ${ROOTFS_DIR}/etc/profile > /dev/null 2>&1
    if [ $? != 0 ] ; then
       echo "alias ls='ls --color=auto'" >> ${ROOTFS_DIR}/etc/profile
    fi
 
    # update sudo without passwd for yocto and debian
    if [ $SYSTEM != buildroot ]  ; then
        sed -i "s|^%sudo.*|%sudo   ALL=(ALL:ALL) NOPASSWD:ALL|g" ${ROOTFS_DIR}/etc/sudoers
    fi
 
    # permit root ssh login
    sed -i "s|^#PermitRootLogin.*|PermitRootLogin yes|g" ${ROOTFS_DIR}/etc/ssh/sshd_config
    sed -i "s|^#PasswordAuthentication.*|PasswordAuthentication yes|g" ${ROOTFS_DIR}/etc/ssh/sshd_config
 
    # add vim alias for buildroot and yocto
    if [ $SYSTEM != "debian" ] ; then
        grep "alias vim=" ${ROOTFS_DIR}/etc/profile > /dev/null 2>&1
        if [ $? != 0 ] ; then
            echo "alias vim='vi'" >> ${ROOTFS_DIR}/etc/profile
        fi
    fi
 
    set -e
 
    printf "\n\n -- modify rootfs done --\n\n"
}
 
function do_pack()
{
    if [ -f ${ROOTFS_DIR}.tar.bz2 ] ; then
       msg_banner " rootfs already generate, skip it"
       return ;
   else
       msg_banner " generate rootfs packet "
    fi
 
    cd ${ROOTFS_DIR}
 
    tar -cjf ../${ROOTFS_DIR}.tar.bz2 *
 
    cd ${PRJ_PATH}
 
    printf "\n\n -- generate rootfs packet done --\n\n"
}
 
function do_distclean()
{
    printf "\n\n -- do distclean in $PRJ_NAME --\n\n"
 
    rm -rf driver
    rm -rf $ROOTFS_DIR
 
    exit;
}
 
function do_rootfs()
{
    do_fetch
    do_install
    do_modify
    do_pack
}
 
function do_root()
{
    echo ""
    if [[ $1 == "yes" ]] && [ `id -u` != 0 ] ; then
        echo "ERROR: This action must run as root!"
        echo ""
        exit;
    elif [[ $1 != "yes" ]] && [ `id -u` == 0 ] ; then
        echo "ERROR: This action cannot run as root!"
        echo ""
        exit;
    fi
}
 
function do_usage()
{
    echo ""
    echo "Usage:"
    echo "   $0 [-b] [-c] [-h]"
    echo "       -b: download and build $PRJ_NAME"
    echo "       -c: clean all the source code"
    echo "       -h: show this help message"
    echo ""
    echo " WARNNING: This shell script must run as sudo"
    echo ""
    exit;
}
 
while getopts "bch" OPTNAME
do
    case "${OPTNAME}" in
        "b")
            break;
            ;;
 
        "c")
            do_root "yes"
            do_distclean
            ;;
 
        "*")
            do_usage
            ;;
    esac
done
 
do_root "yes"
do_rootfs