网站搭建环境h5说 网站
- 作者: 五速梦信息网
- 时间: 2026年04月20日 08:14
当前位置: 首页 > news >正文
网站搭建环境,h5说 网站,青岛黄岛网站建设公司电话,seo体系百科author: hjjdebug date: 2025年 01月 09日 星期四 15:56:15 CST description: ubuntu20下编译linux1.0 (part1) 该博客记录了新gcc编译旧代码可能碰到的问题和解决办法, 可留作参考 操作环境: ubuntu20 \( gcc --version gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 \) as –vers… author: hjjdebug date: 2025年 01月 09日 星期四 15:56:15 CST description: ubuntu20下编译linux1.0 (part1) 该博客记录了新gcc编译旧代码可能碰到的问题和解决办法, 可留作参考 操作环境: ubuntu20 \( gcc --version gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 \) as –version GNU 汇编器 (GNU Binutils for Ubuntu) 2.34 $ ld –version GNU ld (GNU Binutils for Ubuntu) 2.34 文章目录 1. 下载源码:2. 根据readme, 将代码解压到/usr/src/linux 下3 解决 dep 依赖问题4 生成内核文件,解决一系列编译连接问题5 最后的问题 tools/zSystem 已经生成后, 内核压缩问题6 小结 操作过程: 1. 下载源码: https://www.kernel.org/pub/linux/kernel/v1.0/linux-1.0.tar.gz
- 根据readme, 将代码解压到/usr/src/linux 下 先建立两个链接 cd /usr/include mv linux linux_orig mv asm asm_orig ln -s /usr/src/linux/include/linux . ln -s /usr/src/linux/include/asm .然后进行编译 make config //一路回车全给默认 make dep make 说起来就3步make, 但是第二步make dep 就不那么顺利了. 3 解决 dep 依赖问题 \( make dep make[2]: 进入目录“/usr/src/linux/drivers/char” gcc -D__KERNEL__ -E -M tty_io.c console.c keyboard.c serial.c tty_ioctl.c pty.c vt.c mem.c defkeymap.c psaux.c mouse.c .depend serial.c:538:8: error: macro names must be identifiers 538 | #ifdef 0 | ^ make[2]: *** [Makefile:78dep] 错误 1 make[2]: 离开目录“/usr/src/linux/drivers/char” make[1]: *** [Makefile:39dep] 错误 2 make[1]: 离开目录“/usr/src/linux/drivers” make: *** [Makefile:253dep] 错误 2 错误位置: drivers/char/serial.c 文件第538行有#ifdef 0, 使的dep构建不能通过 错误原因: #ifdef 0 在新gcc 中已经不合法 解决办法: 改为 #if 0 顺便把./fs/buffer.c:#ifdef 0 也改掉 In file included from /usr/include/x86_64-linux-gnu/asm/socket.h:1, from /usr/include/x86_64-linux-gnu/bits/socket.h:354, from /usr/include/x86_64-linux-gnu/sys/socket.h:33, from /usr/include/netinet/in.h:23, from plip.c:87: /usr/include/asm-generic/socket.h:5:10: fatal error: linux/posix_types.h: 没有那个文件或目录 5 | #include linux/posix_types.h | ^~~~~~~~~~~~~~~~~~~~~ compilation terminated. make[3]: *** [Makefile:143dep] 错误 1 make[3]: 离开目录“/usr/src/linux/drivers/net” make[2]: *** [Makefile:39dep] 错误 2 make[2]: 离开目录“/usr/src/linux/drivers” make[1]: *** [Makefile:253depend] 错误 2 make[1]: 离开目录“/usr/src/linux” make: *** [Makefile:262…depend] 错误 2 错误位置: drivers/net/plip.c:87调用/usr/include/netinet/in.h, 最后缺失文件linux/posix_types.h 错误原因: 它打开了新版本的netinet/in.h 文件,再访问旧版本linux目录,因而找不到指定文件 解决办法: 把新版本的posix_types.h 拷贝进linux 目录, 令依赖通过 cp /usr/include/linux_orig/posix_types.h /usr/include/linux 解决了上面2个错误 make dep 就通过了,下面开始make 4 生成内核文件,解决一系列编译连接问题 \) make gcc -DKERNEL -E -traditional boot/head.S -o boot/head.s as -c -o boot/head.o boot/head.s boot/head.S: Assembler messages: boot/head.S:64: 错误 invalid instruction suffix for push boot/head.S:65: 错误 invalid instruction suffix for popf’ boot/head.S:99: 错误 invalid instruction suffix for pushf’ … 错误位置: boot/head.S 中有一堆编译错误. 错误原因现在的as 默认是64位的,需要改成32位编译 解决办法打开Makefile , 将 AS as 改为 AS as –32 gcc -DKERNEL -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -m486 -c -o init/main.o init/main.c gcc: error: unrecognized command line option ‘-m486’ 错误原因新gcc已经没有该选项了, 但应该加-m32标志表示编译的是32位程序否则默认是64位程序 解决办法打开Makefile , 注释掉-m486标志 但应该添加-m32标志 表示编译的程序是32位的. #CFLAGS : \((CFLAGS) -m486 HOSTCC gcc -m32 CC gcc -D__KERNEL__ -m32 In file included from init/main.c:10: /usr/include/asm/io.h: In function ‘__inbc’: /usr/include/asm/io.h:78:1: error: impossible constraint in ‘asm’ 78 | __IN(b,“b”,“0” (0)) | ^~~~ make: *** [Makefile:149init/main.o] 错误 1 错误位置: 在init/main.c第10行,包含asm/io.h, 此文件的第78行在宏展开过程中有不正确的asm写法 错误原因: 这个问题比较复杂, 是因为新版gcc 中, 已经不使用extern inline, 代之以inline 解决办法: 把 extern inline 中的extern 去掉. (先处理一下这个io.h文件看看效果 该错误解决后又出现如下错误. In file included from /usr/include/linux/sched.h:77, from init/main.c:15: /usr/include/linux/mm.h: In function ‘get_free_page’: /usr/include/linux/mm.h:98:3: error: ‘asm’ operand has impossible constraints 98 | asm volatile(“rep ; stosl” | ^~~~~~~ make: *** [Makefile:149init/main.o] 错误 1 错误位置: 在init/main.c第15行,包含linux/sched.h, 此文件的第77行包含linux/mm.h 在其第98行, get_free_page 函数中 有不正确的asm写法 错误原因: 新版gcc 内嵌汇编 已经不再需要在第3部分添加变化寄存器说明. 解决办法去掉变换寄存器部分 原代码 asm volatile(“rep ; stosl” : /* no outputs / :“a” (0),“c” (1024),“D” (page) :“di”,“cx”); 修改后代码: asm volatile(“rep ; stosl” : / no outputs */ :“a” (0),“c” (1024),“D” (page) ; 编译通过继续. In file included from init/main.c:19: /usr/include/linux/string.h: In function ‘strcpy’: /usr/include/linux/string.h:24:1: error: ‘asm’ operand has impossible constraints 24 | asm(“cld\n” | ^~~~~~~ make: *** [Makefile:149init/main.o] 错误 1 错误位置: init/main.c:19 -linux/string.h:24, strcpy函数中 错误原因: asm 书写不合法, 有不可能约束. 解决办法: 要去掉变换寄存器约束, 跟上一条处理方法一样. 内嵌汇编由于新版的gcc 已经改为不需要第3部分变换寄存器说明所以这一改动会大量修改内核代码 你可以通过在.h, .c 中查找ax 寄存器或者cx寄存器来找到它们并修改 ./include/linux/mm.h ./include/linux/sched.h ./include/linux/string.h ./include/linux/delay.h ./include/asm/segment.h ./include/asm/system.h 以下.c文件可能需要修改 \) find . -name “.c”|xargs grep -l -w ax ./mm/memory.c ./kernel/traps.c ./fs/minix/bitmap.c ./fs/proc/base.c ./fs/isofs/namei.c ./fs/ext2/balloc.c ./fs/ext2/ialloc.c ./fs/ext/namei.c ./net/inet/loopback.c ./net/inet/ip.c ./net/inet/tcp.c ./net/inet/udp.c ./init/main.c ./drivers/FPU-emu/fpu_trig.c ./drivers/net/3c501.c ./drivers/sound/audio.c ./drivers/char/console.c 打开文件查看,需要改就改 改不完全也没关系,让编译器去检查. 纯手工活,批量改也是手工活没有统一规律,谁对编辑器熟悉改的就快一点,例如emacs 这样就解决了内嵌汇编语法问题. sched.c:41:25: error: conflicting type qualifiers for ‘xtime’ 41 | volatile struct timeval xtime; / The current time */ | ^~~~~ In file included from sched.c:16: /usr/include/linux/sched.h:308:23: note: previous declaration of ‘xtime’ was here 308 | extern struct timeval xtime; | ^~~~~ 错误位置: sched.c:41 行 声明了 volatile struct timeval xtime,与sched.c:16行包含了 linux/sched.h:308行中的声明 extern struct timeval xtime 相冲突 错误原因: 两处变量声明类型不一致,新版gcc 检查更严格 解决办法加上volatile 关键字使完全一致, extern volatile struct timeval xtime; 另外, 把time.c 中的 extern struct timeval xtime 也改为 extern volatile struct timeval xtime 这样编译就通过了,进入下一步链接问题. ld -r -o kernel.o sched.o sys_call.o traps.o irq.o dma.o fork.o panic.o printk.o vsprintf.o sys.o module.o ksyms.o exit.o signal.o mktime.o ptrace.o ioport.o itimer.o info.o ldt.o time.o ld: traps.o: in function tas: traps.c:(.text0x0): multiple definition of tas’; sched.o:sched.c:(.text0x830): first defined here ld: traps.o: in function verify_area: traps.c:(.text0x20): multiple definition of verify_area’; sched.o:sched.c:(.text0x850): first defined here ld: traps.o: in function get_free_page’: ld -r -o kernel.o sched.o sys_call.o traps.o … 错误位置: 连接错误, 在traps.c 中有tas 定义 但是sched.c 中也有tas 定义 同理,在traps.c 中有verify_area函数定义在sched.c 中也有verify_area函数定义 同理,在traps.c 中有get_free_page函数定义在sched.c 中也有get_free_page函数定义 首先先解决一个基本问题 ld 生成32bit 还是64bit 的选择问题 ld 应该加上选项 -m elf_i386 ,使生成 32bit 的库 打开Makefile , 将 LD ld 改为 LD ld -m elf_i386 然后来解决多重定义问题: 错误原因: get_free_page 是在mm.h中定义的 extern inline unsigned long 函数并在头文件中定义了函数体. 调用它的地方在多个文件中包含该头文件 显然它并没有在调用的地方inline 而是似乎定义了多个函数体 新版的gcc 要想inline, 只需要声明inline, 不再需要声明为extern inline 解决办法: 将extern inline … 改为 inline … 这一改动又引起了许多文件的改动 \( find . -name “.c -o -name .h” |xargs grep -l “extern inline” ./include/linux/sysv_fs.h ./include/linux/mm.h ./include/linux/sched.h ./include/linux/locks.h ./include/linux/interrupt.h ./include/linux/string.h ./include/asm/system.h ./fs/sysv/balloc.c ./drivers/net/atp.h ./drivers/sound/audio.c ./drivers/char/kbd_kern.h 不过这次改动比较简单因为是固定改动一个查找替换就可以了. 需要make clean , 消除原来生成的.o文件 再make, 重新生成.o文件 但是问题还没有完全解决, 还有一些连接问题 ld -m elf_i386 -r -o kernel.o sched.o sys_call.o traps.o irq.o dma.o fork.o panic.o printk.o vsprintf.o sys.o module.o ksyms.o exit.o signal.o mktime.o ptrace.o ioport.o itimer.o info.o ldt.o time.o ld: vsprintf.o: in function strcpy: vsprintf.c:(.text0x320): multiple definition of strcpy’; traps.o:traps.c:(.text0x0): first defined here ld: vsprintf.o: in function strncpy: vsprintf.c:(.text0x340): multiple definition of strncpy’; traps.o:traps.c:(.text0x20): first defined here 就是 string.h 文件还是有多重定义,为何? 错误原因: 象strcpy, strcmp 等这些常用的string.h 中的函数, 现代gcc 默认都使用它内置的形式,而不采用用户定义的形式. 解决方法: 在CFLAGS 上加上 -fno-builtin 这样就会使用用户的代码从而消除了重复定义. 这是我参考了0.11源码编译发现的. 打开Makefile 将 CFLAGS -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe 改为 CFLAGS -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-builtin 需要make clean , 消除原来生成的.o文件 再make, 重新生成.o文件 fpu_entry.c:473:24: error: lvalue required as left operand of assignment 473 | FPU_data_address 0; 错误原因: 左值需要左操作数赋值 , 左值FPU_data_address 定义的是(void *) 解决办法: 去掉(void *) #define FPU_data_address ((void *)(I387.soft.twd)) 改为 #define FPU_data_address (I387.soft.twd) 继续make, 还有许多警告 -Wstrict-aliasing fpu_emu.h:136:5: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 现在没空管这些警告, 尤其是这种严格的警告需要关闭 解决办法: 打开Makefile 将 CFLAGS -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-builtin 改为 CFLAGS -Wall -O2 -fomit-frame-pointer -pipe -fno-builtin 这样输出就会好很多! 还是没有关掉-Wstrict-aliasing, 算了,那是-Wall 引起的,就这样吧先不理它了. fpu_trig.c:748:17: error: missing terminating character 748 | asm volatile (movl %2,%%eax; mull %4; subl %%eax,%0; sbbl %%edx,%1; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ fpu_trig.c:749:18: error: expected string literal before ‘movl’ 749 | movl %3,%%eax; mull %4; subl %%eax,%1; 错误原因: 内嵌汇编不能只用一对双引号把块扩起来而应该每行都加双引号 解决办法: 每行加双引号. 这种改动因为没有统一性又是一种纯手工活,碰到了改就是了. exec.c: In function ‘copy_strings’: exec.c:380:44: error: lvalue required as left operand of assignment 380 | !(pag (char *) page[p/PAGE_SIZE] | ^ 将 if (!(pag (char *) page[p/PAGE_SIZE]) !(pag (char *) page[p/PAGE_SIZE] (unsigned long *) get_free_page(GFP_USER))) return 0; 改为 if (!(pag (char *) page[p/PAGE_SIZE])) { pag get_free_page(GFP_USER); page[p/PAGE_SIZE] pag; if(!pag) return 0; } ld -m elf_i386 -r -o minix.o bitmap.o truncate.o namei.o inode.o file.o dir.o symlink.o fsync.o ld: inode.o: in function set_bit: inode.c:(.text0x860): multiple definition of set_bit’; bitmap.o:bitmap.c:(.text0x130): first defined here 查看inode.c 的set_bit, 发现其定义为 extern inline int set_bit(int nr,int * addr) 把 extern 去掉 即可. 同时发现 dma.h 中也需要如此修改 继续,还有汇编问题 balloc.c:106: 错误 junk \)0 after expression balloc.c:106: 错误 junk repnz’ after register 将 asm( cld mov \(0,%%eax … 改为 asm( cld\n\t mov \)0,%%eax\n\t 即每行应加上\n, 又是手工活 不过在emacs或vim中编辑可以用宏命令简化 sock.c:331:17: error: lvalue required as left operand of assignment 331 | UN_DATA(sock) upd; 解决办法: //UN_DATA(sock) upd; sock-data upd; gcc -DKERNEL -m32 -Wall -O2 -fomit-frame-pointer -pipe -fno-builtin -c -o arp.o arp.c arp.c:126:27: error: conflicting type qualifiers for ‘arp_q’ 126 | struct sk_buff * volatile arp_q NULL; | ^~~~~ In file included from arp.c:80: arp.h:48:24: note: previous declaration of ‘arp_q’ was here 48 | extern struct sk_buff arp_q; 解决办法, 前面有说明加volatile 成完全一致 至此编译已经通过解决最后的连接问题. ld -m elf_i386 -Ttext 100000 boot/head.o init/main.o tools/version.o kernel/kernel.o mm/mm.o fs/fs.o net/net.o ipc/ipc.o fs/filesystems.a drivers/block/block.a drivers/char/char.a drivers/net/net.a ibcs/ibcs.o drivers/FPU-emu/math.a lib/lib.a -o tools/zSystem ld: 警告: 无法找到项目符号 _start; 缺省为 0000000000100000 ld: kernel/kernel.o: in function sys_alarm: (.text0x266): undefined reference to __stack_chk_fail_local’ 错误原因: stack_chk_fail_local 是新gcc 为安全启用的一个选项,系统文件中不包含该符号. 我们检查很多.o文件都包含stack_chk_fail_local 符号. 解决办法: CFLAGS 中加上-fno-stack-protector 将 CFLAGS -Wall -O2 -fomit-frame-pointer -pipe -fno-builtin 改为: CFLAGS -Wall -O2 -fomit-frame-pointer -pipe -fno-builtin -fno-stack-protector 重新make clean; make 继续: ld: kernel/kernel.o: in function schedule: (.text0xa2f): undefined reference to _current’ ld: (.text0xa38): undefined reference to _current ld: (.text0xa45): undefined reference to _last_task_used_math’ ld: kernel/kernel.o: in function down’: current 明明在schedule.c 中定义了,却为和说未定义 错误原因: 现在gcc的c语言 符号名不再自动加下划线了. 解决办法: 需要把对_current 的引用改为current, ld: kernel/kernel.o: in function sched_init: (.text0x12e2): undefined reference to gdt’ ld: (.text0x133c): undefined reference to idt ld: (.text0x1342): undefined reference to system_call’ 错误原因: 还是上面原因,新gcc不再把.c文件的符号自动加下划线, 所以.S 与 .C 中文件符号要重新对应 解决办法: 需要把head.S 中的 _gdb 改成gdt, _idt 改成 idt 等等. 起作用的是 .globl _idt,_gdt, 总之,解决这个需要在.S,中定义导出的下划线去掉 调用的下划线也去掉. 又是一个手工活,怎么顺手怎么来吧。 ld: kernel/kernel.o:(.data.rel.ro0x0): undefined reference to bad_IRQ0_interrupt ld: kernel/kernel.o:(.data.rel.ro0x4): undefined reference to bad_IRQ1_interrupt’ irq.h 中有一个宏,BUILD_IRQ, 其中有asm 内链汇编, 把标号名称去掉下划扛. 即将 “_bad_IRQ” #nr interrupt:\n\t SAVE_MOST ACK##chip(mask) RESTORE_MOST 改为: “bad_IRQ” #nr interrupt:\n\t SAVE_MOST ACK##chip(mask) RESTORE_MOST 同样: _IRQ, _fast_IRQ 也要去掉下划线 ld: kernel/kernel.o: in function sys_get_kernel_syms: (.text0x65cc): undefined reference to symbol_table_size’ ld: (.text0x6621): undefined reference to symbol_table’ 这要改ksyms.sh 文件, 去掉下划线,这样生成的 .s 文件不再有下划线. 关于.S, .c 符号一致性问题也就这么多了, 好好用find, grep 来定位问题,结合emacs,vim编辑 make[1]: 进入目录“/usr/src/linux/zBoot” gcc -DKERNEL__ -m32 -O2 -DSTDC_HEADERS xtract.c -o xtract xtract.c:18:10: fatal error: a.out.h: 没有那个文件或目录 18 | #include a.out.h 解决办法: 18 | #include a.out.h 改为 #include linux/a.out.h 实际上xtract 工具已经不使用它了, 因为它操作的是OMAGIC格式文件,而现在生成的是elf32 ld -m elf_i386 -o zSystem -Ttext 1000 head.o inflate.o unzip.o misc.o piggy.o piggy.o: file not recognized: file format not recognized make[1]: ** [Makefile:21zSystem] 错误 1 make[1]: 离开目录“/usr/src/linux/zBoot” 5 最后的问题 tools/zSystem 已经生成后, 内核压缩问题 此时 tools/zSystem 已经生成!! make -C zBoot make[1]: 进入目录“/usr/src/linux/zBoot” ./xtract …/tools/zSystem | gzip -9 | ./piggyback piggy.o Non-GCC header of ‘system’ Compressed size 20. ld -m elf_i386 -o zSystem -Ttext 1000 head.o inflate.o unzip.o misc.o piggy.o piggy.o: file not recognized: file format not recognized make[1]: *** [Makefile:21zSystem] 错误 1 我们可以研究一下zBoot 如何组装数据,有2个执行程序, xtract, piggyback 2个小程序 代码很少可以阅读. xtract 它抽取的是OMAGIC 格式的文件,但现在ld生成的是elf格式,该函数可以用脚本替换. piggyback, 用来生成piggy.o 的文件 但它是OMAGIC 格式的. tools/zSystem 是一个非压缩内核,它已经生成. 但没有生成压缩的内核,因为新版本ld 已经不支持OMAGIC格式的文件了, piggy.o 是把未压缩内核变成OMAGIC类型纯数据文件但ld已经不支持了. ubuntu18下还是支持的. ubuntu18 下的ld 是 ld –version 2.30 ubuntu20 下: ld –version GNU ld (GNU Binutils for Ubuntu) 2.34 只能放弃OMAGIC 格式, xtract,piggyback 都不能使用了, 需要用elf32 格式的文件 有时间再继续! 6 小结 由于汇编as,连接ld,及编译gcc的更新,代码及编译环境需要进行相应的调整 解决了一系列编译连接问题, 生成了未压缩的内核文件. 最后由于ld不能支持OMAGIC 格式文件,压缩的内核未能生成. 另,如果改用非压缩内核也会有问题,因为非压缩内核默认配置下编译出大大小是700多K,超过setup所能容纳 的容量,约512K setup.s 程序不方便改,因为它把内核放到0地址,而0xA0000或0xB8000地址是显示区,所以 内核大小受到了限制. 所以这一篇就先到编译出内核为止,生成tools/zSystem 下一篇继续解决压缩内核问题. 后面的任务包括编译出可启动影像zImage 并在虚拟机上运行和调试.
- 上一篇: 网站搭建和网页设计友点cms
- 下一篇: 网站搭建价格表html5个人网页制作代码
相关文章
-
网站搭建和网页设计友点cms
网站搭建和网页设计友点cms
- 技术栈
- 2026年04月20日
-
网站搭建好了怎么上到服务器wordpress图片768好吗
网站搭建好了怎么上到服务器wordpress图片768好吗
- 技术栈
- 2026年04月20日
-
网站搭建分站需要多少钱济宁500元网站建设
网站搭建分站需要多少钱济宁500元网站建设
- 技术栈
- 2026年04月20日
-
网站搭建价格表html5个人网页制作代码
网站搭建价格表html5个人网页制作代码
- 技术栈
- 2026年04月20日
-
网站搭建平台苏州网站制作 网站
网站搭建平台苏州网站制作 网站
- 技术栈
- 2026年04月20日
-
网站搭建平台有哪些网站建设 化工
网站搭建平台有哪些网站建设 化工
- 技术栈
- 2026年04月20日






