When setting up Debian Linux (Bullseye) on my Lenovo IdeaCentre K430 computer, I encountered problems related to UEFI. After the installation, the system did not boot and displayed the message
Error 1962: No operating system found. It took three attempts before I found the solution, which I describe here.
First, ensure that UEFI is enabled in the BIOS before starting the installation. The Debian installer shows whether the system is booted with UEFI—look out for the message on the Welcome screen.
Second, create an EFI System Partition (ESP) when configuring the disk. This will contain the EFI firmware that allows Debian to boot in UEFI mode. If UEFI is unavailable, you will not see this option.
Third, proceed with installation until it completes. Reboot when prompted but expect to see error 1962. You need a few more steps to fix it.
Fourth, boot into the Debian installer again and choose Rescue mode. Mount the
/boot/efi partitions when asked. Then, open a console into
/root from the Debian installer menu.
/boot/efi/EFI/boot/bootx64.efi. The reason for doing this is documented. This is a crucial step.
Lastly, go into the BIOS setup, enable UEFI and disable CSM to force UEFI boot mode only. Also disable OS optimised settings—those are targeted at Windows 8 operating system.
Now, when you restart your computer, you should not get error 1962 and should boot directly into Debian.
In Debian Linux, when a network interface is configured to obtain an IP address automatically, the DHCP client utility writes the values received from the server over the content of file /etc/resolv.conf. Thus, custom entries that you had saved in this file, typically domain suffixes and domain name servers, are lost. If you need DHCP but also want to keep your configuration, do this:
- Edit file /etc/dhcp/dhclient.conf.
- Add the following lines, adjusting the values to match your needs.
supersede domain-name "my-domain.com";
supersede domain-search "my-domain.com";
prepend domain-name-servers 184.108.40.206;
This example specifies my-domain.com as the domain suffix, overriding whatever value is sent by the DCHP server. The value of the
domain-search setting is appended to hostnames to form fully-qualified domain names. For example, if you try to connect to hostname foo (without a domain name), the DNS will be queried for the FQDN foo.my-domain.com.
The example also sets the domain name server 220.127.116.11 to take priority over domain name servers provided by a DHCP server.
Throughout my technological lifetime I followed the convention that 1 kB was equal to 1000 bytes and that 1 KB was equal to 1024 bytes. Similarly, 1 mB was 1 000 000 bytes, and 1 MB was 1 048 576 bytes.
In dial-up Internet days, we surmised that a 56K modem transferred data at a rate of 56 000 bits per second (that is, 56 kbps or 5.6 kBps). Therefore, dividing the nominal modem speed by 10 gave a simple divisor for quickly calculating the download times of files with sizes expressed in kB, that is,
download time in seconds = file size in kB / modem speed in kBps
In reality, however, this was no more than a loose convention adopted by Internet users to express data volumes and bandwidths, and distinguishing between 1000 bytes and 1024 bytes by using kB and KB in writing was very convenient.
I continued with this convention until comments from a heated debate on reddit informed me of the 1999 IEC 60027-2 standard, which introduced the kibi and removed all ambiguity. The MB Confusion blog post explains this standard in a more interesting way than the Wikipedia article.
For WPS to work on the ESP8266 and using the non-OS SDK, be sure to call
wifi_wps_enable() before setting the callback function with
In the callback itself, call
void wps_callback(int status)
esptool is limited to 115200 bps when flashing your firmware to an ESP8266, you can try to increase the bitrate by following the steps below.
esptool.py for your installation. On Debian and Ubuntu, this file is located in
esptool.py and change the value on the line starting with
ESP_ROM_BAUD from 115200 to the maximum of 921600 or your preferred baud rate.
I don’t remember if this information is in the documentation, but having spent a few hours to figure things out, I think it is important to record it here.
void ICACHE_FLASH_ATTR user_init(void)
* Always call uart_init() before gpio_init()
os_timer_setfn(&os_timer, &main_on_timer, (void *)NULL);
os_timer_arm(&os_timer, 50, 1);
On the ESP8266 ESP-01,
CH_PD must be pulled HIGH at boot for the chip to work. A 10K resistor can be used for the pull-up.
Some variants of the ESP-01 module already have
CH_PD in the HIGH state.
I want to share an anecdote of confusing programming language features as a caution to my fellow programmers.
Reviewing our application logs, I noticed that the API requests were interspersed with pauses of irregular durations. The interval between each successful request is supposed to be fixed; and the interval between each failed request, exponentially growing up to a configured maximum. For example, after the first failure, the application pauses for 5 seconds; after the second, 10 seconds; after the third, 20 seconds; and so on. However, the logs showed intervals of 15 seconds, 30 seconds, 60 seconds, then 0 second—this was odd, especially the last 0 second.
This behaviour remained a mystery even after a colleague helped me look for errors in our C# code. We reviewed this line of code together but found nothing wrong; it clearly showed that on every retry the base interval was doubled.
int tmp = RetryIntervalInMs * (2 ^ retryCounter);
By coincidence, I needed the same calculation of intervals in my hobby embedded project. As I started to write the code that evening, I made an epiphanic realisation.
In our C# code, we had used the
^ operator, interpreting it as raised to the power of. This is true in some languages – BASIC, for example – but not in C#, where it is actually the operator for XOR. I was amazed that this mistake escaped our scrutiny..
Once we had identified the cause, it was easy to fix the error by using the correct library method
int tmp = RetryIntervalInMs * (int)Math.Pow(2, retryCounter);
VARCHAR value that is in scientific notation can be converted to a
DECIMAL value by first converting it to a
REAL value, then to the
DECLARE @s VARCHAR(10) = '9.0E-4';
SELECT CONVERT(DECIMAL(8, 4), CONVERT(REAL, @s));
This also works with