Skip to content

Simple Rust driver that touches real hardware: PR 1/5 #270

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 18, 2021

Conversation

TheSven73
Copy link
Collaborator

Simple Rust driver that touches real h/w: step 1 of 5

@alex and @ojeda suggested that #254 should be split into smaller PRs, so they can be reviewed and merged individually.

Roadmap:

  • platform_device (this PR)
  • probe
  • DrvData
  • regmap/iomem
  • finally the actual hwrng driver

Copy link
Member

@ojeda ojeda left a comment

Choose a reason for hiding this comment

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

Looks good -- @wedsonaf could you take a second look please?

Copy link

@wedsonaf wedsonaf left a comment

Choose a reason for hiding this comment

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

Looks good -- @wedsonaf could you take a second look please?

LGTM too.

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2017 Stefan Wahren <stefan.wahren@i2se.com>
*/

Choose a reason for hiding this comment

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

Perhaps add a comment here explaining that this is copied from from the version without -rust and highlighting the difference (bcm2835-rng-rust)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@wedsonaf the devicetrees are forked temporarily, until the platdev can bind to a devicetree compatible string. Which will be in PR 2/5.

In other words, these forked devicetrees will be "history" in the next PR. I'm sorry that I didn't indicate this anywhere !

In that light, do you still feel it's worth writing/reviewing the devicetree comments? If so I'll add them, no problem.

Choose a reason for hiding this comment

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

Thanks for the clarification. No need for additional comments.

license: b"GPL v2",
}

struct RngModule {

Choose a reason for hiding this comment

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

For drivers that just register support for a platform device in their init function, we should provide a macro similar to C's module_platform_driver. I did that for miscdev in https://github.com/Rust-for-Linux/linux/blob/rust/rust/module.rs#L806.

This could perhaps be done in a different PR but I think it's important for us to provide this so that we reduce boilerplate code in Rust drivers, especially because their C counterparts already have such macros.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Very good point !

Copy link
Collaborator Author

@TheSven73 TheSven73 May 18, 2021

Choose a reason for hiding this comment

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

Can we defer this to the PR that adds probe()? We don't have a Trait object yet to pass to the macro.

Choose a reason for hiding this comment

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

Yes, absolutely.

Sven Van Asbroeck added 3 commits May 18, 2021 09:20
Implements the bare minimum required to register a platform device
with the kernel. Registered devices won't actually be able to do
anything.

Registered platform devices will be visible in sysfs, under
/sys/bus/platform/{devices,drivers}/

Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
Implements the bare minimum for a platform driver to register
itself with the core. It won't be able to do anything, except
show up in sysfs.

Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
Provide a forked `defconfig` and devicetree, so the platform device
core and driver can be easily tested on QEMU, or a Raspberri Pi Zero.

Although called "bcm2835-rng-rust", this is not a functional hwrng driver,
just a bare minimum platform_device. All it will do is log a message to dmesg:
[ ] rust_kernel: Rust platform_device probed

and show up in sysfs:
/sys/bus/platform/driver/bcm2835-rng-rust/ (the driver)
/sys/bus/platform/devices/bcm2835-rng-rust/ (the device)

How to run on QEMU
==================
Download a Raspbian image. I used `2021-03-04-raspios-buster-armhf-lite.img`.
It will consist of two partitions. Discover their offsets using:
```sh
$ fdisk -l 2021-03-04-raspios-buster-armhf-lite.img
Device                                    Boot  Start     End Sectors  Size Id Type
2021-03-04-raspios-buster-armhf-lite.img1        8192  532479  524288  256M  c W95 FAT32 (LBA)
2021-03-04-raspios-buster-armhf-lite.img2      532480 3645439 3112960  1.5G 83 Linux
```

Mount the second partition on your PC: (note how the offset is multiplied by 512)
```sh
$ mount -o loop,offset=$((512*532480)) 2021-03-04-raspios-buster-armhf-lite.img /mnt
Comment out everything in /etc/ld.so.preload - otherwise the Raspbian rootfs cannot support
a mainline kernel:
$ vi /etc/ld.so.preload # comment everything out
$ umount /mnt
```

Build the kernel for arm 32-bit:
```sh
$ make bcm2835_rust_defconfig # defconfig forked so `bcm2835-rng-rust` binds to our driver
$ make zImage dtbs modules
```

Start QEMU:
```sh
  # to boot mainline, make sure that /etc/ld.so.preload is commented out
  # in the Raspbian image.
qemu-system-arm \
	-M raspi2 \
	-append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 dwc_otg.lpm_enable=0 root=/dev/mmcblk0p2 rootwait" \
	-cpu arm1176 \
	-dtb bcm2836-rpi-2-b-rust.dts \
	-hda ./2021-03-04-raspios-buster-armhf-lite.img \
	-kernel zImage \
	-m 1G \
	-smp 4 \
	-nographic \
;

How to run on a Raspberry Pi Zero(W)
====================================
Follow the instructions for QEMU above. Deploy the Raspbian image to SD card.
Copy zImage and bcm2835-rpi-zero-w-rust.dtb to Raspbian's first (boot) partition:
```
		zImage                       -> boot partition: kernel.img
		bcm2835-rpi-zero-w-rust.dtb  -> boot partition: bcm2708-rpi-0-w.dtb
```
If you'd like wifi to keep working, also copy the kernel modules you built to
Raspbian's second partition:
```sh
$ make modules_install INSTALL_MOD_PATH=<somewhere>
$ cp -rfa <somewhere> <Raspbian Partition> # should end up in /lib/modules/5.12.0-rc4+/
```

Signed-off-by: Sven Van Asbroeck <thesven73@gmail.com>
@TheSven73 TheSven73 force-pushed the rust-for-linux-pdev-pr1 branch from 1aac70e to 9551aa5 Compare May 18, 2021 13:31
@TheSven73
Copy link
Collaborator Author

v1 -> v2

ojeda:

  • comment improvements

v3 to follow depending on wedsonaf's feedback.

@ojeda ojeda merged commit 8687614 into Rust-for-Linux:rust May 18, 2021
@TheSven73 TheSven73 deleted the rust-for-linux-pdev-pr1 branch May 18, 2021 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants