无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
12
返回列表 发新帖
楼主: jianliulin
打印 上一主题 下一主题

[求助] 批处理引导linux内核出错

  [复制链接]
31#
发表于 2017-4-13 19:51:29 来自手机 | 只看该作者
回复

使用道具 举报

32#
 楼主| 发表于 2017-4-14 09:10:27 | 只看该作者
本帖最后由 jianliulin 于 2017-4-14 09:12 编辑

还是有意义的,如果逻辑比较复杂的可以写批处理,只是批处理不能加载尾续的linux内核而已。
回复

使用道具 举报

33#
发表于 2017-4-21 08:55:47 | 只看该作者
本帖最后由 2011yaya2007777 于 2017-4-21 08:58 编辑
然而,我写的 mem64 汇编语言函数,竟然是无效的

现在可以使用了。4Gb以下内存我测试可以移动及填充。4Gb以上内存我没有测试环境,不知如何。请有条件的网友帮忙测试。

无效的原因源自:
  1. movl        %esp, %ebp                # clear upper 32-bit of %rbp
复制代码


估计 esp 由于以下语句改变了值:
  1. ljmp        $32, $ABS(1f)                # ljmp to enter 64-bit mode
  2.         .code64
  3. 1:
复制代码

现在修改为:
  1. addl $0, %ebp
复制代码

经测试,不加这句也能正常工作。

grldr.rar

160.79 KB, 下载次数: 2, 下载积分: 无忧币 -2

点评

同样的测试环境,引导ud中的内核成功,引导尾续在批处理后面的内核失败 如图 [attachimg]345235[/attachimg] [attachimg]345236[/attachimg]  详情 回复 发表于 2017-4-21 14:59
超级强悍!此问题终于被你俘虏!我没测试环境,但应该是解决了。以下是我的分析、思考。 mem64 函数的开头,是这样的: 可以看到,在 ebp 被赋值以后,又执行了三条 push 指令,这就隐含地改变了 esp 的值!这  详情 回复 发表于 2017-4-21 12:30
回复

使用道具 举报

34#
发表于 2017-4-21 12:30:16 | 只看该作者
2011yaya2007777 发表于 2017-4-21 08:55
现在可以使用了。4Gb以下内存我测试可以移动及填充。4Gb以上内存我没有测试环境,不知如何。请有条件的网 ...

超级强悍!此问题终于被你俘虏!我没测试环境,但应该是解决了。以下是我的分析、思考。

mem64 函数的开头,是这样的:
  1.         .code32

  2.         pushl        %ebp
  3.         movl        %esp, %ebp

  4.         #; +28        len
  5.         #; +20        src
  6.         #; +12        dest
  7.         #;  +8        func
  8.         #;  +4        EIP
  9.         #; ebp        EBP
  10.         #;  -4        ESI
  11.         #;  -8        EDI
  12.         #; -12        EBX

  13.         pushl        %esi
  14.         pushl        %edi
  15.         pushl        %ebx
复制代码


可以看到,在 ebp 被赋值以后,又执行了三条 push 指令,这就隐含地改变了 esp 的值!这是关键。我的失误就在此处——没能意识到 esp 已经改变了。

再看这个片段:

  1.         ljmp        $32, $ABS(1f)                # ljmp to enter 64-bit mode

  2.         .code64
  3. 1:

  4.         /* 28(%ebp) = len */
  5.         /* 20(%ebp) = src */
  6.         /* 12(%ebp) = dest */
  7.         /*  8(%ebp) = func */

  8.         movl        %esp, %ebp                # clear upper 32-bit of %rbp
复制代码


ljmp 属于跳转指令,而跳转指令是不可能改变 esp 的值的。正是前面的三条 push 指令,改变了 esp 的值。此时,我把错误的 esp 赋值给 ebp,是问题的症结。佩服 yaya 的调试功底,抓住了它。一般来说,调试别人的代码,那是困难的。yaya 功力不凡。

此处,rbp 的高 32 位,是应该被清除的。由于我已经脱离了 intel x86 体系,不再学习,所以,我现在不清楚 x86 的指令细节。确切地说,我不知道 addl $0, %ebp 能否清除 rbp 的高 32 位。

也可以试试 movl %ebp, %ebp,看看它能否清除 rbp 的高 32 位。应该查阅相关资料(查阅 intel 和 amd 的资料),了解这些细节。

程序运行需要万无一失。因此,该清除高32位的时候,就必须清除,不能让它有偶然出错的可能性。


回复

使用道具 举报

35#
发表于 2017-4-21 12:38:43 | 只看该作者
本帖最后由 2011yaya2007777 于 2017-4-21 14:37 编辑

ljmp        $32, $ABS(1f)
其中 $32 是什么意思?是段因子?

点评

看这段 “全局描述符表” 的定义: 其中的 /*32*/ 处,就是关于 64 位 long_mode 的代码段的描述。 当 ljmp $32, $ABS(1f) 这条指令执行的时候,CPU 仍旧处于 32 位保护模式。它执行的结果,就是实实在在地  详情 回复 发表于 2017-4-21 16:54
回复

使用道具 举报

36#
 楼主| 发表于 2017-4-21 14:59:39 | 只看该作者
2011yaya2007777 发表于 2017-4-21 08:55
现在可以使用了。4Gb以下内存我测试可以移动及填充。4Gb以上内存我没有测试环境,不知如何。请有条件的网 ...


同样的测试环境,引导ud中的内核成功,引导尾续在批处理后面的内核失败

如图




回复

使用道具 举报

37#
发表于 2017-4-21 15:13:38 | 只看该作者
本帖最后由 2011yaya2007777 于 2017-4-21 15:30 编辑

现在只是 mem64 函数可以使用了。引导尾续在批处理后面的内核没有改进。

经测试,movl %ebp, %ebp 或者 addl $0, %ebp 都可以清除 rbp 的高32位。
movl %ebp, %ebp 编译后少一个字节。

点评

搞清楚了就好。其实,还得测试 AMD 和 Intel 两个厂家的 CPU 才行,而不能只测试其中一家。 grub4dos 迄今为止的代码,全都同时适用于 AMD 和 Intel。就连进入 64 位以后的操作,也都有意避免了那些有差异的部分  详情 回复 发表于 2017-4-21 17:13
回复

使用道具 举报

38#
发表于 2017-4-21 16:54:01 | 只看该作者
本帖最后由 不点 于 2017-4-21 17:32 编辑
2011yaya2007777 发表于 2017-4-21 12:38
ljmp        $32, $ABS(1f)
其中 $32 是什么意思?是段因子?


看这段 “全局描述符表” 的定义:
  1. MyGDT:
  2. //gdt:
  3. /* 0*/        .word        0        /* NULL entry. Can be used at will. */
  4. gdtdesc:                /* 6 bytes used for gdt descriptor. */
  5.         .word        MyGDTEnd - MyGDT - 1        /* GDT limit */
  6.         /* The gdt linear base address will be adjusted by set_int13_handler,
  7.          * but not touched outside int13_handler. */
  8.         .long        ABS(MyGDT)                /* GDT linear address */

  9. /* 8*/        PM_DS16 = (. - MyGDT)        /* adjusted base = int13_handler */
  10.         .long        0x0000FFFF, 0x00009300        /* 16-bit data 64K limit */
  11. /*16*/        PM_DS32 = (. - MyGDT)
  12.         .long        0x0000FFFF, 0x00CF9300        /* 32-bit data 4GB limit */

  13.         /* The 16-bit code segment base will be adjusted by set_int13_handler,
  14.          * but not touched outside int13_handler. */
  15. /*24*/        PM_CS16 = (. - MyGDT)        /* adjusted base = int13_handler */
  16.         .long        0x0000FFFF, 0x00009B00        /* 16-bit code 64K limit */
  17. /*32*/        LM_CS64 = (. - MyGDT)
  18.         .long        0x0000FFFF, 0x00AF9B00        /* 64-bit code 4GB limit */

  19.         /* This gdt entry is not used by int13_handler, but used outside. */
  20. /*40*/        PM_CS32 = (. - MyGDT)
  21.         .long        0x0000FFFF, 0x00CF9B00        /* 32-bit code 4GB limit */
  22. MyGDTEnd:
复制代码


其中的 /*32*/ 处有 LM_CS64 = (. - MyGDT),就是关于 64 位 long_mode 的代码段的描述。此处的 32,就是“段选择器”(segment selector),它就是 CS、DS、ES、SS、FS、或 GS 之类的段寄存器可以取的值。或者说,此处 32 就是“段值”,不过,保护模式的段值,其含义不同于实模式下的段值。

当 ljmp  $32, $ABS(1f) 这条指令执行的时候,CPU 仍旧处于 32 位保护模式。它执行的结果,就是实实在在地切换到 64 位 long mode(长模式)。那么接下来就是 64 位的段了,不能是 32 位了,因此用 .code64 来通知编译器,接下来的汇编语言代码需要按照 64 位的指令格式来编译。

我猜,如果你将 $32 改成 $LM_CS64,可能也行(如果真行的话,那肯定更好,因为可读性更高了)。这些 PM_DS16, PM_CS16, PM_DS32,PM_CS32,LM_CS64 之类的定义,好像都是 karyonix 做的,我之所以没有采用,那是因为我的代码先写好了,karyonix 后来才增加的这几个定义(我先写的 64 位函数,karyonix 后来添加的 PAE 功能)。我对汇编语法并不熟悉,而 karyonix 比较专业。

再看结尾的片段:

  1.         /* XXX: Is this actually needed? */
  2.         ljmp        $40, $ABS(1f)                # ljmp to enter 32-bit protected mode
  3. 1:
  4.         xchgl        %eax, %ebx                # EAX=return value
  5.         popl        %ebx
  6.         popl        %edi
  7.         popl        %esi
  8.         popl        %ebp

  9.         ret
复制代码


这个 $40 不就是 $PM_CS32 嘛(见前面关于 PM_CS32 的定义),即 32 位保护模式代码段。那就是,实实在在地进入常规的 32 位模式。

不知道这是谁注释的:/* XXX: Is this actually needed? */ 有可能是我注释的,也有可能是 karyonix 注释的,也有可能是别的开发者注释的。反正我没什么记性了。

究竟需要不需要这个跳转,我也不能肯定。你也可以试试去掉(或者注释掉)这条 ljmp $40, $ABS(1f),看看有没有什么异常现象发生?

多执行这条指令,肯定是更安全一点(没什么坏处),但会浪费 CPU 执行这么一条指令的时间。       

如果确实能够证明去掉这条指令也行的话,那还是去掉了更好,毕竟少执行一条指令、少让 cpu 走弯路,那是更优化的。如果要证明的话,需要在 AMD 和 Intel 都验证通过,那才算是一个有效的证明。

回复

使用道具 举报

39#
发表于 2017-4-21 17:13:36 | 只看该作者
本帖最后由 不点 于 2017-4-21 17:19 编辑
2011yaya2007777 发表于 2017-4-21 15:13
现在只是 mem64 函数可以使用了。引导尾续在批处理后面的内核没有改进。

经测试,movl %ebp, %ebp 或者  ...


搞清楚了就好。其实,还得测试 AMD 和 Intel 两个厂家的 CPU 才行,而不能只测试其中一家。

grub4dos 迄今为止的代码,全都同时适用于 AMD 和 Intel。就连进入 64 位以后的操作,也都有意避免了那些有差异的部分,即,全都采用两个厂家同时都支持的 cpu 特性和指令,避免采用只有其中一家支持的 cpu 指令或特性。

另外,关于清除 rbp 的高 32 位,还可能有如下一些方法:

方法一:orl    %ebp, %ebp

方法二:andl   %ebp, %ebp

如果有时间、有兴趣,可以通过试验验证,来确定是否可行。

回复

使用道具 举报

40#
发表于 2017-4-21 17:24:00 来自手机 | 只看该作者
本帖最后由 2011yaya2007777 于 2017-4-21 17:39 编辑

明白了。谢谢。

movl  %ebp, %ebp
orl    %ebp, %ebp
andl   %ebp, %ebp
都是3字节指令。
回复

使用道具 举报

41#
发表于 2017-4-21 17:49:26 | 只看该作者
同样的测试环境,引导ud中的内核成功,引导尾续在批处理后面的内核失败

最好能给出调用尾续批处理的语句,便于分析是哪个函数引起内存冲突。
同时给一个简易的引导尾续批处理的 grldr。我会移植压缩菜单到新的 grldr.

点评

我是按C进入命令行后,直接执行批处理的,没有使用到grldr的菜单功能。 批处理内容如下,其中vmlinuz-4.10.4-1.el7.elrepo.x86_64,initramfs-4.10.4-1.el7.elrepo.x86_64.img是尾续在此批处理中: !BAT  详情 回复 发表于 2017-4-22 08:45
回复

使用道具 举报

42#
 楼主| 发表于 2017-4-22 08:45:12 | 只看该作者
2011yaya2007777 发表于 2017-4-21 17:49
最好能给出调用尾续批处理的语句,便于分析是哪个函数引起内存冲突。
同时给一个简易的引导尾续批处理的 ...


我是按C进入命令行后,直接执行批处理的,没有使用到grldr的菜单功能。



批处理内容如下,其中vmlinuz-4.10.4-1.el7.elrepo.x86_64,initramfs-4.10.4-1.el7.elrepo.x86_64.img是尾续在此批处理中:

!BAT

kernel  %~m0/vmlinuz-4.10.4-1.el7.elrepo.x86_64 root=UUID=aaa-bbb  ro quiet
initrd  %~m0/initramfs-4.10.4-1.el7.elrepo.x86_64.img
boot
回复

使用道具 举报

43#
发表于 2017-4-22 11:19:31 | 只看该作者
其实,还得测试 AMD 和 Intel 两个厂家的 CPU 才行

movl %ebp, %ebp
在 AMD 和 Intel 两个厂家的 CPU 测试,证明可以清除 rep 的高32位.

点评

好的,这就可以放心地使用 movl %ebp, %ebp 了。先前你证明了 add 指令也能够清除寄存器的高 32 位。而 or 和 and 指令,还没有证明过。如果以后有机会,最好都能证明一下,这样将来说不定啥时候就能用上了。甚至还  详情 回复 发表于 2017-4-24 00:27
现在mem64可用的话 优先用mem64启动大于4G的内存吧 顺便usb --init这几天频繁发生这个检测到USB设备但是没有进度条的问题  详情 回复 发表于 2017-4-23 21:07
回复

使用道具 举报

44#
发表于 2017-4-23 21:07:53 | 只看该作者
2011yaya2007777 发表于 2017-4-22 11:19
movl %ebp, %ebp
在 AMD 和 Intel 两个厂家的 CPU 测试,证明可以清除 rep 的高32位.

现在mem64可用的话 优先用mem64启动大于4G的内存吧
顺便usb --init这几天频繁发生这个检测到USB设备但是没有进度条的问题

点评

是的,yaya 居然把 mem64 救活了。这是我感觉很震动的一件事情,事先不敢有这样的奢望。我的代码我看过很多遍,一头雾水,找不到问题的根源在那里。当毛病找出来了之后,大家再看这毛病,似乎觉得很显然。但在找出毛  详情 回复 发表于 2017-4-24 01:01
回复

使用道具 举报

45#
发表于 2017-4-24 00:27:53 | 只看该作者
2011yaya2007777 发表于 2017-4-22 11:19
movl %ebp, %ebp
在 AMD 和 Intel 两个厂家的 CPU 测试,证明可以清除 rep 的高32位.

好的,这就可以放心地使用 movl %ebp, %ebp 了。先前你证明了 add 指令也能够清除寄存器的高 32 位。而 or 和 and 指令,还没有证明过。如果以后有机会,最好都能证明一下,这样将来说不定啥时候就能用上了。甚至还可以试试 test %ebp, %ebp 指令的效果。
回复

使用道具 举报

46#
发表于 2017-4-24 01:01:43 | 只看该作者
求道者 发表于 2017-4-23 21:07
现在mem64可用的话 优先用mem64启动大于4G的内存吧
顺便usb --init这几天频繁发生这个检测到USB设备但是 ...

是的,yaya 居然把 mem64 救活了。这是我感觉很震动的一件事情,事先不敢有这样的奢望。我的代码我看过很多遍,一头雾水,找不到问题的根源在那里。当毛病找出来了之后,大家再看这毛病,似乎觉得很显然。但在找出毛病之前,那可不是个简单的事。看代码——理解代码——集中火力——进攻!我想,至少是要耗费不少体力的,需要把自己锻造成子弹头,才能进攻。cpu 模式转换的代码,我自己现在都看不懂了。幸亏 yaya 进入了团队!

在当时, karyonix 可能早就发现 mem64 不能用了。所以,karyonix 编写了 PAE 的代码。真的感谢 karyonix,要不是他,grub4dos 根本就无法读写 4G 之上的内存。

yaya 可以研究一下 karyonix 的代码,看看代码是否支持 512G 的内存。

(1)如果 karyonix 的代码支持 512G 甚至完全不限制内存大小,那就继续采用 karyonix 的代码。
(2)如果 karyonix 的代码所支持的内存不足 512G,那就调整为默认采用 mem64 的代码。
(3)如果可能的话,yaya 也可以考虑进一步改进 mem64,让 mem64 支持无限大的内存(即,不限制内存的大小)。

点评

不能吧 AMD64弄出来的时候不是2^48吗? PAE不是最大64G吗?(linux)  详情 回复 发表于 2017-4-24 12:34
回复

使用道具 举报

47#
发表于 2017-4-24 12:34:33 | 只看该作者
本帖最后由 求道者 于 2017-4-24 15:00 编辑
不点 发表于 2017-4-24 01:01
是的,yaya 居然把 mem64 救活了。这是我感觉很震动的一件事情,事先不敢有这样的奢望。我的代码我看过很 ...


不能吧 AMD64弄出来的时候不是2^48吗?
PAE不是最大64G吗?(linux)

然后原理上讲 PAE的性能不是不可能比得上mem64吗?
回复

使用道具 举报

48#
发表于 2017-4-24 16:49:58 | 只看该作者
印象中,PAE 后来又有新的扩展,似乎 AMD 和 Intel 同时支持,可以处理 64 位内存,与 cpu 64 位模式的内存处理能力相同。

就是说,如果不考虑性能,则 PAE 与 64 位模式的处理能力相同。

64 位模式的字符串拷贝指令每次处理 8 个字节,比 PAE 的 4 字节要多一倍,因此速度会更快一点。

点评

e文维基上Win,linux,MAC 最大支持是64G物理内存…… 但是就算是DDR4 要插满64GB的内存也是有点虚吧(现在内存条贼J8贵) 有猛男试试现在grub4dos pae下最大支持多少内存吗?  详情 回复 发表于 2017-4-24 18:20
回复

使用道具 举报

49#
发表于 2017-4-24 18:20:42 | 只看该作者
本帖最后由 求道者 于 2017-4-24 18:38 编辑
不点 发表于 2017-4-24 16:49
印象中,PAE 后来又有新的扩展,似乎 AMD 和 Intel 同时支持,可以处理 64 位内存,与 cpu 64 位模式的内存 ...

好像3.几的内核还是2.几的内核就强制PAE了

e文维基上Win,linux,MAC 最大支持是64G物理内存……
但是就算是DDR4 要插满64GB的内存也是有点虚吧(现在内存条贼J8贵)

这么说的话mem64 优势贼大啊……
然后如果要测试的话 要先写个g4d下的脚本或者批处理吧

那么也是时候找个有256GB内存的猛男来测试一发了
回复

使用道具 举报

50#
发表于 2017-4-24 18:27:10 | 只看该作者
orl %ebp, %ebp
andl %ebp, %ebp
在 AMD 和 Intel 两个厂家的 CPU 测试,证明可以清除 rep 的高32位.

test %ebp, %ebp
在 AMD 和 Intel 两个厂家的 CPU 测试,证明不能清除 rep 的高32位.

PAE分页到底可以支持多大内存,从网上没有查到准确信息。很早的帖子说是64GB。

karyonix 的代码有点特殊。没有采用常规的连续分页方法,而是采用分段方法。
每次填写分页表,修改虚拟地址为固定的16MB及32MB,读8MB长度。特点是分页表只使用了12KB,速度相对慢些。不使用64位代码。

不点采用连续分页方法,读512GB使用了2MB多分页表。可以直接读任意地址及长度。可以适用于多任务操作系统,各任务在自己的分页内运行,互不干扰。

实际上,从32位代码跳转到在64位代码,可以使用 %ebp而不使用%rbp(其高32位为零),就不会出问题了。

点评

扩展后的 PAE 支持很大的内存。你可以写个测试程序,看看 karyonix 的代码能否读写 64G 以上的内存。我估计没问题。另外,如果 karyonix 的代码能够处理 64G 以上的内存,(根据你提供的分页方面的信息)那就能够处  详情 回复 发表于 2017-4-24 18:47
回复

使用道具 举报

51#
发表于 2017-4-24 18:47:53 | 只看该作者
2011yaya2007777 发表于 2017-4-24 18:27
orl %ebp, %ebp
andl %ebp, %ebp
在 AMD 和 Intel 两个厂家的 CPU 测试,证明可以清除 rep 的高32位.

扩展后的 PAE 支持很大的内存。你可以写个测试程序,看看 karyonix 的代码能否读写 64G 以上的内存。我估计没问题。另外,如果 karyonix 的代码能够处理 64G 以上的内存,(根据你提供的分页方面的信息)那就能够处理任意大的内存了。

如果普通用户不需要 1T 内存的话,目前的 mem64 也就够用了(可以处理 512G 内存)。特殊用户使用若干 T 的内存(估计是服务器虚拟主机的商家),那就让他自己修改 grub4dos 吧(假如他使用 grub4dos 的话;其实,这些商户没有一个是使用 grub4dos 的,至少我没发现;grub4dos 随着 BIOS 一起快要淘汰了,人家都不用)。

回复

使用道具 举报

52#
发表于 2017-4-24 19:42:22 来自手机 | 只看该作者
可惜我的内存只有2Gb

点评

不是你自己测试,你可以让网友测试。你只需要告诉测试步骤即可。  详情 回复 发表于 2017-4-24 19:45
回复

使用道具 举报

53#
发表于 2017-4-24 19:45:06 | 只看该作者
2011yaya2007777 发表于 2017-4-24 19:42
可惜我的内存只有2Gb

不是你自己测试,你可以让网友测试。你只需要告诉测试步骤即可。
回复

使用道具 举报

54#
发表于 2017-4-24 19:48:44 来自手机 | 只看该作者
哪位网友有大于64Gb的内存,帮忙试一试。

点评

本区的人估计都没有64G内存的机子 测试的话甚至可能要128GB内存 还有就是测试用的程序或者批处理  详情 回复 发表于 2017-4-24 20:26
回复

使用道具 举报

55#
发表于 2017-4-24 20:26:43 | 只看该作者
本帖最后由 求道者 于 2017-4-24 20:28 编辑
2011yaya2007777 发表于 2017-4-24 19:48
哪位网友有大于64Gb的内存,帮忙试一试。


本区的人估计都没有64G内存的机子
测试的话甚至可能要128GB内存

还有就是测试用的程序或者批处理
从U盘读取文件测试的话那就太慢了
最好是弄个内存测试的批处理或者小程序
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-4-19 22:24

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表