1. 编译工具
现在版本的ubuntu上的gcc编linux-2.4的内核错误太多,想了一个折中的方法:
把redhat9上的gcc-3.34拿出来编译linux-2.4.18就可以了
b. 刚开始下载的内核版本是linux-2.4.12了,后来发现《深入理解linux内核 第二版》指定的内核版本是2.4.18,
所以就换成2.4.18了,反正编译花不了多长是间,轻车熟路。
2. 修改如下
2.1顶层Makefile
ARCH := $(shell uname -m | sed
-e s/x86_64/i386/ -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
添加 sed -e s/x86_64/i386/
2.2 指定交叉编译工具链
CROSS_COMPILE = /work/os/bak/gcc/gcc-3.34/bin/
CFLAGS := -g $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O0 \
-fomit-frame-pointer -fno-strict-aliasing -fno-common
-O2 改为 O0 并添加了 -g
GENKSYMS = /sbin/genksyms
DEPMOD = /sbin/depmod
修改为-->
GENKSYMS = $(CROSS_COMPILE)/sbin/genksyms
DEPMOD = $(CROSS_COMPILE)/sbin/depmod
2.3
-
/work/os/linux-2.4.18/include/asm/checksum.h:72:30: missing terminating " character
-
In file included from ksyms.c:50:
-
/work/os/linux-2.4.18/include/asm/checksum.h: In function `ip_fast_csum':
-
/work/os/linux-2.4.18/include/asm/checksum.h:73: error: parse error before "movl"
-
/work/os/linux-2.4.18/include/asm/checksum.h:75:17: invalid suffix "f" on integer constant
-
/work/os/linux-2.4.18/include/asm/checksum.h:82:17: invalid suffix "b" on integer constant
-
/work/os/linux-2.4.18/include/asm/checksum.h:90:13: missing terminating " character
-
/work/os/linux-2.4.18/include/asm/checksum.h:105:17: missing terminating " character
-
/work/os/linux-2.4.18/include/asm/checksum.h: In function `csum_fold':
-
/work/os/linux-2.4.18/include/asm/checksum.h:106: error: parse error before "addl"
-
/work/os/linux-2.4.18/include/asm/checksum.h:108:17: missing terminating " character
-
/work/os/linux-2.4.18/include/asm/checksum.h:121:13: missing terminating " character
-
/work/os/linux-2.4.18/include/asm/checksum.h: In function `csum_tcpudp_nofold':
-
/work/os/linux-2.4.18/include/asm/checksum.h:122: error: parse error before "addl"
-
/work/os/linux-2.4.18/include/asm/checksum.h:126:9: missing terminating " character
-
/work/os/linux-2.4.18/include/asm/checksum.h:161:17: missing terminating " character
-
/work/os/linux-2.4.18/include/asm/checksum.h: In function `csum_ipv6_magic':
-
/work/os/linux-2.4.18/include/asm/checksum.h:162: error: parse error before "addl"
-
/work/os/linux-2.4.18/include/asm/checksum.h:173:17: missing terminating " character
改正: /work/os/linux-2.4.18/include/asm-i386/checksum.h
2.4
ide-cd.h:438: error: long, short, signed or unsigned used invalidly for `slot_tablelen'
__u8 short slot_tablelen;
--> unsigned short slot_tablelen;
2.5
-
/work/os/bak/gcc/gcc-3.34/bin/gcc -g -D__KERNEL__ -I/work/os/linux-2.4.18/include -Wall -Wstrict-prototypes -Wno-trigraphs -O0 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -DKBUILD_BASENAME=eepro100 -c -o eepro100.o eepro100.c
-
eepro100.c:87:2: warning: #warning You must compile this file with the correct
-
eepro100.c:88:2: warning: #warning See the last lines of the source file.
-
eepro100.c:89:2: #error You must compile this driver with "-O".
改正:
89 #error You must compile this driver with "-O".
--> 89 #warning You must compile this driver with "-O".
2.6
-
/work/os/bak/gcc/gcc-3.34/bin/gcc -g -D__KERNEL__ -I/work/os/linux-2.4.18/include -Wall -Wstrict-prototypes -Wno-trigraphs -O0 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -DKBUILD_BASENAME=semaphore -c -o semaphore.o semaphore.c
-
semaphore.c:241:1: missing terminating " character
-
semaphore.c:242: error: request for member `align' in something not a structure or union
-
semaphore.c:242: error: parse error before numeric constant
-
semaphore.c:248:17: invalid suffix "b" on integer constant
-
semaphore.c:258: error: parse error before '%' token
-
semaphore.c:260: warning: type defaults to `int' in declaration of `$1'
-
semaphore.c:260: error: parse error before '%' token
-
semaphore.c:261:17: invalid suffix "b" on integer constant
-
semaphore.c:263: error: parse error before '%' token
-
semaphore.c:266:1: missing terminating " character
-
make[1]: *** [semaphore.o] Error 1
将linux-2.4.18/arch/i386/kernel/semaphore.c的最后改成如下形式
-
#if defined(CONFIG_SMP)
-
asm(
-
"\n\t"
-
".align 4\n\t"
-
".globl __write_lock_failed\n\t"
-
"__write_lock_failed:\n\t"
-
" " LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)\n\t"
-
"1: rep; nop\n\t"
-
" cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t"
-
" jne 1b\n\t"
-
"\n\t"
-
" " LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t"
-
" jnz __write_lock_failed\n\t"
-
" ret\n\t"
-
-
"\n\t"
-
".align 4\n\t"
-
".globl __read_lock_failed\n\t"
-
"__read_lock_failed:\n\t"
-
" lock ; incl (%eax)\n\t"
-
"1: rep; nop\n\t"
-
" cmpl $1,(%eax)\n\t"
-
" js 1b\n\t"
-
"\n\t"
-
" lock ; decl (%eax)\n\t"
-
" js __read_lock_failed\n\t"
-
" ret\n\t"
-
);
-
#endif
2.7
/work/os/bak/gcc/gcc-3.34/bin/ld -m elf_i386 -r -o kernel.o process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o pci-dma.o i386_ksyms.o i387.o bluesmoke.o dmi_scan.o pci-i386.o pci-pc.o pci-irq.o smp.o smpboot.o trampoline.o mpparse.o apic.o nmi.o io_apic.o acpitable.o
trampoline.o: file not recognized: File format not recognized
这是因为我的交叉编译工具链没有完全弄好,对于*.S的文件,它会用原系统中的as工具
-
/work/os/bak/gcc/gcc-3.34/bin/gcc -D__ASSEMBLY__ -D__KERNEL__ -I/work/os/linux-2.4.18/include -traditional -c arch/i386/kernel/entry.S -o entry.o --verbose
-
as -V -Qy -o entry.o /tmp/cckGi4Jo.s
-
GNU assembler version 2.24 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.24
所以只好手动编译了:
手动编译 --> arch/i386/kernel/entry.S
手动编译 --> arch/i386/kernel/trampoline.S
手动编译--> arch/i386/kernel/head.S
手动编译--> arch/i386/lib/checksum.S
2.8
/work/os/linux-2.4.18/arch/i386/lib/usercopy.c:47: undefined reference to `prefetch'
/work/os/linux-2.4.18/include/asm-i386/processor.h
extern inline void prefetch(const void *x) --->
static inline void prefetch(const void *x)
2.9
/work/os/linux-2.4.18/net/sunrpc/xdr.c:95: undefined reference to `ntohl'
/work/os/linux-2.4.18/include/linux/byteorder/generic.h
#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__)
-->
//modify by wangcong
//#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__)
#if defined(__GNUC__) && (__GNUC__ >= 2)
2.10
/work/os/linux-2.4.18/net/sunrpc/xprt.c:241: undefined reference to `xprt_move_iov'
/work/os/linux-2.4.18/net/sunrpc/xprt.c
extern inline void
xprt_move_iov(struct msghdr *msg, struct iovec *niv, unsigned amount)
-->static inline void
xprt_move_iov(struct msghdr *msg, struct iovec *niv, unsigned amount)
2.11
net/network.o(.text+0x652f5):/work/os/linux-2.4.18/net/unix/garbage.c:268: undefined reference to `maybe_unmark_and_push'
unix_release_addr -->net/packet/af_packet.c
fn_flush_list --> net/ipv4/fib_hash.c
before --> include/net/tcp.h
after --> include/net/tcp.h
tcp_replace_ts_recent --> net/ipv4/tcp_input.c
sockfd_put --> net/socket.c
socki_lookup -->net/socket.c
ipc_lock -->ipc/util.h
SBI --> fs/devpts/devpts_i.h
tcpdiag_rcv_skb -->net/ipv4/tcp_diag.c
rotate_left -->drivers/char/random.c
rtnetlink_rcv_skb -->net/core/rtnetlink.c
tcp_need_reset -->net/ipv4/tcp.c
还有一些没有添加的
2.12. /work/os/linux-2.4.18/include/linux/brlock.h:87: undefined reference to `__br_lock_usage_bug'
/work/os/linux-2.4.18/include/linux/brlock.h
extern void __br_lock_usage_bug (void);
-->//modify by wangcong
static inline void __br_lock_usage_bug (void)
{
printk("cong: __BRLOCK_USE_ATOMICS\n");
return ;
}
include/asm/fixmap.h
extern void __this_fixmap_does_not_exist(void);
-->//modify by wangcong
static inline void __this_fixmap_does_not_exist(void)
{
printk("cong: __this_fixmap_does_not_exist\n");
}
2.13.
/work/os/linux-2.4.18/net/ipv4/af_inet.c:839: undefined reference to `__get_user_4'
arch/i386/lib/getuser.S 手动编译
arch/i386/boot/compressed/head.S 手动编译
2.14
tools/build -b bbootsect bsetup compressed/bvmlinux.out CURRENT > bzImage
Root device is (8, 8)
./Makefile
export ROOT_DEV = CURRENT -->
export ROOT_DEV =
arch/i386/boot/tools/build.c
42 #define DEFAULT_MAJOR_ROOT 0
43 #define DEFAULT_MINOR_ROOT 0
-->
42 #define DEFAULT_MAJOR_ROOT 0x03
43 #define DEFAULT_MINOR_ROOT 0x01
2.15 现在编译成功了,运行时出现
Kernel panic: I have no root and I want to scream
/work/os/linux-2.4.18/fs/super.c --> mount_root 的开始添加 ROOT_DEV = 0x301;
2.16 用qemu运行完美
a. qemu 进行内核调试
b. 启动运行busybox ls 正常
2.17 用bochs调试
如果在编译的最扣出现 kernel is too big for standalone boot, 说明内核太大了不支持从软盘单独启动,解决方法有两个
a. 制作grub引导的硬盘镜像,将bzImage放在硬盘分区中
b. 裁减内核到小于 960K就可以了
附录1. 编译流程
-
cong@msi:/work/os/linux-2.4.18$ make config
-
cong@msi:/work/os/linux-2.4.18$ ./mycompile.sh -->先手动编译一下
-
cong@msi:/work/os/linux-2.4.18$ make -j8 bzImage -->会出现entry.S编译不正确
-
cong@msi:/work/os/linux-2.4.18$ ./mycompile.sh -->没关系再执行一下手动编译
-
cong@msi:/work/os/linux-2.4.18$ make -j8 bzImage -->这次就正常了
附2:手动编译脚本
-
cong@msi:/work/os/linux-2.4.18$ cat mycompile.sh
-
#!/bin/sh
-
GCC_PATH=/work/os/bak/gcc/gcc-3.34
-
CC=$GCC_PATH/bin/gcc
-
CC1=$GCC_PATH/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/cc1
-
AS=$GCC_PATH/bin/as
-
SRC=`pwd`
-
make_module()
-
{
-
echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/work/os/bak/gcc/gcc-3.34/lib/"
-
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/work/os/bak/gcc/gcc-3.34/lib/
-
#$CC -D__ASSEMBLY__ -D__KERNEL__ -I$SRC/include -traditional -c arch/i386/kernel/entry.S -o entry.o --verbose
-
echo "make----> arch/i386/kernel/entry.o"
-
$CC1 -E -traditional-cpp -lang-asm -quiet -v -I$SRC/include -iprefix $GCC_PATH/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/ -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=4 -D__ASSEMBLY__ -D__KERNEL__ arch/i386/kernel/entry.S -o /tmp/entry.s
-
$AS -V -Qy -o entry.o /tmp/entry.s
-
cp ./entry.o ./arch/i386/kernel/entry.o
-
rm /tmp/entry.s
-
-
echo "make ----> arch/i386/kernel/trampoline.o"
-
$CC1 -E -traditional-cpp -lang-asm -quiet -v -I$SRC/include -iprefix $GCC_PATH/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/ -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=4 -D__ASSEMBLY__ -D__KERNEL__ ./arch/i386/kernel/trampoline.S -o /tmp/trampoline.s
-
$AS -V -Qy -o trampoline.o /tmp/trampoline.s
-
cp ./trampoline.o ./arch/i386/kernel/trampoline.o
-
rm /tmp/trampoline.s
-
-
echo "make ----> arch/i386/kernel/head.o"
-
$CC1 -E -traditional-cpp -lang-asm -quiet -v -I$SRC/include -iprefix $GCC_PATH/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/ -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=4 -D__ASSEMBLY__ -D__KERNEL__ ./arch/i386/kernel/head.S -o /tmp/head.s
-
$AS -V -Qy -o head.o /tmp/head.s
-
cp ./head.o ./arch/i386/kernel/head.o
-
rm /tmp/head.s
-
-
echo "make ----> arch/i386/lib/checksum.o"
-
$CC1 -E -lang-asm -quiet -v -I$SRC/include -iprefix $GCC_PATH/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/ -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=4 -D__ASSEMBLY__ -D__KERNEL__ ./arch/i386/lib/checksum.S -o /tmp/checksum.s
-
$AS -V -Qy -o checksum.o /tmp/checksum.s
-
cp ./checksum.o ./arch/i386/lib/checksum.o
-
rm /tmp/checksum.s
-
-
echo "make ----> arch/i386/lib/getuser.o"
-
$CC1 -E -lang-asm -quiet -v -I$SRC/include -iprefix $GCC_PATH/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/ -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=4 -D__ASSEMBLY__ -D__KERNEL__ arch/i386/lib/getuser.S -o /tmp/getuser.s
-
$AS -V -Qy -o getuser.o /tmp/getuser.s
-
cp ./getuser.o ./arch/i386/lib/getuser.o
-
rm /tmp/getuser.s
-
-
echo "make ----> arch/i386/boot/compressed/head.o"
-
$CC1 -E -traditional-cpp -lang-asm -quiet -v -I$SRC/include -iprefix $GCC_PATH/lib/gcc-lib/i686-pc-linux-gnu/3.3.4/ -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=4 -D__ASSEMBLY__ -D__KERNEL__ arch/i386/boot/compressed/head.S -o /tmp/head.s
-
$AS -V -Qy -o head.o /tmp/head.s
-
cp ./head.o ./arch/i386/boot/compressed/head.o
-
rm /tmp/head.s
-
}
-
-
make_sched()
-
{
-
#02-->ok O0-->bad
-
#change the CFLAGS at kernle/Makefile
-
echo "make --> kernel/sched.c "
-
$CC -g -D__KERNEL__ -I$SRC/include -Wall -Wstrict-prototypes -Wno-trigraphs -O1 -fomit-frame-pointer -fno-strict-aliasing -fno-common -pipe -mpreferred-stack-boundary=2 -march=i686 -c -o kernel/sched.o kernel/sched.c
-
}
-
-
case "$1" in
-
*)
-
make_module
-
;;
-
esac
附录2. 下面将生成的patch打包
diff -Nur linux-2.4.18 linux-2.4.18_grep > linux-2.4.18-patch.txt
tar czf linux-2.4.18-patch.rar ./linux-2.4.18-patch.txt
linux-2.rar (下载后改名为linux-2.4.18.patch.tar.gz)