-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathMakefile
More file actions
404 lines (347 loc) · 12.2 KB
/
Copy pathMakefile
File metadata and controls
404 lines (347 loc) · 12.2 KB
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
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# 当前目录
PWD = $(shell pwd)
BUSYBOX_DIR = ${PWD}/src/busybox
LINUX_DIR= ${PWD}/src/linux
# 主机 arch
HOST_ARCH = $(shell uname -m)
# 编译的线程数
THREADS ?= 32
# 编译时内存限制
MEM_LIMIT ?= 64G
# 默认目标体系结构就是主机体系结构
# 如若想交叉编译,则需要指定
TARGET_ARCH ?= ${HOST_ARCH}
# 待编译的 linux 源码版本
LINUX_VERSION ?= linux-4.9.229
# docker 镜像名
DOCKER_IMAGE = linux-lib-${TARGET_ARCH}-${LINUX_VERSION}:latest
# docker 容器名
DOCKER_CONTAINER = linux-lib-${TARGET_ARCH}-${LINUX_VERSION}
# GCC 依赖库
GCCLIB_PATH = /lib/x86_64-linux-gnu
# 环境检测
## 1. 编译主机必须是 x64 体系结构
ifeq ($(findstring x86_64,$(HOST_ARCH)),)
$(error "The system has detected that your host is not an x64 architecture.");
endif
# 动态变量设置
## 1. 根据目标体系结构判断 linux 的对应目录名
LINUX_ARCH ?=
LINUX_CONSOLE ?=
LINUX_IMAGE ?=
QEMU_MACHINE ?=
GDB_ARCH ?=
### USB 主机控制器
QEMU_USB_HCI ?=
ifeq ("$(TARGET_ARCH)", "x86_64")
LINUX_ARCH = x86_64
LINUX_CONSOLE = ttyS0
LINUX_IMAGE = bzImage
GDB_ARCH = i386:x86-64
QEMU_USB_HCI = nec-usb-xhci
else ifeq ("$(TARGET_ARCH)", "aarch64")
LINUX_ARCH = arm64
LINUX_CONSOLE = ttyAMA0
LINUX_IMAGE = Image
GDB_ARCH = aarch64
QEMU_MACHINE = -machine virt,gic-version=2 -cpu cortex-a53
QEMU_USB_HCI = qemu-xhci
ifeq ("$(LINUX_VERSION)", "linux-2.6.34")
$(error "linux-2.6.34 does not support aarch64!!!");
endif
else
$(error "unkown arch!!!");
endif
## 2. 根据本地体系结构与目标体系结构判断是否需要交叉编译
CROSS_COMPILER_PERFIX ?=
ifneq ("$(HOST_ARCH)", "$(TARGET_ARCH)")
ifeq ("$(LINUX_VERSION)", "linux-3.12")
CROSS_COMPILER_PERFIX = /opt/gcc-linaro-4.9-2016.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
GCCLIB_PATH = /opt/gcc-linaro-4.9-2016.02-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib
else ifeq ("$(LINUX_VERSION)", "linux-4.9.229")
CROSS_COMPILER_PERFIX = /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
GCCLIB_PATH = /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/lib
else
$(error "does not support $(LINUX_VERSION) !!!");
endif
endif
### 待编译的 busybox 源码
BUSYBOX ?=
## 3. 根据待编译linux版本做选择 busybox 版本
ifeq ("$(LINUX_VERSION)", "linux-2.6.34")
BUSYBOX = busybox-1.15.3
else ifeq ("$(LINUX_VERSION)", "linux-3.12")
BUSYBOX = busybox-1.22.0
else ifeq ("$(LINUX_VERSION)", "linux-4.9.229")
BUSYBOX = busybox-1.30.0
else
$(error "does not support $(LINUX_VERSION) !!!");
endif
# debug 提示
$(info 编译信息如下:);
$(info 主机体系结构 = ${HOST_ARCH});
$(info 目标体系结构 = ${TARGET_ARCH});
$(info 编译线程数 = ${THREADS});
$(info 编译时内存限制 = ${MEM_LIMIT});
$(info 编译Linux版本 = ${LINUX_VERSION});
$(info 编译BUSYBOX版本 = ${BUSYBOX});
# docker image
.PHONY += build-image run-image clean-image
# config
.PHONY += defconfig menuconfig fs-defconfig fs-menuconfig
# compile and run
.PHONY += image devel dump all cleanall
# 运行在容器 使用串口
.PHONY += run flush
# 运行在主机 使用串口
.PHONY += drun dflush
# 运行在主机 使用图形化终端
.PHONY += grun gflush
# debug
.PHONY += gdb-start gdb-stop gdb-restart gdb-attch debug
.PHONY += image-in-docker rootfs-in-docker
.PHONY += grun-in-docker run-in-docker
.PHONY += defconfig-in-docker menuconfig-in-docker
.PHONY += fs-defconfig-in-docker fs-menuconfig-in-docker
.PHONY += clean-in-docker distclean-in-docker
.PHONY += gdb-start-in-docker dump-in-docker
defconfig-after-in-docker-x86_64 :
cd ${LINUX_DIR}/${LINUX_VERSION} && \
scripts/config --enable DEBUG_INFO && \
scripts/config --disable USB_OHCI_HCD && \
scripts/config --disable USB_UHCI_HCD && \
scripts/config --disable USB_EHCI_HCD && \
scripts/config --enable USB_XHCI_HCD && \
scripts/config --disable XHCI_HCD_DEBUGGING && \
scripts/config --disable USB_XHCI_HCD_DEBUGGING && \
scripts/config --enable BLK_DEV_RAM && \
scripts/config --set-val BLK_DEV_RAM_COUNT 16 && \
scripts/config --set-val BLK_DEV_RAM_SIZE 65536
defconfig-after-in-docker-aarch64 :
cd ${LINUX_DIR}/${LINUX_VERSION} && \
scripts/config --set-val DRM y && \
scripts/config --set-val VIRTIO y && \
scripts/config --set-val DRM_VIRTIO_GPU y && \
scripts/config --enable DEBUG_INFO && \
scripts/config --disable USB_OHCI_HCD && \
scripts/config --disable USB_UHCI_HCD && \
scripts/config --disable USB_EHCI_HCD && \
scripts/config --enable USB_XHCI_HCD && \
scripts/config --enable XHCI_HCD_DEBUGGING && \
scripts/config --enable USB_XHCI_HCD_DEBUGGING && \
scripts/config --enable BLK_DEV_RAM && \
scripts/config --set-val BLK_DEV_RAM_COUNT 16 && \
scripts/config --set-val BLK_DEV_RAM_SIZE 65536 && \
scripts/config --disable ARM64_UAO
fs-defconfig-after-in-docker-x86_64 :
cd ${BUSYBOX_DIR}/${BUSYBOX}
fs-defconfig-after-in-docker-aarch64 :
cd ${BUSYBOX_DIR}/${BUSYBOX} && \
${BUSYBOX_DIR}/scripts/config --set-str CROSS_COMPILER_PREFIX "${CROSS_COMPILER_PERFIX}"
# 在镜像环境内的操作
defconfig-in-docker :
cd ${LINUX_DIR}/${LINUX_VERSION} && make ARCH=${LINUX_ARCH} defconfig && cd - && \
make defconfig-after-in-docker-${TARGET_ARCH} && \
cd ${LINUX_DIR}/${LINUX_VERSION} && make ARCH=${LINUX_ARCH} localmodconfig && cd -
menuconfig-in-docker :
cd ${LINUX_DIR}/${LINUX_VERSION} && make menuconfig
distclean-in-docker :
cd ${LINUX_DIR}/${LINUX_VERSION} && make distclean
clean-in-docker :
cd ${LINUX_DIR}/${LINUX_VERSION} && make clean
image-in-docker :
cd ${LINUX_DIR}/${LINUX_VERSION} && make ARCH=${LINUX_ARCH} CROSS_COMPILE=${CROSS_COMPILER_PERFIX} ${LINUX_IMAGE} -j$(THREADS)
gdb-start-in-docker :
qemu-system-${TARGET_ARCH} \
-nographic \
${QEMU_MACHINE} \
-smp 4 -m 2G \
-device ${QEMU_USB_HCI} \
-drive file=${PWD}/usbdisk.img,if=none,id=my_usb_disk \
-usb -device usb-storage,drive=my_usb_disk \
-kernel ${LINUX_DIR}/${LINUX_VERSION}/arch/${LINUX_ARCH}/boot/${LINUX_IMAGE} \
-initrd ${BUSYBOX_DIR}/${BUSYBOX}/rootfs.img.gz \
-s -S \
-append "root=/dev/ram console=${LINUX_CONSOLE} init=/linuxrc"
fs-defconfig-in-docker :
cd ${BUSYBOX_DIR}/${BUSYBOX} && make defconfig && \
cd - && make fs-defconfig-after-in-docker-${TARGET_ARCH}
fs-menuconfig-in-docker :
cd ${BUSYBOX_DIR}/${BUSYBOX} && make menuconfig
fs-clean-in-docker :
cd ${BUSYBOX_DIR}/${BUSYBOX} && make clean
rootfs-in-docker :
cd ${BUSYBOX_DIR}/${BUSYBOX} && make -j$(THREADS) && make install && bash ${BUSYBOX_DIR}/scripts/rootfs-${LINUX_ARCH}.sh ${GCCLIB_PATH} ${BUSYBOX}
fs-distclean-in-docker :
cd ${BUSYBOX_DIR}/${BUSYBOX} && make distclean \
&& rm -rf _install/ \
&& rm -rf rootfs.ext3 \
&& rm -rf rootfs.img.gz
dump-in-docker :
objdump -s -d ${LINUX_DIR}/${LINUX_VERSION}/vmlinux > dump.s
# 串口运行
run-in-docker :
qemu-system-${TARGET_ARCH} \
-nographic \
${QEMU_MACHINE} \
-smp 4 -m 2G \
-device ${QEMU_USB_HCI} \
-drive file=${PWD}/usbdisk.img,if=none,id=my_usb_disk \
-usb -device usb-storage,drive=my_usb_disk \
-kernel ${LINUX_DIR}/${LINUX_VERSION}/arch/${LINUX_ARCH}/boot/${LINUX_IMAGE} \
-initrd ${BUSYBOX_DIR}/${BUSYBOX}/rootfs.img.gz \
-append "root=/dev/ram console=${LINUX_CONSOLE} init=/linuxrc"
# 图形化运行
grun-in-docker :
qemu-system-${TARGET_ARCH} \
${QEMU_MACHINE} \
-smp 4 -m 2G \
-device ${QEMU_USB_HCI} \
-drive file=${PWD}/usbdisk.img,if=none,id=my_usb_disk \
-usb -device usb-storage,drive=my_usb_disk \
-device usb-kbd \
-kernel ${LINUX_DIR}/${LINUX_VERSION}/arch/${LINUX_ARCH}/boot/${LINUX_IMAGE} \
-initrd ${BUSYBOX_DIR}/${BUSYBOX}/rootfs.img.gz \
-device virtio-gpu -display gtk,gl=on \
-append "root=/dev/ram console=tty0 init=/linuxrc"
usbdisk-in-docker:
bash scripts/create_usbdisk.sh
gdb-connect-in-docker:
gdb-multiarch ${LINUX_DIR}/${LINUX_VERSION}/vmlinux -q \
-ex "set architecture ${GDB_ARCH}" \
-ex " target remote localhost:1234"
# 在镜像外的操作
build-image :
sudo docker build -t ${DOCKER_IMAGE} Docker/${TARGET_ARCH}/${LINUX_VERSION} --build-arg BUILDKIT_INLINE_CACHE=1
run-image :
sudo docker run \
--privileged \
--volume=${PWD}:/workdir:rw \
-it ${DOCKER_IMAGE} \
/bin/bash
clean-image :
sudo docker rmi ${DOCKER_IMAGE}
run :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} run-in-docker; \
sudo docker rm ${DOCKER_CONTAINER}
stop :
sudo docker stop ${DOCKER_CONTAINER}
drun :
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} run-in-docker;
grun :
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} grun-in-docker;
menuconfig : defconfig
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} menuconfig-in-docker; \
sudo docker rm ${DOCKER_CONTAINER}
defconfig :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} defconfig-in-docker; \
sudo docker rm ${DOCKER_CONTAINER}
fs-defconfig :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} fs-defconfig-in-docker; \
sudo docker rm ${DOCKER_CONTAINER}
fs-menuconfig : fs-defconfig
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} fs-menuconfig-in-docker; \
sudo docker rm ${DOCKER_CONTAINER}
# 这里必须要加 --privileged, 否则挂载文件时会提示无权限。
rootfs :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--privileged \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} rootfs-in-docker; \
sudo docker rm ${DOCKER_CONTAINER}
fs-distclean :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} fs-distclean-in-docker; \
sudo docker rm ${DOCKER_CONTAINER}
clean :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} clean-in-docker ; \
sudo docker rm ${DOCKER_CONTAINER}
fs-clean :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} fs-clean-in-docker ; \
sudo docker rm ${DOCKER_CONTAINER}
image :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
--memory-reservation ${MEM_LIMIT} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} image-in-docker; \
sudo docker rm ${DOCKER_CONTAINER};
usbdisk:
sudo docker run \
--privileged \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
--memory-reservation ${MEM_LIMIT} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} usbdisk-in-docker; \
sudo docker rm ${DOCKER_CONTAINER};
distclean :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} distclean-in-docker; \
sudo docker rm ${DOCKER_CONTAINER}
devel : build-image
dump :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name ${DOCKER_CONTAINER} \
-it ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} dump-in-docker; \
sudo docker rm ${DOCKER_CONTAINER}
all : defconfig fs-defconfig rootfs image run
cleanall : distclean fs-distclean
flush : image run
dflush : image drun
gflush : image grun
fs-flush : fs-distclean fs-defconfig rootfs run
gdb-start :
sudo docker run \
--volume=${PWD}:/workdir:rw \
--name gdb \
-itd ${DOCKER_IMAGE} \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} gdb-start-in-docker
gdb-stop :
sudo docker stop gdb; \
sudo docker rm gdb
gdb-attch :
sudo docker exec -it gdb /bin/bash
gdb-restart : gdb-stop gdb-start
gdb-connect :
sudo docker exec -it gdb \
make TARGET_ARCH=${TARGET_ARCH} LINUX_VERSION=${LINUX_VERSION} gdb-connect-in-docker