首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GRUB为Multiboot2提供了"error: unsupported : 0xc“

GRUB为Multiboot2提供了"error: unsupported : 0xc“
EN

Stack Overflow用户
提问于 2018-03-15 23:04:36
回答 1查看 584关注 0票数 2

我试图为兼容Multiboot2的内核的头使用以下代码,但是当我在grub中尝试multiboot2命令时,它给出了以下错误消息:

错误:不支持的标记: 0xc

我的Multiboot2头定义为:

代码语言:javascript
复制
section .multiboot align=4096
mbhead: dd 0xe85250d6
        dd 0
        dd 76
        dd 0 - 76 - 0xe85250d6                  ; TODO the linker and assembler get angry if we calculate this with symbols, we need to do this by hand
        dw 1                                    ; multiboot information request
        dw 0
        dd 20
        dd 1
        dd 2
        dd 6
        dw 4                                    ; console flags
        dw 0
        dd 12
        dd 0x3
        dw 5                                    ; framebuffer settings
        dw 1
        dd 12
        dd 80
        dd 25
        dd 0
        dw 0                                    ; last tag
        dw 0
        dd 8

我的项目储存库提供完整的源代码。我用make test_longmode.iso生成一个ISO。我用QEMU测试。

导致标记错误的问题是什么,我如何修复它?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-17 21:49:20

主要问题

GRUB错误:

错误:不支持的标记: 0xc

是因为您没有按照Multiboot2规范对每个标记的8个字节

3.1.3一般标签结构 标记构成结构的缓冲区,在必要时互相填充以使每个标记以8字节对齐的地址开始。标签以‘0’和大小‘8’的标记结束。每个结构都有以下格式

为了方便地解决这个问题,您可以在每个标记之前使用align 8,并且可以让汇编程序处理对齐。这种对齐不会计算到标记的长度中。

可以更好地计算校验和,这样就不会让NASM使用截断来引起警告。这一行:

代码语言:javascript
复制
dd 0 - 76 - 0xe85250d6

本可以更好地表述为:

代码语言:javascript
复制
dd 0x100000000 - 76 - 0xe85250d6

代码可读性

我认为这个代码片段的第一件事是它是多么不可读。引起我注意的是这样的评论:

链接器和汇编程序如果用符号来计算,我们需要手工计算。

似乎您已经手工计算了值,因为您在尝试以其他方式进行计算时遇到了问题。在这里帮助您的NASM指令是EQU指令

3.2.4 EQU:定义常量 EQU将符号定义为给定的常量值:当使用EQU时,源行必须包含一个标签。EQU的作用是将给定的标签名定义为其(仅)操作数的值。此定义是绝对的,以后不能更改。所以,比如说, 消息db 'hello,world‘msglen $-message 将msglen定义为常量12,以后可能不会重新定义msglen。这也不是预处理器的定义: msglen的值只计算一次,在定义点使用$的值(参见$ 3.5节的解释),而不是在引用它的地方被计算,并在参照点使用$的值。

通过使用EQU,我们可以提高代码的可读性。

其次,您可以向每个标记的开始和结束添加标签,然后让汇编程序为您计算每个标记的长度。长度是每个标签的结束标签和开始标签之间的区别。

改进代码

上述更改的NASM程序集代码可以如下所示:

代码语言:javascript
复制
MB2_ARCH  EQU 0                                 ; 0 = x86/x86-64
MB2_LEN   EQU (mbend-mbhead)
MB2_MAGIC EQU 0xe85250d6

section .multiboot align=4096
mbhead:
        dd MB2_MAGIC                            ; Multiboot2 magic number
        dd MB2_ARCH                             ; Architecture
        dd MB2_LEN                              ; Multiboot header length
        dd 0x100000000 - MB2_LEN - MB2_ARCH - MB2_MAGIC
                                                ; Checksum

mb2_tag_info_start:
        dw 1                                    ; multiboot information request
        dw 0
        dd mb2_tag_info_end - mb2_tag_info_start
        dd 1
        dd 2
        dd 6
mb2_tag_info_end:

        align 8
mb2_tag_console_start:
        dw 4                                    ; console flags
        dw 0
        dd mb2_tag_console_end - mb2_tag_console_start
        dd 0x3
mb2_tag_console_end:

        align 8
mb2_tag_fb_start:
        dw 5                                    ; framebuffer settings
        dw 1
        dd mb2_tag_fb_end - mb2_tag_fb_start
        dd 80
        dd 25
        dd 0
mb2_tag_fb_end:

        align 8
mb2_tag_end_start:
        dw 0                                    ; last tag
        dw 0
        dd mb2_tag_end_end - mb2_tag_end_start
mb2_tag_end_end:

mbend:

这一点可以进一步改进,但与原始代码片段相比,这似乎更易读,也更具有自文档性。如果更改标记或标头的大小,则所有长度都将为您计算。如果大小发生变化,align 8指令将为您计算正确的对齐方式。这使得代码更易于维护。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49310653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档