wintoflash
发表于 2019-10-29 21:46:15
求道者 发表于 2019-10-29 21:19
你用gcc4.5编译的wee64.mbr吧……
体积大不少
但偏移常数是对的
fsys_ext2fs.c:39:1: 错误:对‘log2_tmp’的静态声明出现在非静态声明之后
修改fsys_ext2fs.c 37~44行
把
static __inline__ unsigned long
log2_tmp (unsigned long word)
{
__asm__ ("bsfl %1,%0"
: "=r" (word)
: "r" (word));
return word;
}
移动到shard.h 389行,覆盖原来的
extern inline unsigned long log2_tmp (unsigned long word);
求道者
发表于 2019-10-29 22:47:05
本帖最后由 求道者 于 2019-10-29 22:52 编辑
wintoflash 发表于 2019-10-29 21:46
fsys_ext2fs.c:39:1: 错误:对‘log2_tmp’的静态声明出现在非静态声明之后
修改fsys_ext2fs.c 37~44 ...
NICE!
但别的地方报错了
wee63start.S: Assembler messages:
wee63start.S:248: 错误:value of 131336476 too large for field of 2 bytes at 132
wee63start.S:375: 错误:value of 8208529 too large for field of 2 bytes at 289
make: *** 错误 1
wintoflash
发表于 2019-10-29 22:57:07
求道者 发表于 2019-10-29 22:47
NICE!
但别的地方报错了
这个和我编译grub4dos的时候遇到的错误一样.我不懂汇编,所以没办法了
求道者
发表于 2019-10-29 23:06:31
wintoflash 发表于 2019-10-29 22:57
这个和我编译grub4dos的时候遇到的错误一样.我不懂汇编,所以没办法了
这个能搞定的话,应该能连同grub4dos一起迁移到gcc9吧……
yaya救命啊
不点
发表于 2019-10-30 10:17:26
本帖最后由 不点 于 2019-10-30 10:37 编辑
求道者 发表于 2019-10-29 22:47
NICE!
但别的地方报错了
贴出 248 行以及 375 行附近的代码看看,汇编代码的错误,应该有办法解决。
忽然想起来了,可能没法解决。
可能是 gcc 新版生成的代码体积太大(上百M,天文数字)造成的。
算了吧,死了这条心。
其一是可以用旧版 gcc。
其二是用 clang
其三是用 tcc(Tiny C Compiler)
应该还有许多别的可能性。
个人顺便留个阶段性的结论(声明:只用于提醒自己,与别人无关):
Linus Torvalds 不值得信任。gcc 和 bash 属于 GNU 的,也不能信任。如此,GNU/Linux 也就不能信任了。这就为将来努力抛弃 Linux 找到了完整的理由。
求道者
发表于 2019-10-30 21:02:22
不点 发表于 2019-10-30 10:17
贴出 248 行以及 375 行附近的代码看看,汇编代码的错误,应该有办法解决。
忽然想起来了,可能没法 ...
248行和附近
/* begin characteristics distinguish this sector from others */
.byte 0x8E, 0xDB //movw %bx, %ds
.byte 0x68, 0xE0, 0x07 //pushw $0x07E0
.byte 0x07 //popw %es /* ES=0x07E0 */
//cmpl $0xCE1A02B0, (wee63_signature - _start1 + 4 + STAGE2_SIZE - 4)
.byte 0x66, 0x81, 0x3E //cmpl
.word (wee63_signature - _start1 + STAGE2_SIZE)
//this word is a pointer to the bootlace
//signature near the end of pre_stage2
//this word varies according to STAGE2_SIZE.
.byte 0xB0, 0x02, 0x1A, 0xCE //this is the bootlace signature.
//it should also appear at near the end
//of pre_stage2
/* end characteristics distinguish this sector from others */
375行和附近 movb $0x80, %dl /* try hard drive first */
1:
xorl %eax, %eax
pushaw
pushl %eax
pushl %eax
pushw %es
pushw %ax
pushw $127 //$63
pushw $0x10
movw %sp, %si /* DS:SI=SS:SP=disk address packet */
movw $0x4200, %ax
call int13
popaw
popaw
/* compare the sector to the MBR, ignoring BPB */
movw $0x5A, %si
movw %si, %di
movw $((0x200 - 0x5A) / 2), %cx
cs repz cmpsw
je 1f
testb %dl, %dl /* floppy tried? */
je Error_or_prev_MBR /* yes. fail */
movb $0, %dl /* then try floppy */
jmp 1b
1:
movw %es, %bx
addw $((wee63_signature - _start1 + 4 + STAGE2_SIZE - 4) >> 4), %bx
movw %bx, %ds
cmpl $0xCE1A02B0, ((STAGE2_SIZE - 4) & 0x0F)
jne Error_or_prev_MBR /* Missing helper */
2:
ljmp $0, $0x8200
求道者
发表于 2019-10-30 21:12:44
不点 发表于 2019-10-30 10:17
贴出 248 行以及 375 行附近的代码看看,汇编代码的错误,应该有办法解决。
忽然想起来了,可能没法 ...
clang编译 报这个错
clang -m32 -mno-sse -g-c asm.S -o ./asm.o
asm.S:7618:5: error: invalid operand for instruction
cs lodsb
^~~~~
asm.S:7627:5: error: invalid operand for instruction
cs lodsb
^~~~~
asm.S:8566:15: error: unexpected token in argument list
addr32 loopz 1b
^
make: *** 错误 1
不点
发表于 2019-10-31 02:19:26
求道者 发表于 2019-10-30 21:02
248行和附近
这个已经说过了,是新版 gcc 编译的二进制结果体积太大导致的,无解。就是 STAGE2_SIZE 超级大,很多 M 字节。你的编译过程中,应该出现这个超级大的中间结果文件,那就是新版 gcc 编译出的中间结果文件。
不点
发表于 2019-10-31 02:40:11
求道者 发表于 2019-10-30 21:12
clang编译 报这个错
clang 的汇编器可能不支持前缀 cs 和 addr32 等。解决办法:
把 cs lodsb 写成两行:
.byte 0x2E // 手动编码前缀 cs
lodsb
同理,把 addr32 loopz 1b 也写成两行:
.byte 0x67 // 手动编码前缀 addr32
loopz1b
求道者
发表于 2019-10-31 13:00:01
本帖最后由 求道者 于 2019-10-31 13:01 编辑
不点 发表于 2019-10-31 02:40
clang 的汇编器可能不支持前缀 cs 和 addr32 等。解决办法:
把 cs lodsb 写成两行:
make
make WEE127=1 BUILDIDUNSUPPORTTED=0 wee127/wee63.mbr
make: 进入目录“/home/daiaji/grubutils/grubutils/wee”
clang -m32 -mno-sse -g -DMBRSECTORS127 -c asm.S -o wee127/asm.o
asm.S:4218:12: error: unknown token in expression
lcall %cs:*(ROM_int15 - int13_handler)
^
asm.S:5708:12: error: unknown token in expression
lcall %cs:*(ROM_int15 - int13_handler)
^
asm.S:5789:11: error: unknown token in expression
ljmp %cs:*(ROM_int15 - int13_handler)
^
asm.S:5835:11: error: unknown token in expression
ljmp %cs:*(ROM_int15 - int13_handler)
^
asm.S:5872:12: error: unknown token in expression
lcall %cs:*(ROM_int15 - int13_handler)
^
asm.S:6042:12: error: unknown token in expression
lcall %cs:*(ROM_int15 - int13_handler)
^
asm.S:6169:11: error: unknown token in expression
ljmp %cs:*(ROM_int15 - int13_handler)
^
make: *** 错误 1
make: 离开目录“/home/daiaji/grubutils/grubutils/wee”
make: *** 错误 2而且clang不支持-mpreferred-stack-boundary=2
不点
发表于 2019-10-31 15:08:35
本帖最后由 不点 于 2019-10-31 16:40 编辑
求道者 发表于 2019-10-31 13:00
而且clang不支持-mpreferred-stack-boundary=2
这次的错误其实只有一个:都是不认识 %cs:*(ROM_int15 - int13_handler)
这很容易搞。试试两个办法,其一,试试去掉星号,看看能否通过。其二,那就得手动替它汇编了。手动汇编还得查阅 intel 相关指令手册。你就先试试去掉星号,看看怎么样?
不支持 -mpreferred-stack-boundary=2 没关系,这个参数不重要。
lcall 和 ljmp 就相当于微软汇编里面的 call far 和 jmp far。
有个偷懒的办法,可以不用查阅 intel 手册,就能知道
ljmp %cs:*(ROM_int15 - int13_handler)
能够编码成什么字节串。
在 gcc 编译的情况下,你在
ljmp %cs:*(ROM_int15 - int13_handler)
的前后插入一些垃圾字节,比如这样:
.ascii "hihihi" // 这些垃圾字节当然不可以出现在正式使用的编译结果中
ljmp %cs:*(ROM_int15 - int13_handler)
.ascii "hello!" // 这些垃圾字节当然不可以出现在正式使用的编译结果中
然后,你在编译结果中查找这些字符串,就能知道两个字符串中间的编译结果了。然后,通过猜测,就能知道指令代码 ljmp 和 cs 前缀分别是啥,以及跟着的参数(ROM_int15 - int13_handler) 的值。于是,就可以用
.byte0x?? // 这应该是 cs 前缀,也就是前面曾经用过的 0x2E
.byte0x?? // 这个应该是 ljmp 间接寻址的指令码,究竟是单字节还是两个字节,我不太确定。如果是俩字节,那就是 .byte0x?? , 0x?? 的格式。
.word (ROM_int15 - int13_handler)
来构造汇编代码,让 clang 能够运转了。
同理,lcall 的情况也可以用这种方法来处理。
求道者
发表于 2019-10-31 18:42:41
本帖最后由 求道者 于 2019-10-31 18:56 编辑
不点 发表于 2019-10-31 15:08
这次的错误其实只有一个:都是不认识 %cs:*(ROM_int15 - int13_handler)
这很容易搞。试试两个办法, ...
asm.S:4218:2: error: unknown use of instruction mnemonic without a size suffix
lcall %cs:(ROM_int15 - int13_handler)
^
asm.S:5708:2: error: unknown use of instruction mnemonic without a size suffix
lcall %cs:(ROM_int15 - int13_handler)
^似乎是编译失败……
但我不不知道产物去哪了……
并没有wee127/asm.o
不点
发表于 2019-10-31 19:01:49
说明去掉星号起作用了。它还要求精确的字宽后缀。给指令添加w后缀试试。w代表 word,即 16 位宽度。
就是说,把 ljmp 改成 ljmpw,把 lcall 改成 lcallw。
求道者
发表于 2019-10-31 19:23:56
本帖最后由 求道者 于 2019-10-31 19:29 编辑
不点 发表于 2019-10-31 19:01
说明去掉星号起作用了。它还要求精确的字宽后缀。给指令添加w后缀试试。w代表 word,即 16 位宽度。
就 ...
make
make WEE127=1 BUILDIDUNSUPPORTTED=0 wee127/wee63.mbr
make: 进入目录“/home/daiaji/grubutils/grubutils/wee”
clang -m32 -mno-sse -g -DMBRSECTORS127 -c asm.S -o wee127/asm.o
asm.S:4218:9: error: invalid operand for instruction
lcallw %cs:(ROM_int15 - int13_handler)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
asm.S:5708:9: error: invalid operand for instruction
lcallw %cs:(ROM_int15 - int13_handler)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
asm.S:5789:8: error: invalid operand for instruction
ljmpw %cs:(ROM_int15 - int13_handler)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
asm.S:5835:8: error: invalid operand for instruction
ljmpw %cs:(ROM_int15 - int13_handler)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
asm.S:5872:9: error: invalid operand for instruction
lcallw %cs:(ROM_int15 - int13_handler)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
asm.S:6042:9: error: invalid operand for instruction
lcallw %cs:(ROM_int15 - int13_handler)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
asm.S:6169:8: error: invalid operand for instruction
ljmpw %cs:(ROM_int15 - int13_handler)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make: *** 错误 1
make: 离开目录“/home/daiaji/grubutils/grubutils/wee”
make: *** 错误 2
不点
发表于 2019-10-31 19:57:18
这次报操作数错误。试试去掉%cs:,在指令前面插入一行 .byte 0x2E
求道者
发表于 2019-10-31 20:03:01
不点 发表于 2019-10-31 19:57
这次报操作数错误。试试去掉%cs:,在指令前面插入一行 .byte 0x2E
make
make WEE127=1 BUILDIDUNSUPPORTTED=0 wee127/wee63.mbr
make: 进入目录“/home/daiaji/grubutils/grubutils/wee”
clang -m32 -mno-sse -g -DMBRSECTORS127 -c asm.S -o wee127/asm.o
asm.S:4220:9: error: invalid operand for instruction
lcallw (ROM_int15 - int13_handler)
^~~~~~~~~~~~~~~~~~~~~~~~~~~
不点
发表于 2019-10-31 20:29:37
添加星号试试
lcallw *(ROM_int15 - int13_handler)
如果不行,再试试
lcallw 7777
lcallw *7777
lcallw (7777)
lcallw *(7777)
看哪个能成功。注意星号和 w 之间有空格。
求道者
发表于 2019-10-31 20:45:16
不点 发表于 2019-10-31 20:29
添加星号试试
lcallw *(ROM_int15 - int13_handler)
-rw-r--r-- 1 daiaji daiaji 126M 10月 31 20:44 wee127.mbr
-rw-r--r-- 1 daiaji daiaji 126M 10月 31 20:44 wee63.mbr
能编译但是产物非常大
代码我改成这样了
.byte 0x2E
lcallw *(EXT_C(ROM_int15) - int13_handler)
.byte 0x2E
ljmpw *(EXT_C(ROM_int15) - int13_handler)
不点
发表于 2019-10-31 21:08:03
这么大的文件,是错的。我猜可能是操作系统底层更改造成的。算了,不折腾了。安心用旧版 gcc 编译吧。
求道者
发表于 2019-10-31 21:34:22
本帖最后由 求道者 于 2019-10-31 21:35 编辑
不点 发表于 2019-10-31 21:08
这么大的文件,是错的。我猜可能是操作系统底层更改造成的。算了,不折腾了。安心用旧版 gcc 编译吧。
前面汇编代码部分似乎被充了很多零,然后菜单前面有100M多的零.
可能是填充出了问题,gcc是对的。
不点
发表于 2019-10-31 21:40:39
求道者 发表于 2019-10-31 21:34
前面汇编代码部分似乎被充了很多零,然后菜单前面有100M多的零.
可能是填充出了问题,gcc是对的。
跟踪 Makefile 的执行过程,可以了解究竟是哪个步骤增大了体积。
求道者
发表于 2019-10-31 21:44:14
不点 发表于 2019-10-31 21:40
跟踪 Makefile 的执行过程,可以了解究竟是哪个步骤增大了体积。
pre_stage2 非常大
这不正常吧?
不点
发表于 2019-10-31 22:26:03
这个 pre_stage2 是 gcc 生成的,是编译过程生成的。情况与 grub4dos 一样,无解了。老老实实用旧版 gcc 吧。
求道者
发表于 2019-10-31 22:43:11
本帖最后由 求道者 于 2019-10-31 22:47 编辑
不点 发表于 2019-10-31 22:26
这个 pre_stage2 是 gcc 生成的,是编译过程生成的。情况与 grub4dos 一样,无解了。老老实实用旧版 gcc 吧 ...
好消息恐怕是,两者的迁移经验应该是差不多的,未来也许能完成迁移……
谁知道这东西是怎么生成的?
不点
发表于 2019-11-1 17:05:34
求道者 发表于 2019-10-31 22:43
好消息恐怕是,两者的迁移经验应该是差不多的,未来也许能完成迁移……
谁知道这东西是怎么生成的?
我个人感觉,折腾 gcc 的意义不大。我也不想研究,究竟是 bin-utils 的原因呢,还是 gcc 的原因,拟或是别的什么原因(比如 Linux 内核的原因)。整个 Linux 内核连同 GNU 工具链,都不可靠,而且是越来越不可靠。
我在想,将来或许会有人从以前的某个 Linux 版本以及某个 GNU 工具链开始,重新建立一个新系统。GNU 的 GPL 协议提供了这种可能性。不过,那也许是猴年马月的事了,我不一定能看得到。
我目前对待 Linux 的态度就是,凑合着用。这与我对待 Windows 的态度也差不多是一样的。不要太认真,过一天是一天。至于说 wee 呀,grub4dos 呀,都不是大事,能有一个编译版本用着,就该知足了。能有一个编译方法在网上找得到、行得通,就该满意了。
对待同一件事,不同的人,站的角度不同,态度就不同,结论也不同,处理方法也不同。
求道者
发表于 2019-11-1 18:19:39
不点 发表于 2019-11-1 17:05
我个人感觉,折腾 gcc 的意义不大。我也不想研究,究竟是 bin-utils 的原因呢,还是 gcc 的原因,拟或是 ...
你这完完全全就是不符合客观事实的臆测了!
事实就是gcc起码直接告诉你就是pre_stage2生成的有问题!
clang还有一堆汇编方法不支持,要手动汇编!最后pre_stage2还是很大!
没错,clang是没怎么报警告,但这只是说明clang习惯宽松的语法检测!或者干脆不报!
这不能说明clang更好,更先进!
clang还浪费了一堆时间!
感觉顶多就是语法变了!
搞不好还是c的问题!
求道者
发表于 2019-11-1 18:43:36
gcc -m32 -mno-sse -g -o 1.bin -nostdlib -Wl,-N -Wl,-Ttext -Wl,308200 -Wl,-N -Wl,--build-id=none ./asm.o ./builtins.o ./disk_io.o ./fsys_ext2fs.o ./fsys_fat.o ./fsys_ntfs.o
ls -alh 1.bin
-rwxr-xr-x 1 daiaji daiaji 122K 11月1 18:41 1.bin
objcopy -O binary 1.bin
ls -alh 1.bin
-rwxr-xr-x 1 daiaji daiaji 126M 11月1 18:41 1.bin
我个人的一点点进展
不知道为什么objcopy -O binary之后体积变大
我不知道objcopy -O binary是怎么工作的……
不点
发表于 2019-11-1 20:14:41
本帖最后由 不点 于 2019-11-1 20:51 编辑
求道者 发表于 2019-11-1 18:43
我个人的一点点进展
不知道为什么objcopy -O binary之后体积变大
我不知道objcopy -O binary是怎么工 ...
我不懂,所以,臆测一下,也很自然。谁懂,谁就多劳啊!
你这不已经很有成效了吗?发现 objcopy 使得体积变大。抱歉,对这些,我又是完全不懂。
让懂的人来帮你,或者,你自己查资料搞定。
关键是,我俩站的角度不同。我对 Linux 的整体大环境没兴趣了,而你还很有兴趣。我失望了、没有希望了,而你还很有希望。我觉得折腾这些编译没有意义,随便有个编译能够凑合着用也就够了。而你还满怀信心和希望,你不满足于我的那种低标准和低要求。那接下来看看现实世界会朝哪个方向发展,看看实践检验的结果究竟如何。咱也没必要进行争论,实践会检验的。几年以后,Linux、GNU 工具链、发行版的情况变好,能有很大的进展,我倒是希望如此。希望在将来,你不会沦落到像我这么样的地步、像我这么样的心态。恕我直言,对这个 Linux,我目前在逐渐把它看成“又一个 Windows,一个开源的 Windows”,越来越没有新鲜感了。
9001
发表于 2020-5-20 22:11:32
求道者 发表于 2019-10-29 15:54
原始菜单没问题,但改菜单就会出问题。
还真是这样。
一旦修改,比如原始菜单修改了写入移动硬盘,以下面一句开头
timeout 1
一个偶然的机会,用fbinsttool打开了移动硬盘,发现菜单是以 " t 1"开头,显然是前面6个字符“timeou"被吃掉了。
据此,可以在菜单开始处加上6个空格就OK了。测试也是成功的。
通过fbinsttool可以看到,修改后的菜单结尾有单独一行“-e”,这个会影响到最后一个菜单。需要使用winhex清除或者在它之前加一个隐藏无意义的菜单屏蔽之。
9001
发表于 2020-5-20 22:14:06
本帖最后由 9001 于 2020-5-23 23:05 编辑
9001 发表于 2020-5-20 22:11
还真是这样。
一旦修改,比如原始菜单修改了写入移动硬盘,以下面一句开头就是说,如果菜单出了问题,用bootice写入修改的菜单,bootice是看不出来的。但是,fbinsttool可以非常直观地再现菜单问题,与实际启动后显示的一致。
现在的解决办法是:
1、winhex大法,尽管bootice写入的菜单地址是0x7850,之前有那么6个字节的乱码,用winhex把6个乱码清零,从7850处复制菜单,把菜单情况的-e清零。
2、使用上面28楼求道者编译的WEE63.mbr,使用bootice导入到MBR。当然,可以事先把自己的菜单使用hex编辑器修改好。