You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -523,13 +523,13 @@ This likely comes from the ifdef split at `init/main.c`:
523
523
524
524
/* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
525
525
#define pr_debug(fmt, ...) \
526
-
dynamic_pr_debug(fmt, ##__VA_ARGS__)
526
+
dynamic_pr_debug(fmt, ##__VA_ARGS__)
527
527
#elif defined(DEBUG)
528
528
#define pr_debug(fmt, ...) \
529
-
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
529
+
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
530
530
#else
531
531
#define pr_debug(fmt, ...) \
532
-
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
532
+
no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
533
533
#endif
534
534
....
535
535
@@ -2837,13 +2837,13 @@ dummy-irq: interrupt occurred on IRQ 1
2837
2837
However, this module is intended to fire only once as can be seen from its source:
2838
2838
2839
2839
....
2840
-
static int count = 0;
2840
+
static int count = 0;
2841
2841
2842
-
if (count == 0) {
2843
-
printk(KERN_INFO "dummy-irq: interrupt occurred on IRQ %d\n",
2844
-
irq);
2845
-
count++;
2846
-
}
2842
+
if (count == 0) {
2843
+
printk(KERN_INFO "dummy-irq: interrupt occurred on IRQ %d\n",
2844
+
irq);
2845
+
count++;
2846
+
}
2847
2847
....
2848
2848
2849
2849
and furthermore interrupt `1` and `12` happen immediately TODO why, were they somehow pending?
@@ -3494,7 +3494,7 @@ it makes the terminal go crazy, as if multiple processes are randomly eating up
3494
3494
* `/dev/ttyN` for the other graphic TTYs. Note that there are only 63 available ones, from `/dev/tty1` to `/dev/tty63` (`/dev/tty0` is the current one): link:https://superuser.com/questions/449781/why-is-there-so-many-linux-dev-tty[]. I think this is determined by:
3495
3495
+
3496
3496
....
3497
-
#define MAX_NR_CONSOLES63
3497
+
#define MAX_NR_CONSOLES63
3498
3498
....
3499
3499
+
3500
3500
in `linux/include/uapi/linux/vt.h`.
@@ -3745,11 +3745,200 @@ Studying them can teach you:
3745
3745
3746
3746
To get started, have a look at the "Hardware device drivers" section under link:kernel_module/README.adoc[], and try to run those modules, and then grep the QEMU source code.
3747
3747
3748
-
==== Mainline hardware models
3748
+
The hardware models can be either:
3749
3749
3750
-
This section documents hardware models present in the QEMU upstream.
3750
+
* present in the QEMU upstream
3751
+
* added in on link:https://github.com/cirosantilli/qemu[our fork of QEMU].
3752
+
+
3753
+
These have been explicitly designed to be educational rather than model real existing hardware.
3754
+
+
3755
+
But note that upstream [[edu]] device is also purely educational.
3756
+
3757
+
==== PCI
3758
+
3759
+
Only tested in x86.
3760
+
3761
+
===== pci_min
3762
+
3763
+
PCI driver for our minimal `pci_min.c` QEMU fork device:
* the QEMU `edu` educational device, which is a minimal educational in-tree PCI example
3808
+
* out `/pci.ko` kernel module, which exercises the `edu` hardware.
3809
+
+
3810
+
I've contacted the awesome original author author of `edu` link:https://github.com/jirislaby[Jiri Slaby], and he told there is no official kernel module example because this was created for a kernel module university course that he gives, and he didn't want to give away answers. link:https://github.com/cirosantilli/how-to-teach-efficiently[I don't agree with that philosophy], so students, cheat away with this repo and go make startups instead.
3811
+
3812
+
TODO exercise DMA on the kernel module. The `edu` hardware model has that feature:
* a more complete one from link:https://github.com/pciutils/pciutils[pciutils] which Buildroot has a package for. This is the one we enable by default.
3823
+
3824
+
`setpci` can read and write to PCI configuration registers.
3825
+
3826
+
Read is possible from Linux with:
3827
+
3828
+
....
3829
+
hexdump /sys/bus/pci/devices/0000:00:05.0/config
3830
+
....
3831
+
3832
+
and `/dev/mem` can of course do both reads and writes, but `setpci` provides nice human readable register names, e.g.:
3833
+
3834
+
....
3835
+
setpci --dumpregs
3836
+
....
3837
+
3838
+
then and then get the values with either bus or device id:
3839
+
3840
+
....
3841
+
setpci -s 0000:00:05.0 BASE_ADDRESS_0
3842
+
setpci -d 1234:11e9 BASE_ADDRESS_0
3843
+
....
3844
+
3845
+
Note however that `BASE_ADDRESS_0` also appears when you do:
3846
+
3847
+
....
3848
+
lspci -v
3849
+
....
3850
+
3851
+
Then you can try messing with that address with:
3852
+
3853
+
....
3854
+
devmem 0xfeb52000 w 0x12345678
3855
+
....
3856
+
3857
+
which for our <<pci_min>> device fires interrupts.
3858
+
3859
+
===== Introduction to PCI
3860
+
3861
+
The PCI standard is non-free, obviously like everything in low level: https://pcisig.com/specifications but Google gives several illegal PDF hits :-)
3862
+
3863
+
And of course, the best documentation available is: http://wiki.osdev.org/PCI
3864
+
3865
+
Like every other hardware, we could interact with PCI on x86 using only IO instructions and memory operations.
3866
+
3867
+
But PCI is a complex communication protocol that the Linux kernel implements beautifully for us, so let's use the kernel API.
TODO: broken. Was working before we moved `arm` from `-M versatilepb` to `-M virt` around af210a76711b7fa4554dcc2abd0ddacfc810dfd4. Either make it work on `-M virt` if that is possible, or document precisely how to make it work with `versatilepb`, or hopefully `vexpress` which is newer.
3755
3944
@@ -3775,11 +3964,13 @@ then test it out with:
3775
3964
/gpio.sh
3776
3965
....
3777
3966
3967
+
Source: link:rootfs_overlay/gpio.sh[].
3968
+
3778
3969
Buildroot's Linux tools package provides some GPIO CLI tools: `lsgpio`, `gpio-event-mon`, `gpio-hammer`, TODO document them here.
3779
3970
3780
3971
Those broke MIPS build in 2017-02: https://bugs.busybox.net/show_bug.cgi?id=10276 and so we force disable them in our MIPS build currently.
3781
3972
3782
-
===== LEDs
3973
+
==== LEDs
3783
3974
3784
3975
TODO: broken when `arm` moved to `-M virt`, same as <<gpio>>.
3785
3976
@@ -3823,15 +4014,9 @@ Relevant kernel files:
3823
4014
* `drivers/leds/led-class.c`
3824
4015
* `drivers/leds/leds-sysctl.c`
3825
4016
3826
-
==== Fork hardware models
3827
-
3828
-
This section documents hardware models added on link:https://github.com/cirosantilli/qemu[our fork of QEMU].
3829
-
3830
-
These have been explicitly designed to be educational rather than model real existing hardware.
3831
-
3832
-
===== platform_device
4017
+
==== platform_device
3833
4018
3834
-
This is an example of hardware coded into an ARM `-M versatilepb` SoC.
4019
+
Minimal platform device example coded into the `-M versatilepb` SoC of our QEMU fork.
3835
4020
3836
4021
Using this device now requires checking out to the branch:
3837
4022
@@ -3859,7 +4044,7 @@ Expected outcome after insmod:
3859
4044
* QEMU reports MMIO with printfs
3860
4045
* IRQs are generated and handled by this module, which logs to dmesg
3861
4046
3862
-
Also without insmodding this module, try:
4047
+
Also without insmoding this module, try:
3863
4048
3864
4049
....
3865
4050
devmem 0x101e9000 w 0x12345678
@@ -6247,7 +6432,9 @@ Runnable stuff:
6247
6432
6248
6433
Theory:
6249
6434
6250
-
* http://nairobi-embedded.org you will fall here a lot when the hard Google queries start popping. They have covered everything we do here basically, but with a more manual approach, while this repo automates everything.
6435
+
* http://nairobi-embedded.org you will fall here a lot when you start popping the hard QEMU Google queries. They have covered everything we do here basically, but with a more manual approach, while this repo automates everything.
6436
+
+
6437
+
I couldn't find the markup source code for the tutorials, and as a result when the domain went down in May 2018, you have to use http://web.archive.org/ to see the pages...
0 commit comments