-
Notifications
You must be signed in to change notification settings - Fork 0
Long mode #8
base: master
Are you sure you want to change the base?
Conversation
@homunkulus try |
💔 Test failed - status-travis |
accessed via pure Rust, AFAIK. For that reason, this part is written in inline assembly. | ||
- Caveat: Because we are telling `rustc` to use a 32-bit target, `rustc` always emit 32-bit | ||
instructions and we can't actually use 64-bit instructions/registers in the section of the program | ||
where the CPU is already in long mode. Yikes, I'll have to think about how to solve this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be solved by splitting this crate in two: one crates that does the booting process and is compiled for a 32-bit target and the other crate that exposes the long_mode_start
symbol and is compiled for a 64-bit target. The issue is that I think the compiler won't link together crates compiled for different types (imagine mixing a crate compiled for ARM with a crate compiled for x86). If that's the case we could compiled the boot
crate as a staticlib and link that staticlib into the long
crate. That should bypass the "same target" check.
All this is speculation from my part. I don't know if it will actually work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds about right to me.
the target changed
@homunkulus try |
// extra selector | ||
asm!("mov es, ax" :::: "intel"); | ||
|
||
// FIXME Is this the right syntax for a far jump? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought on this part?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so? Not 100% sure though.
💔 Test failed - status-travis |
it fails to link for some reason :-/
@homunkulus try |
☀️ Test successful - status-travis |
accessed via pure Rust, AFAIK. For that reason, this part is written in inline assembly. | ||
- Caveat: Because we are telling `rustc` to use a 32-bit target, `rustc` always emit 32-bit | ||
instructions and we can't actually use 64-bit instructions/registers in the section of the program | ||
where the CPU is already in long mode. Yikes, I'll have to think about how to solve this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds about right to me.
|
||
// move page table address to cr3 | ||
asm!("mov eax, p4_table | ||
mov cr3, eax" :::: "intel"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://crates.io/crates/x86 would be neat to use here, but it also only supports 64-bit for now, IIRC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They added support for 32 bit lately, but I'm not sure if it's already on crates.io…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0.8 on crates.io has the bulk of this.
// extra selector | ||
asm!("mov es, ax" :::: "intel"); | ||
|
||
// FIXME Is this the right syntax for a far jump? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so? Not 100% sure though.
A thought that I've been rolling around in my head, but haven't tried to implement yet. What about having a |
@steveklabnik That would have to shell out to an external assembler like |
Yeah, it would still require shelling out. It's not a perfect solution, but Even worse idea: one huge "inline asm" Rust block? lololol On Fri, Sep 23, 2016 at 2:48 PM, Jorge Aparicio [email protected]
|
Another approach that could work is have a single x86_64 target, split the boot code into its own crate, compile that I tried this but I couldn't figure a combination of |
👍. I have actually thought about this! I think it requires global asm instead of inline though (I haven't actually tried) |
I bet you could configure start? Hm. On Fri, Sep 23, 2016 at 2:54 PM, Jorge Aparicio [email protected]
|
A naked extern function with |
I'm guessing a similar situation arises when using arm's dynamic endianness to mix ABIs. To me this is proof that the problem is general enough that Cargo should get a proper solution for this. I do believe baking exact targets into packages is bad, so I guess the solution would be "chameleon targets" that change their definition based on the crate being built? On the other hand two such crates may share the same dependency in which case it is should be configured (flags) + compiled differently, so naive per-crate target shape-shifting won't work. |
I implemented the "build using nasm in a build script" over here: intermezzOS/kernel#63 That nasty build script can be made much nicer with the gcc crate, but then you have to use a syntax gcc understands, which isn't nasm. and i haven't taken the time to port it over yet. I still find #8 (comment) very interesting |
So, I'm giving that idea a try. I got a
So, something must be slightly off. But I think this might work? |
So, @mkpankov pointed out this:
It's going to know that it's a 32-bit ELF file, and not link it in. Given this,
Seems like it's probably the correct approach. |
Regarding the "can inline asm do BITS 32", I got a tweet that says yes: https://twitter.com/rpjohnst/status/780474494066450433 |
@steveklabnik did the libboot.a approach work in the end? I tried the two targets, x86 and x86_64, approach and hitted the same problem: the libboot.a (a rust crate compiled as a staticlib) compiled for x86 was a 32-bit elf/library and got ignored by the linker when I tried to link it to the x86_64
Yeah, but LLVM isn't cooperating :-/. |
I couldn't get it to work, due to the 64/32 issue. |
One other idea I had: if we converted into intel syntax rather than nasm-specific, we could just use the gcc crate to build it. rust already uses gcc for the linker, so that would eliminate one more dep... |
p4_table[0] = &p3_table[0] as *const _ as usize as u64 | 0b11; | ||
p3_table[0] = &p2_table[0] as *const _ as usize as u64 | 0b11; | ||
|
||
for (entry, i) in p2_table.iter_mut().zip(0..) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.enumerate()
rather than zip(0
?
cc @steveklabnik @phil-opp