According to OSDev, to locate the Port I/O address of ACPI timer, we first open FADT table and check entries PM Timer Block Length and PM Timer Block Address. In my computer, PM Timer Block Address gives address 0x408 and it works correctly.
However, in the implementation of OVMF, the I/O address of ACPI timer is calculated as PMBA + 0x8. I search the internet and found no information about this way of calculation.
I'm wondering are both methods to decide ACPI timer address correct? If both are correct, where can I find definitions of information about the second way of calculation?
Firmware (e.g. OVMF) uses chipset specific methods to determine the IO port of the ACPI timer; and then constructs the FADT and fills it in so that an OS doesn't need to be chipset specific.
If you don't want to use FADT, then you can write a chipset specific driver for each chipset. For some cases (open source emulators) this may be relatively easy, and for some cases (proprietary and undocumented real hardware) this will be almost impossible.
Related
For a work project, I have to read a bunch of holding registers from an IFM CR1203 PLC that is programmed using CODESYS 3.5.
The PLC will be running a slave instance and the device reading the holding registers will be a PC running a custom application programmed in Javascript to be a client. I have already programmed MODBUS TCP/IP functions for the custom application that is tested and works (For a previous project I had to do the same for a different PLC programmed using a different platform).
My current issue is that I need the raw memory address of the first holding register to do this, but I can't find it on the CODESYS IDE. CODESYS uses an addressing system that makes it easy for different CODESYS-based devices to communicate. Here is a link that explains how it works: CODESYS MODBUS register location guide
The only thing that looks like it can work is from the link above:
<memory position> : <number> ( .<number> )* // Depends on the target system
But I don't fully understand what all that means.
I also can't find any documentation on the PLC or CODESYS that explains this topic in enough detail. Here is a snippet of dummy code used for testing that shows the CODESYS addresses:
Can someone please explain to me how I can convert the value %IW0 to a raw memory address, for example, 0xFFFF?
I use Machine Expert (Codesys 3.5.16) and in their documentation says:
The I/Os are mapped to Modbus registers from the master perspective as follows:
%IWs are mapped from register 0 to n-1 and are R/W (n = Holding register quantity, each %IW register is 2 bytes).
%QWs are mapped from register n to n+m -1 and are read only (m = Input registers quantity, each %QW register is 2 bytes).
So in your example they should be address 0 and 1.
How can I load OS image from floppy disk to memory without BIOS Service while booting my PC?
The only way I’ve used is calling int13h in real mode .
I got to know that I need to handle with ‘Disk controller’ .
Do I need to write kinda ‘Device driver’ in [BIT 16] real mode and is it possible?
As 0andriy has commented, you will have to communicate with the floppy controller directly, bypassing the BIOS. (Which BTW, why do you want to do such a thing? The BIOS was made specifically so you don't have to do this. Is it solely because you want to, maybe to learn how to program the FDC? I'm okay with that.)
The FDC (Floppy Disk Controller) is of the ISA (Industry Standard Architecture) era, back when I/O ports were hard coded to specific addresses. The FDC came in many variants, but most followed a standard rule. The original 756 was a common FDC, with later (still really old to today's standards) controllers following the 82077AA variant.
These controllers had twelve (12) registers using eight (8) I/O Byte addresses, Base + 00h to Base + 07h. (Please note that a single I/O address can be two registers if one is a read and one is a write.) You read and write to these registers to instruct the FDC to do things, such as start the motor for drive 1. (For fun: Did you know that the FDC was originally capable of handling four drives?)
This isn't to difficult to do, but now you have to have some way for the ISA bus to communicate with the FDC and the main memory. In comes the DMA (Direct Memory Access). Now you have to also program the DMA to make the transfers.
Here is the catch. If you don't have all of the FDC and DMA code within the first 512 bytes of the floppy, the 512 bytes the BIOS loaded for you already, there is no way to load the remaining sectors. For example, you can't have your DMA code in the second sector of your boot code expecting to call it, since you have to use that DMA to load that sector in the first place. All FDC and DMA code, at least a minimum read service, must be in the first sector of the disk. This is quite difficult to do, reliably.
I am not saying it is impossible to do, I am just saying it is improbable. For one thing, if you can do it (reliably) in 512 bytes, I would like to see it. It might be a fun experiment. Anyway, do a search for FDC, DMA, etc., things I wrote of here. There are many examples on the web. If you wish to read a book about it, I wrote such a book a while back with all the juicy details.
I am looking to have the processor read from I2C and store the data in DDR in an embedded system. As I have been looking at solutions, I have been introduced to Linux device drivers as well as the GNU C Library. It seems like for many operations you can perform with the basic Linux drivers you can also perform with basic glibc system calls. I am somewhat confused when one should be used over the other. Both interfaces can be accessed from the user space.
When should I use a kernel driver to access a device like I2C or USB and when should I use the GNU C Library system functions?
The GNU C Library forwards function calls such as read, write, ioctl directly to the kernel. These functions are just very thin wrappers around the system calls. You could call the kernel all by yourself using inline assembly, but that is rarely helpful. So in this sense, all interactions with the kernel driver will go through these glibc functions.
If you have questions about specific interfaces and their trade-offs, you need to name them explicitly.
In ARM:
Privilege states are built into the processor and are changed via assembly commands. A memory protection unit, a part of the chip, is configured to disallow access to arbitrary ranges of memory depending on the privilege status.
In the case of the Linux kernel, ALL physical memory is privileged- memory addresses in userspace are virtual (fake) addresses, translated to real addresses once in privileged mode.
So, to access a privileged memory range, the mechanics are like a function call- you set the parameters indicating what you want, and then make a ('SVC')- an interrupt function which removes control of the program from userspace, gives it to the kernel. The kernel looks at your parameters and does what you need.
The standard library basically makes that whole process easier.
Drivers create interfaces to physical memory addresses and provide an API through the SVC call and whatever 'arguments' it's passed.
If physical memory is not reserved by a driver, the kernel generally won't allow anyone to access it.
Accessing physical memory you're not privileged to will cause a "bus error".
BTW: You can use a driver like UIO to put physical memory into userspace.
I am using fsl_elbc_nand [1] driver for my NAND device. This is a NAND IC connected to the LocalBus Controller (eLBC), part of SoC. I have also ethernet MAC (ASIX) connected to the same ELBC bus. The nand driver works as follows:
setups operation via MMIO
wait_event_timeout for an interrupt from elbc informing that the operation (read/write/whatever) has finished
process result
Problem is, during wait_event_timeout() (which can take up to 0.5s) ASIX cannot talk with eLBC. But it is in three ways:
interrupt, when incoming frames
start_xmit from softirq for outgoing frames
mdio from ethtool ioctl (i.e. link status every second)
I can disable particular irq, resolving first case. I can return NETDEV_TX_BUSY by start_xmit, so I will resolve second case. But I cannot find any way to resolve third case. I tried spinlocks, mutexes, but I've learnt, that spinlocks are prohibited, when sleeping.
Is there some way to achieve proper locking? Maybe I should replace wait_event_timeout() to something else?
[1] http://lxr.free-electrons.com/source/drivers/mtd/nand/fsl_elbc_nand.c?v=3.10
I got a strange text by 'catting' the /proc/ioports file of my PC linux,
0000-001f : dma1
0020-003f : pic1
0040-005f : timer
0060-006f : keyboard
0070-007f : rtc0
...
What I dont understand is the anterior part of each entry, look at the first entry for example, does it mean 31(0x1f in hex) ports occupied by dma1? If true, I cannot imagine how many ports on x86 processor, since I know there are only several 8bit ports on a 8bit-MCU.
Can anyone detail the meaning of the number, and the io ports of x86 processor?
It's the list of I/O ports regions that have been claimed by kernel drivers using the request_region kernel function. So it's not the complete list of I/O ports or devices available, only the ones that have been claimed by various kernel drivers. The request_region mechanism allows the kernel to prevent multiple drivers from talking to the same device.
/proc/ioports lists the ranges and names of ioports provided by device drivers in the Linux kernel of ports of the port ranges claimed and handled by said drivers.
As an example, io ports 0070 - 007f are claimed by the RTC Linux kernel driver.
One would assume that said port ranges claimed by the driver correspond to the appropriate port ranges offered by the respective hardware but you should note that there is actually no mechanism that ensures that indeed they are.