Skip to content

feat: Added the "from_pfn" in PhysFrame#593

Merged
Freax13 merged 11 commits into
rust-osdev:masterfrom
zhangxuan2011:master
Jul 10, 2026
Merged

feat: Added the "from_pfn" in PhysFrame#593
Freax13 merged 11 commits into
rust-osdev:masterfrom
zhangxuan2011:master

Conversation

@zhangxuan2011

@zhangxuan2011 zhangxuan2011 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Preface

Sometimes, I know its PFN number (espeically in frame allocator), but I have to convert it again and again - That's annoying, and may cause performance problem.

So, the from_pfn is one way to solve this problem - No need to convert, write that shitty long code!

Changelog

  • Added a fn called from_pfn that was in PhysFrame

@zhangxuan2011 zhangxuan2011 changed the title fix: Fixed the Star register's selector checking feat: Added the "from_pfn" in PhysFrame Jul 4, 2026

@Freax13 Freax13 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution!

Yeah, if one is primarily working with PFNs, the conversions can become a bit tedious. Also having written a decent amount of code centered around PFNs recently, I welcome this addition.

}
}

/// Returns the frame by a physical frame number.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a panic section to the doc comment.

Let's also mention that the conversion takes the page size into consideration. For example, converting pfn 512 with page size 4K will not return the same address compared to converting pfn 512 with page size 2M.
The way I usually see it used, pfn is based around the smallest page size on the system. For example, AFAIK, on x86-64, Linux always computes the pfn with a 4K page size even though the hardware also supports other page sizes. Your proposal is not to do that and instead consider the page size. I'm fine with that, I just want to make sure that we communicate that to our users.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We just use pfn * page size, the panick seems not needed...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair.

Let's still add a section explaining how we interpret PFNs with respect to different page sizes though.

Comment thread src/structures/paging/frame.rs Outdated
Comment thread src/registers/model_specific.rs Outdated
Comment on lines +462 to +463
/// Also, if you want to return from syscall, you
/// shall use "sysretq" instead of "syscall".

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean 'Also, if you want to return from syscall, you shall use "sysretq" instead of "sysret"'?

Suggested change
/// Also, if you want to return from syscall, you
/// shall use "sysretq" instead of "syscall".
/// To return to 64-bit user space code, use `sysretq`.
/// To return to 32-bit user space code, use `sysret`.

@zhangxuan2011 zhangxuan2011 Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. (my brain boomed). As the issue that you have replied, i use "sysret" wrongly (correct one is "sysretq"). To make other user notice this, i added this comment.

This crate is for "x86_64" architectures, so i don't think we shall mention "use sysret if use 32-bit" (otherwise you should delete that "-16")

*sorry my phone has no backtick and my eng is not well

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

x86_64 has a "compatibility mode" which can be used to execute 32-bit code. I would say it's reasonable that people might try to implement that (I have in the past), so we might as well give them this hint about the right sysret instruction to use.

image

Comment thread src/structures/paging/frame.rs
Comment thread src/structures/paging/frame.rs
@zhangxuan2011

zhangxuan2011 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for your contribution!

Yeah, if one is primarily working with PFNs, the conversions can become a bit tedious. Also having written a decent amount of code centered around PFNs recently, I welcome this addition.

@Freax13 ,

I just checked your suggestions and did some improvements.

However, it's 11pm for me currently. As a junior high student, I just finish my zhongkao (an important exam), and i can have rest, so that i can continually do more updates tomorrow morning.

All in all, good night 🌙

@zhangxuan2011

zhangxuan2011 commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Seems I have an good idea: Perhaps we can define a enum, PageError, which contains all of the error that might caused, so that i don't need to add more struct definitions about some errors.

@zhangxuan2011

Copy link
Copy Markdown
Contributor Author

@Freax13

To be honest i have waited for you for a long time... Oh, god, That's freaking long😨😪

@Freax13

Freax13 commented Jul 6, 2026

Copy link
Copy Markdown
Member

@Freax13

To be honest i have waited for you for a long time... Oh, god, That's freaking long😨😪

It's been two days. that's really not that long, lol. You need to be more patient :). Most of have busy lives. I'll take a look now.

Comment thread src/structures/paging/frame.rs Outdated
#[inline]
#[rustversion::attr(since(1.61), const)]
pub fn from_start_address(address: PhysAddr) -> Result<Self, AddressNotAligned> {
pub fn from_start_address(address: PhysAddr) -> Result<Self, PageError> {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this would be a breaking change. Let's not do that.

Let's use different error types for from_start_address and from_pfn instead of a single common error type.

@zhangxuan2011 zhangxuan2011 Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I will revert to original one then

So, you mean I shall define another struct that is an error type as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this would be a breaking change. Let's not do that.

Let's use different error types for from_start_address and from_pfn instead of a single common error type.

Refactored, currently using another error type, PhysicalAddressNotValid, which is exist here.

Comment thread src/structures/paging/frame.rs Outdated
Comment thread src/structures/paging/frame.rs Outdated
#[rustversion::attr(since(1.61), const)]
pub fn from_pfn(pfn: u64) -> Result<Self, PageError> {
// Check: is the PFN overflowed?
if pfn > (u64::MAX / S::SIZE) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides checking for an integer overflow, we also need to make sure that the the result is a valid physical address. Let's not reimplement that part here and just call PhysAddr::try_new instead. Once we have a PhysAddr we can use that to directly construct Self without going through Self::from_pfn_unchecked.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I even did not notice that fn... But okay, i will try.

}
}

/// Returns the frame by a physical frame number.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair.

Let's still add a section explaining how we interpret PFNs with respect to different page sizes though.

@zhangxuan2011

zhangxuan2011 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@Freax13

To be honest i have waited for you for a long time... Oh, god, That's freaking long😨😪

It's been two days. that's really not that long, lol. You need to be more patient :). Most of have busy lives. I'll take a look now.

Okay, I was too tired because it is very late.

I'm sorry about this breaking change. Because it is my developing habit. I will reverse it later and learn more About the APIs.

But, I am outside and go back in 1d. Once I backed, I will do the suggested change immediately

@zhangxuan2011

Copy link
Copy Markdown
Contributor Author

@Freax13,

Just modified the code as your requirements, see it again :)

@Freax13 Freax13 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a heads up. I have some local changes to improve the documentation. I'll push those before merging this PR.

Comment thread src/structures/paging/frame.rs Outdated
@zhangxuan2011

Copy link
Copy Markdown
Contributor Author

Just a heads up. I have some local changes to improve the documentation. I'll push those before merging this PR.

Okay, I will sync once you push that.

@zhangxuan2011

zhangxuan2011 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

@Freax13,

I am backed and resolved that problem by using checked_mul.

Also, I improved the docs: If the multiplication caused overflow, an u64 cannot contain that, so store PFN in PhysAddrNotValid is the only solution (at least i can think about that, in order to avoid breaking changes).

Now look look again if you're free :)

btw, this is my first PR in my life, too young, im only 15, lol

Comment thread src/structures/paging/frame.rs Outdated
@zhangxuan2011

Copy link
Copy Markdown
Contributor Author

Okay then, I added a new error type InvalidPfn which contains the invalid PFN. @Freax13

@Freax13

Freax13 commented Jul 10, 2026

Copy link
Copy Markdown
Member

I'd say this is ready. Let's wait for #595 to be merged first, so that CI stops complaining about the recent nightly breakage.

zhangxuan2011 and others added 10 commits July 10, 2026 19:24
- Added a fn in `PhysFrame` so that we can create a frame easily (instead of converting)
- Use `checked_mul` to ensure that the mul operation won't cause panick
 - Updated docs about `PhysAddrNotValid` to make it much clear

rust-osdev#523
- Slightly reword things
- Add more examples
InvalidPfn is more in line with the existing error names
(VirtAddrNotValid, PhysAddrNotValid).

Also move it down in the file. `PhysFrame` is arguably more important,
so let's make sure it's at the top of the file.
@Freax13 Freax13 force-pushed the master branch 3 times, most recently from a7ea828 to 4fcf6a6 Compare July 10, 2026 17:37

@Freax13 Freax13 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks! :shipit:

btw, this is my first PR in my life

Great job on your first PR! Keep up the good work!

@Freax13 Freax13 merged commit 98d498b into rust-osdev:master Jul 10, 2026
12 of 13 checks passed
@zhangxuan2011

Copy link
Copy Markdown
Contributor Author

LGTM, thanks! :shipit:

btw, this is my first PR in my life

Great job on your first PR! Keep up the good work!

You're welcome! I will do more better work in the future😄

I will keep up making good things, as ur wish 😎

@Freax13 Freax13 mentioned this pull request Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants