I have a student task to read PCI info via 0xCF8 and 0xCFC ports using outl(), inl() functions. It assumes I use Linux x86, but can I do such things on macos with M1 chip?
I found <sys/uio.h> header but it does not define functions prototypes.
outl and inl are platform-specific functions for Linux. If it is an exercise, and you have to submit a code snippet, then I suggest installing some kind of virtual machine (VirtualBox or maybe Docker Desktop) and write a program for Linux, otherwise your code would be unlikely to be accepted, since it'd use completely different low-level API.
Related
I am currently taking a class on Assembly Language and Computer Architecture. We're programming in MASM for x86 processors. I have a Macbook Air, so of course I have to run Windows on a virtual machine to program in MASM for our assignments.
What I'm confused about: We're learning about, and programming for x86 architecture. When I looked up my Macbook Air's processor, it seemed to be in the x86 family. Considering that, why doesn't MASM work with Mac OS X?
Furthermore, if assembly language communicates directly w/ hardware, why does merely installing the Windows OS (or running it through a VM) on Apple Hardware suddenly allow me to program in MASM?
Thanks,
Ian
[EDIT for clarification: My understanding -- please tell me if i'm wrong -- is that Assembly Language is as "low as you can go." I.e. it's pre-operating system, and provides instructions directly to the hardware itself. Thus, I don't understand why an assembly language for x86 architecture doesn't work on ALL x86 machines, regardless of OS]
Programs are made up of more than just the raw machine code. The executable needs to have a special format that the OS can understand, so it can load and run the code. Also, the code expects a certain environment, such as libraries and system calls (along with the appropriate calling conventions).
To compile and run your assembly program you need to assemble it first, that is run it through MASM in this case. However, MASM itself is a windows executable. It is in the executable format for windows, and it uses libraries and operating system functions accordingly. As such, you can't run it directly on mac os. Afterwards, you typically also need to link your code, which has the same issues. The next problem is with the program itself. MASM (and the rest of the toolchain) is by default also targeting windows (or dos) and so the created program has the appropriate format.
You can theoretically create a program intended to run on mac os using windows and masm. This is called cross-compiling in general. If your toolchain does not support the required mac format, you will need to create everything by hand. You obviously also need to write your program such that it expects the mac environment. For example, you can't use dos interrupts or windows libraries.
Since the architecture is the same, you don't need to virtualize the cpu. You can get away with emulating just the environment. An example for this is the windows emulator, wine, or cygwin emulating unix on windows.
A very rough analogy: there are human languages that use the same alphabet, but you still need to translate. There are also languages that do not even use the same alphabet, or don't even have letters. You will need to do more work in these cases.
I'm currently struggling to determine how I can get an emulated environment via QEMU to correctly display output on the command line. I have an environment that displays perfectly well using the virt reference board, a cortex-a9CPU, and the 4.1 Linux kernel cross-compiled for ARM. However, if I swap out the 4.1 kernel for 2.6 or 3.1, suddenly I can no longer see console output.
While solving this issue is my main goal, I feel like I lack a critical understanding of how Linux and the hardware initially integrate before userspace configurations via boot scripts and whatnot have a chance to execute. I am aware of the device tree, and have a loose understanding of how it works. But the issue I ran into where a different kernel version broke console availability entirely confounds me. Can someone explain how Linux initially maps console output to a hardware device on the ARM architecture?
Thank you!
The answer depends quite a bit on which kernel version, what config options are set, what hardware, and also possibly on kernel command line arguments.
For modern kernels, the answer is that it looks in the device tree blob it is passed for descriptions of devices, some of which will be serial ports, and it initializes those. The kernel config or command line will specify which of those is to be used for the console. For earlier kernels, especially if you go all the way back to 2.6, use of device tree was less universal, and for some hardware the boot loader simply said "this is a versatile express board" (for instance) and the kernel had compiled-in data structures to tell it where the devices were for each board that it supported. As the transition to device tree progressed, boards were converted one by one, and sometimes a few devices at a time, so what exactly the situation was for any specific kernel version depends on which board you're using.
The other thing that I rather suspect you're running into is that if the kernel crashes early in bootup (ie before it finds the serial port at all) then it will never output anything. So if the kernel is just too early to support the "virt" board properly at all, or if your kernel config is missing something important, then the chances are good that it crashes in early boot without being able to print you a useful message. (Sometimes "earlycon" or "earlyprintk" kernel arguments can assist here, but not always.)
I have some code that using UNIX sockets. But I need to compile it for winodws(using mingw32 on mac os x) but I don't want to use winsock because I'm worried about compatibility! Is there is a way to use UNIX sockets on windows?
If you stick to the BSD API that Winsock provides then you wont have that many problems. A small amount of start up and shutdown code will be Windows specific but most of the socket code will be cross platform.
I'd suggest looking into cygwin (http://www.cygwin.com/), they make every effort to be compatible. However, I have no idea how you would cross-compile for that environment on Mac OSX.
I'm building an IOKit CFPlugin driver for OS X. I'll be working with network data coming in that will be translated to MIDI data. No hardware is involved other than the built-in Airport. I have experience with drivers on Windows machines and firmware but this is my first dip into doing it on the Mac. So far things are going pretty well, but the Apple documentation sez: "For safety reasons, you should not load your driver on your development machine."
I only have one Mac. I really don't want two Macs- sorry, Apple. Should I take this warning seriously? Are there things I need to know?
Thanks, Tom Jeffries
You could also consider running OS X inside a VM as your testbed. It would surely be much more convenient that having a separate boot volume.
The warning is rather poorly worded; what you should consider doing is using a separate boot volume (partition) for trying out your driver, since it's possible to arbitrarily hose your system with your driver.
If you're doing kernel development on any OS that isn't isolated from your main system (via a VM, alternate boot disk, etc.), you're crazy!
What may be a bigger issue is that you can't do any kernel debugging, because the only option for that is to use GDB on a remote OS X system. For this, you may want to consider running OS X in virtualization.
you DEFINITELY want to have some way to recover a fubar kext installation: a bootable external drive or something you can quickly restore from-- this is the main reason for Apple's warning against running in-development-kernel-extensions on your production machine.
Nicholas is right that in order to debug using gdb (the only way in kernel space) you do need two machines. I've never tried using a VM as Coxy suggests: but I guess it's feasible (assuming that you run your kext on the virtual machine and use the real host machine to run gdb).
My preferred method for tracing and debugging in the kernel is kprintf() routed to firewire (aka firewire kprintf (man fwkpfv) ). for this you do need two machines with firewire ports.
finally, being an old computer musician myself, I wonder why you want to program a MIDI synthesizer (or transformer) on the network stack level. my guess is that you would have a much more gratifying experience working in userland (where you can use floating point math...)
if you need some hints or tips, feel free to get in touch...
|K<
from the ADC Kernel Programming Guide
Kernel programming is a black art that
should be avoided if at all possible.
Fortunately, kernel programming is
usually unnecessary. You can write
most software entirely in user space.
Even most device drivers (FireWire and
USB, for example) can be written as
applications, rather than as kernel
code. A few low-level drivers must be
resident in the kernel's address
space, however, and this document
might be marginally useful if you are
writing drivers that fall into this
category.
I've to test some low level code on an ARM architecture. Typically experimentation is quite complicated on the real board, so I was thinking about QEMU.
What I'd like to get is some kind of debugging information like printfs or gdb. I know that this is simple with linux since it implements both the device driver for the QEMU Integrator and the gdb feature, but I'm not working with Linux. Also I suspect that extracting this kind of functionality from the Linux kernel source code would be complicated.
I'm searching from some simple operating system that already implements one of those features. Do you have some advice?
You don't need a target OS to debug code that's running inside QEMU -- QEMU already does that for you.
Specifically, QEMU supports remote debugging from GDB -- you can run QEMU with the appropriate command-line options and it will export an interface that a copy of GDB (running on the host machine) can connect to. At that point, you can debug the program in GDB pretty much just as if you were running it on the host machine.
http://wiki.osdev.org/GDB appears to have a bit more basic information; possibly not enough to completely get you started, but at least give you the basic idea and some terms to look for in the QEMU and GDB documentation. Skip over the bit about "Implementing GDB Stubs", which doesn't apply here since QEMU has one already, and start at the section on "Using Emulator Stubs". The short form is simply that you start QEMU with the -s option (export a GDB connection on localhost:1234) and the -S option (wait for a GDB "continue" command before starting execution), and then in GDB on your host you say target remote :1234 instead of run. Also, of course, you need to be using an ARM version of GDB rather than a native-x86 one.
(In addition, if you're willing to pay for a commercial solution, CodeSourcery's ARM toolchain has the IDE integration to set all of this up automatically, including support for "printf" to print into the debugger console. That works on a physical board, too, if you've got a hardware debugger. Usual disclaimer about me being a CodeSourcery employee applies -- but I do find it very easy to use.)
Update, 2012: CodeSourcery's toolchain is now called Mentor Graphics Sourcery CodeBench, but all the above still applies.
I realise that I am addressing your original problem here rather than your proposed solution (perhaps that's better?), but to use GDB (or Insight/GDB) directly on the target, use a low-cost JTAG tool and OpenOCD. An example of such a set-up and how to implement it can be found here.
If you have a larger budget, a more fully featured JTAG debugger may be useful, such as the Abatron BDI3000 with bdiGDB firmware which allows remote debugging and device programming over Ethernet with GDB and no special drivers or target debug agent.
Maybe a microkernel like OKL4 would suit your needs?